Exemplo n.º 1
0
    def match_xy(self, public_key):

        x = self.openssl.lib.BN_new()
        y = self.openssl.lib.BN_new()
        common_util.assert_in_error(
            self.openssl.lib.EC_POINT_get_affine_coordinates_GFp(
                self.openssl.lib.EC_KEY_get0_group(public_key),
                self.openssl.lib.EC_KEY_get0_public_key(public_key),
                x,
                y,
                None,
            ),
            "match_xy() failed to EC_POINT_get_affine_coordinates_GFp()",
        )

        cpointer = self.get_char_point_from_bignum(x, self.curve_info.size)
        cpointer.compare_data(
            self.xy.data[:self.curve_info.size],
            ("X of Public key from QKY does not match " +
             "with private key from PEM file"),
        )
        del cpointer

        cpointer = self.get_char_point_from_bignum(y, self.curve_info.size)
        cpointer.compare_data(
            self.xy.data[self.curve_info.size:],
            ("Y of Public key from QKY does not match " +
             "with private key from PEM file"),
        )
        del cpointer

        self.openssl.lib.BN_clear_free(x)
        self.openssl.lib.BN_clear_free(y)
Exemplo n.º 2
0
    def __init__(self, args):
        self.args = args
        self.database = database.FAMILY_LIST["PAC_CARD"]
        log.debug(args.main_command)
        self.bitstream_type = self.database.SUPPORTED_TYPES[
            args.main_command].ENUM
        self.verify = True if args.root_bitstream else False
        if self.verify:
            offset = 0
            self.reh = common_util.BYTE_ARRAY("FILE", args.root_bitstream)
            con_type = self.reh.get_dword(offset + 8)

            if (self.reh.get_dword(offset) !=
                    database.DESCRIPTOR_BLOCK_MAGIC_NUM
                    or self.reh.get_dword(offset + 4) != 128
                    or (con_type >> 8) & 0xFF != database.BITSTREAM_TYPE_RK_256
                    or self.reh.get_dword(offset + 128) !=
                    database.SIGNATURE_BLOCK_MAGIC_NUM):
                common_util.assert_in_error(
                    False,
                    "File '{}' is not a root entry hash programming bitstream".
                    format(args.root_bitstream),
                )

            if con_type & 0xFF != self.bitstream_type:
                log.warn("File '{}' different type than bitstream."
                         "  Validation impossible".format(args.root_bitstream))
                self.verify = False

        if self.verify:
            self.val_root_hash = int.from_bytes(self.reh.data[1024:1056],
                                                byteorder="big")
            self.val_root_hash_dc = int.from_bytes(self.reh.data[1072:1104],
                                                   byteorder="big")
Exemplo n.º 3
0
    def retrive_key_info(self):

        assert self.key is not None
        assert self.curve_info is None

        # Checking support type
        group = self.openssl.lib.EC_KEY_get0_group(self.key)
        common_util.assert_in_error(
            group is not None,
            "generate_openssl_key() failed to EC_KEY_get0_group()")
        type = self.openssl.lib.EC_GROUP_get_curve_name(group)
        self.curve_info = openssl.get_curve_info_from_enum(type)
        common_util.assert_in_error(
            self.curve_info is not None,
            "EC curve enum (%d) name (%s) is not supported" %
            (type, self.openssl.lib.OBJ_nid2ln(type)),
        )
        log.debug("Curve info={}, group={}, type={}".format(
            self.curve_info, group, self.openssl.lib.OBJ_nid2ln(type)))

        # Get XY
        pub = self.openssl.lib.EC_KEY_get0_public_key(self.key)
        x = self.openssl.lib.BN_new()
        y = self.openssl.lib.BN_new()
        common_util.assert_in_error(
            self.openssl.lib.EC_POINT_get_affine_coordinates_GFp(
                group, pub, x, y, None),
            "Fail to EC_POINT_get_affine_coordinates_GFp()",
        )
        temp = common_util.get_byte_size(self.openssl.lib.BN_num_bits(x))
        common_util.assert_in_error(
            self.curve_info.size >= temp,
            ("Public key X size (%d Bytes) does not aligned " +
             "with EC curve (%d Bytes)") % (temp, self.curve_info.size),
        )
        temp = common_util.get_byte_size(self.openssl.lib.BN_num_bits(y))
        common_util.assert_in_error(
            self.curve_info.size >= temp,
            ("Public key Y size (%d Bytes) does not aligned " +
             "with EC curve (%d Bytes)") % (temp, self.curve_info.size),
        )

        # Copy X and Y
        cpointer = self.get_char_point_from_bignum(x, self.curve_info.size)
        self.xy.append_data(cpointer.data)
        log.debug("".join("{:02x} ".format(x) for x in self.xy.data))
        del cpointer

        cpointer = self.get_char_point_from_bignum(y, self.curve_info.size)
        self.xy.append_data(cpointer.data)
        log.debug("".join("{:02x} ".format(x) for x in self.xy.data))
        del cpointer
        log.debug(self.xy)

        self.openssl.lib.BN_clear_free(x)
        self.openssl.lib.BN_clear_free(y)
Exemplo n.º 4
0
 def __init__(self, file, openssl, key_info):
     self.key_info = key_info
     super(_PRIVATE_KEY, self).__init__(file, openssl, key_info)
     public_pem = self.check_pem_file()
     common_util.assert_in_error(
         public_pem is False,
         ("Expect the PEM file %s to be private PEM, " +
          "but detected as public PEM") % self.file,
     )
     self.key = self.openssl.read_private_key(self.file)
     self.retrive_key_info()
Exemplo n.º 5
0
    def get_bignums_from_byte_array(self, byte_array):

        common_util.assert_in_error(
            len(byte_array) == 64 or len(byte_array) == 96,
            ("get_bignums_from_byte_array() expects data size to be " +
             "64 or 96 Bytes, but found %d Bytes") % len(byte_array),
        )
        byte_array_size = int(len(byte_array) / 2)
        return [
            self.get_bignum_from_byte_array(byte_array[:byte_array_size]),
            self.get_bignum_from_byte_array(byte_array[byte_array_size:]),
        ]
Exemplo n.º 6
0
    def generate_public_pem(self, pem, key):

        bio = self.lib.BIO_new(self.lib.BIO_s_file())
        status = self.lib.BIO_ctrl(bio, BIO_C_SET_FILENAME,
                                   BIO_CLOSE | BIO_FP_WRITE,
                                   pem.encode("utf-8"))
        common_util.assert_in_error(status > 0,
                                    "Fail to open file %s for BIO write" % pem)
        status = self.lib.PEM_write_bio_EC_PUBKEY(bio, key)
        common_util.assert_in_error(status > 0,
                                    "Fail to write EC Publick Key to PEM BIO")
        self.lib.BIO_free_all(bio)
Exemplo n.º 7
0
    def generate_key(self, group):

        key = self.lib.EC_KEY_new()
        common_util.assert_in_error(
            self.lib.EC_KEY_set_group(key, group) != 0,
            "generate_key() failed to EC_KEY_set_group()",
        )
        common_util.assert_in_error(
            self.lib.EC_KEY_generate_key(key) != 0,
            "generate_key() failed to EC_KEY_generate_key()",
        )
        return key
Exemplo n.º 8
0
 def __init__(self,
              min_csk,
              max_csk,
              enum,
              permission,
              supported_size=None):
     self.MIN_CODE_SIGNING_KEY_ENTRIES = min_csk
     self.MAX_CODE_SIGNING_KEY_ENTRIES = max_csk
     common_util.assert_in_error(
         self.MAX_CODE_SIGNING_KEY_ENTRIES >=
         self.MIN_CODE_SIGNING_KEY_ENTRIES,
         "Impossible Code Signing Key entry count [min: %d, max: %d]" %
         (self.MIN_CODE_SIGNING_KEY_ENTRIES,
          self.MAX_CODE_SIGNING_KEY_ENTRIES),
     )
     self.ENUM = enum
     self.PERMISSION = permission
     self.SUPPORTED_SIZE = supported_size
Exemplo n.º 9
0
    def read_private_key(self, private_pem):

        bio = self.lib.BIO_new(self.lib.BIO_s_file())
        status = self.lib.BIO_ctrl(
            bio,
            BIO_C_SET_FILENAME,
            BIO_CLOSE | BIO_FP_READ,
            private_pem.encode("utf-8"),
        )
        common_util.assert_in_error(
            status > 0, "Fail to read file %s for BIO read" % private_pem)
        key = self.lib.PEM_read_bio_ECPrivateKey(
            bio, None, callback, ("Reading %s" % private_pem).encode("utf-8"))
        common_util.assert_in_error(
            key is not None,
            "Fail to read EC Private Key from PEM BIO %s" % private_pem)
        self.lib.BIO_free_all(bio)
        return key
Exemplo n.º 10
0
    def __init__(self, cfg_file):

        self.openssl = openssl.openssl()
        self.key_path = None
        self.curve = None
        self.keys = None

        if cfg_file is not None:
            with open(cfg_file, "r") as read_file:
                j_data = json.load(read_file)

            try:
                self.key_path = j_data["key_path"]
                self.curve = j_data["curve"]
                self.keys = j_data["keys"]
            except KeyError as ke:
                common_util.assert_in_error(
                    False, "No key '{}' in config file".format(ke))
Exemplo n.º 11
0
    def get_public_key(self, public_pem):
        pem = public_pem
        local_key = None
        if self.keys:
            for k in self.keys:
                if pem == k["label"]:
                    local_key = k
                    break
            common_util.assert_in_error(
                local_key is not None,
                "Key '{}' not found".format(pem),
            )
            common_util.assert_in_error(
                "pub_key" in local_key,
                "Public key for '{}' not found".format(pem),
            )
            pem = os.path.join(self.key_path, local_key["pub_key"])

        return _PUBLIC_KEY(pem, self.openssl, local_key)
Exemplo n.º 12
0
    def sign(self, sha, data, fixed_RS_size=0):
        log.debug("Sign: sha_size:{}".format(len(sha)))
        common_util.assert_in_error(
            len(sha) == 32 or len(sha) == 48 or len(sha) == 64,
            ("Supported SHA is SHA256, SHA314 and SHA512, " +
             "but found sha size of %d") % (len(sha) * 8),
        )
        signature = self.openssl.lib.ECDSA_do_sign(sha, len(sha), self.key)
        common_util.assert_in_error(
            self.openssl.lib.ECDSA_do_verify(sha, len(sha), signature,
                                             self.key),
            "Fail to verify after the signing",
        )

        r = c_void_p(None)
        s = c_void_p(None)
        self.openssl.lib.ECDSA_SIG_get0(signature, byref(r), byref(s))

        # assign r
        cpointer = self.get_char_point_from_bignum(r, self.curve_info.size)
        log.debug("Sign: curve_info.size={}, cpointer.size={}".format(
            self.curve_info.size, cpointer.size()))
        data.append_data(cpointer.data)
        del cpointer

        if fixed_RS_size:
            assert fixed_RS_size == 48 or fixed_RS_size == 64
            for _ in range(self.curve_info.size, fixed_RS_size):
                data.append_byte(0)

        # assign s
        cpointer = self.get_char_point_from_bignum(s, self.curve_info.size)
        data.append_data(cpointer.data)
        del cpointer

        if fixed_RS_size:
            assert fixed_RS_size == 48 or fixed_RS_size == 64
            for _ in range(self.curve_info.size, fixed_RS_size):
                data.append_byte(0)

        # Free signature
        self.openssl.lib.ECDSA_SIG_free(signature)
Exemplo n.º 13
0
 def get_private_key(self, private_pem):
     pem = private_pem
     local_key = None
     if self.keys:
         for k in self.keys:
             if pem == k["label"]:
                 local_key = k
                 break
         common_util.assert_in_error(
             local_key is not None,
             "Key '{}' not found".format(pem),
         )
         common_util.assert_in_error(
             "priv_key" in local_key,
             "Private key for '{}' not found".format(pem),
         )
         pem = os.path.join(self.key_path, local_key["priv_key"])
     else:
         pem = private_pem.replace("_public_", "_private_", 1)
     return _PRIVATE_KEY(pem, self.openssl, local_key)
Exemplo n.º 14
0
    def get_byte_array_sha(self, type, bytes):

        common_util.assert_in_error(
            type == 32 or type == 48 or type == 64,
            ("Expect SHA supported type size is 32, 48 or " +
             "64 Bytes, but found %d Bytes") % type,
        )
        common_util.assert_in_error(
            len(bytes) > 0 and (len(bytes) % 128) == 0,
            ("Data to be hashed must have size greater than " +
             "zero and multiple of 128 Bytes, but found %d Bytes") %
            len(bytes),
        )
        common_util.assert_in_error(
            memoryview(bytes).c_contiguous,
            "Byte array is not contiguous in memory")
        cpointer = c_char_p(bytes.buffer_info()[0])
        sha = common_util.CHAR_POINTER(type)
        if type == 32:
            self.get_sha256(cpointer, bytes.buffer_info()[1], sha)
        elif type == 48:
            self.get_sha384(cpointer, bytes.buffer_info()[1], sha)
        else:
            self.get_sha512(cpointer, bytes.buffer_info()[1], sha)
        del cpointer
        return sha
Exemplo n.º 15
0
    def __init__(self, cfg_file=None):
        common_util.assert_in_error(
            cfg_file, "PKCS11 HSM manager requires a configuration file")
        self.session = None
        with open(cfg_file, "r") as read_file:
            self.j_data = json.load(read_file)
        j_data = self.j_data

        lib = pkcs11.lib(j_data["lib_path"])
        common_util.assert_in_error(
            j_data["library_version"] == list(lib.library_version),
            "PKCS11 HSM manager library version mismatch",
        )
        common_util.assert_in_error(
            j_data["cryptoki_version"] == list(lib.cryptoki_version),
            "PKCS11 HSM manager cryptoki version mismatch",
        )
        token = lib.get_token(token_label=j_data["token"]["label"])
        self.session = token.open(user_pin=j_data["token"]["user_password"])
        self.curve = j_data["curve"]

        self.ecparams = self.session.create_domain_parameters(
            pkcs11.KeyType.EC,
            {
                pkcs11.Attribute:
                pkcs11.util.ec.encode_named_curve_parameters(self.curve)
            },
            local=True,
        )
Exemplo n.º 16
0
    def get_char_point_from_bignum(self, bignum, size):

        common_util.assert_in_error(
            size == 32 or size == 48,
            ("get_char_point_from_bignum() expects data size to be " +
             "32 or 48 Bytes, but found %d Bytes") % size,
        )
        cpointer = common_util.CHAR_POINTER(size)
        bn_byte = self.openssl.lib.BN_bn2bin(bignum, cpointer.data)
        common_util.assert_in_error(
            bn_byte <= size,
            ("BN_bn2bin() expects BN size to be %d Bytes, " +
             "but found %d Bytes") % (size, bn_byte),
        )
        if bn_byte != size:
            cpointer1 = common_util.CHAR_POINTER(size)
            cpointer1.assign_partial_data(cpointer.data, 0, size - bn_byte,
                                          bn_byte)
            del cpointer
            return cpointer1
        else:
            return cpointer
Exemplo n.º 17
0
    def __init__(
        self,
        family,
        supported_types,
        max_csk,
        signature_max_size,
        supported_cancels,
        cert_types,
    ):

        self.FAMILY = family
        # You can set the types to None, if this family has only one type data
        self.SUPPORTED_TYPES = supported_types
        self.MAX_CODE_SIGNING_KEY_ENTRIES = max_csk
        self.SIGNATURE_MAX_SIZE = signature_max_size
        self.SUPPORTED_CANCELS = (
            supported_cancels
        )  # You can set cancels to None, if it does not support cancel
        self.SUPPORTED_CERT_TYPES = cert_types
        common_util.assert_in_error(
            self.SIGNATURE_MAX_SIZE > 0 and self.SIGNATURE_MAX_SIZE <= 880
            and (self.SIGNATURE_MAX_SIZE % 4) == 0,
            ("Maximum signature reserved field should greater than zero, " +
             "less than 880 Bytes and multiple of 4 Bytes, but found %d") %
            self.SIGNATURE_MAX_SIZE,
        )
        for key in self.SUPPORTED_TYPES:
            common_util.assert_in_error(
                self.SUPPORTED_TYPES[key].MIN_CODE_SIGNING_KEY_ENTRIES <=
                self.MAX_CODE_SIGNING_KEY_ENTRIES,
                ("File type (%s) minimum Code Signing Key entry (%d) " +
                 "cannot be more than family (%s) maximum " +
                 "Code Signing Key entry (%d)") % (
                     key,
                     self.SUPPORTED_TYPES[key].MIN_CODE_SIGNING_KEY_ENTRIES,
                     self.FAMILY,
                     self.MAX_CODE_SIGNING_KEY_ENTRIES,
                 ),
            )
            common_util.assert_in_error(
                self.SUPPORTED_TYPES[key].MAX_CODE_SIGNING_KEY_ENTRIES <=
                self.MAX_CODE_SIGNING_KEY_ENTRIES,
                ("File type (%s) maximum Code Signing Key entry (%d) " +
                 "cannot be more than family (%s) maximum " +
                 "Code Signing Key entry (%d)") % (
                     key,
                     self.SUPPORTED_TYPES[key].MAX_CODE_SIGNING_KEY_ENTRIES,
                     self.FAMILY,
                     self.MAX_CODE_SIGNING_KEY_ENTRIES,
                 ),
            )
        self.CURRENT_TYPE = None
        self.CURRENT_TYPE_NAME = None
        self.CURRENT_CERT_TYPE = None
        self.CURRENT_CERT_TYPE_NAME = None
Exemplo n.º 18
0
    def get_public_key(self, public_key):
        try:
            key_, local_key = self.get_key(public_key, ObjectClass.PUBLIC_KEY)
            key_ = key_[Attribute.EC_POINT]

            common_util.assert_in_error(
                key_[0] == 0x04, "PKCS11 HSM manager key not in DER format")
            common_util.assert_in_error(
                key_[1] == 0x41, "PKCS11 HSM manager key not in DER format")
            common_util.assert_in_error(
                key_[2] == 0x04, "PKCS11 HSM manager key not in DER format")
        except pkcs11.NoSuchKey:
            log.error("No such key")
        except pkcs11.MultipleObjectsReturned:
            log.error("multiple")
        return _PUBLIC_KEY(key_[3:], local_key)
Exemplo n.º 19
0
def password_callback(buf, bufsiz, verify, cb_temp):

    comment = ""
    if cb_temp is not None:
        for char in cb_temp:
            if char != 0:
                comment += chr(char)
    common_util.assert_in_error(
        bufsiz >= 4,
        ("Minimum password must be 4 characters," +
         " but only %d buffer size is being provided") % bufsiz,
    )
    try:
        if verify:
            (password, error) = common_util.get_password(
                [
                    ("Enter PEM passphrase (4 to %d characters per OpenSSL " +
                     "spec, Intel recommends minumum 13 characters): ") %
                    (bufsiz - 1),
                    ("Re-enter PEM passphrase (4 to %d characters per OpenSSL "
                     + "spec, Intel recommends minumum 13 characters): ") %
                    (bufsiz - 1),
                ],
                4,
                bufsiz - 1,
                comment,
            )
        else:
            (password, error) = common_util.get_password(
                [("Enter PEM passphrase (4 to %d characters per OpenSSL" +
                  " spec, Intel recommends minumum 13 characters): ") %
                 (bufsiz - 1)],
                4,
                bufsiz - 1,
                comment,
            )
        common_util.assert_in_error(len(error) == 0, error)
    except Exception:
        common_util.assert_in_error(False, "Fail to get passphrase")
    password_size = len(password)
    if password_size < 13:
        common_util.print_warning(PEM_PASSWORD_WARNING)
    for i in range(password_size):
        buf[i] = password[i]
    del password
    password = []
    return password_size
Exemplo n.º 20
0
    def generate_ec_key_using_xy_and_curve_info(self, xy, curve_info):

        common_util.assert_in_error(
            len(xy) == (curve_info.size * 2),
            "%s xy size should be %d Bytes, but found %d Bytes" %
            (curve_info.name, curve_info.size * 2, len(xy)),
        )
        (x, y) = self.get_bignums_from_byte_array(xy)
        key = self.lib.EC_KEY_new_by_curve_name(curve_info.enum)
        status = self.lib.EC_KEY_set_public_key_affine_coordinates(key, x, y)
        common_util.assert_in_error(
            status > 0, "Fail to set public key affine coordinates")
        status = self.lib.EC_KEY_check_key(key)
        common_util.assert_in_error(status > 0, "Invalid key")
        self.lib.BN_clear_free(x)
        self.lib.BN_clear_free(y)
        return key
Exemplo n.º 21
0
    def read_public_key(self, public_pem):

        bio = self.lib.BIO_new(self.lib.BIO_s_file())
        status = self.lib.BIO_ctrl(bio, BIO_C_SET_FILENAME,
                                   BIO_CLOSE | BIO_FP_READ,
                                   public_pem.encode("utf-8"))
        common_util.assert_in_error(
            status > 0, "Fail to read file %s for BIO read" % public_pem)
        pub_key = self.lib.PEM_read_bio_PUBKEY(bio, None, None, None)
        common_util.assert_in_error(
            pub_key is not None,
            "Fail to read EC Public Key from PEM BIO %s" % public_pem,
        )
        key = self.lib.EVP_PKEY_get1_EC_KEY(pub_key)
        common_util.assert_in_error(key is not None,
                                    "Fail to get EC Key from public key")
        self.lib.EVP_PKEY_free(pub_key)
        self.lib.BIO_free_all(bio)
        return key
Exemplo n.º 22
0
    def generate_private_pem(self, pem, group, key, encrypt):

        bio = self.lib.BIO_new(self.lib.BIO_s_file())
        status = self.lib.BIO_ctrl(bio, BIO_C_SET_FILENAME,
                                   BIO_CLOSE | BIO_FP_WRITE,
                                   pem.encode("utf-8"))
        common_util.assert_in_error(status > 0,
                                    "Fail to open file %s for BIO write" % pem)
        status = self.lib.PEM_write_bio_ECPKParameters(bio, group)
        common_util.assert_in_error(status > 0,
                                    "Fail to write EC Param to PEM BIO")
        if encrypt is None or not encrypt:
            status = self.lib.PEM_write_bio_ECPrivateKey(
                bio, key, None, None, 0, None, None)
        else:
            enc = self.lib.EVP_get_cipherbyname("aes256".encode("utf-8"))
            status = self.lib.PEM_write_bio_ECPrivateKey(
                bio, key, enc, None, 0, callback,
                ("Writing %s" % pem).encode("utf-8"))
        common_util.assert_in_error(status > 0,
                                    "Fail to write EC Private Key to PEM BIO")
        self.lib.BIO_free_all(bio)
Exemplo n.º 23
0
    def verify_signature(self, sha, rs):

        common_util.assert_in_error(
            len(sha.data) == 32 or len(sha.data) == 48 or len(sha.data) == 64,
            ("verify_signature() data size to be veried must be 32, " +
             "48 or 64 Bytes, but found %d Bytes") % len(sha.data),
        )
        common_util.assert_in_error(
            len(rs) == (self.curve_info.size * 2),
            "Key expects RS size to be %d Bytes, but found %d Bytes" %
            (self.curve_info.size * 2, len(rs)),
        )
        (r, s) = self.openssl.get_bignums_from_byte_array(rs)
        signature = self.openssl.lib.ECDSA_SIG_new()
        self.openssl.lib.ECDSA_SIG_set0(signature, r, s)

        common_util.assert_in_error(
            self.openssl.lib.ECDSA_do_verify(sha.data, len(sha.data),
                                             signature, self.key),
            "verify_signature() failed to ECDSA_do_verify()",
        )
        self.openssl.lib.ECDSA_SIG_free(signature)
Exemplo n.º 24
0
def test_assert_in_error():
    assert_in_error_boolean = mock.MagicMock()
    assert_in_error_string = mock.MagicMock()
    assert_in_error(assert_in_error_boolean, assert_in_error_string)
Exemplo n.º 25
0
    def run(self, fname, file_offset, block0, block1, payload):
        log.info("Starting verification")
        payload_content = common_util.BYTE_ARRAY("FILE", fname)

        # Skip JSON and old signature if they exist
        has_json = self.is_JSON(payload_content)
        log.debug("has_json = {}".format(has_json))
        sig_offset = 0 if not has_json else self.skip_JSON(payload_content)

        # Determine if platform is RC or DC
        self.dc_pr = self.is_Darby_PR(payload_content, sig_offset)

        fd = open(fname, "rb")
        fd.seek(file_offset, 0)

        b0 = fd.read(block0.size())
        b1 = fd.read(block1.size())
        if self.dc_pr:
            pay = fd.read(len(payload))
            pay_good = pay == bytes(payload)
        else:
            pay = fd.read(payload.size())
            pay_good = pay == bytes(payload.data)

        fd.close()
        common_util.assert_in_error(
            b0 == bytes(block0.data) and b1 == bytes(block1.data) and pay_good,
            "File not written properly",
        )

        log.info("Bitstream file written properly (bits match expected)")

        pay_sha256_v = int.from_bytes(sha256(pay).digest(), byteorder="big")
        pay_sha384_v = int.from_bytes(sha384(pay).digest(), byteorder="big")

        if not self.dc_pr:
            if pay_sha256_v != int.from_bytes(b0[16:16 + 32], byteorder="big"):
                log.error("SHA-256 in Block 0 does not match")

            if pay_sha384_v != int.from_bytes(b0[48:48 + 48], byteorder="big"):
                log.error("SHA-384 in Block 0 does not match")

        # Check root hash
        if self.dc_pr:
            hash = int.from_bytes(sha256(b1[152:152 + 64]).digest(),
                                  byteorder="big")
            good = hash == self.val_root_hash_dc
        else:
            hash = int.from_bytes(sha256(b1[20:148]).digest(), byteorder="big")
            good = hash == self.val_root_hash

        if good:
            log.info("Root hash matches")
        else:
            log.error("Root hash mismatch:")
            log.error("Signed bitstream:                   {}".format(
                hex(hash)))
            log.error("Root entry hash bitstream provided: {}".format(
                hex(self.val_root_hash_dc if self.dc_pr else self.val_root_hash
                    )))

        if self.dc_pr:
            root_pub_key_x = int.from_bytes(b1[152:152 + 32], byteorder="big")
            root_pub_key_y = int.from_bytes(b1[152 + 32:152 + 64],
                                            byteorder="big")
            root_pub_key_v = (root_pub_key_x, root_pub_key_y)
            csk_pub_key_x = int.from_bytes(b1[264:264 + 32], byteorder="big")
            csk_pub_key_y = int.from_bytes(b1[264 + 32:264 + 64],
                                           byteorder="big")
            csk_pub_key_v = (csk_pub_key_x, csk_pub_key_y)
            csk_rs_r = int.from_bytes(b1[344:344 + 32], byteorder="big")
            csk_rs_s = int.from_bytes(b1[344 + 32:344 + 64], byteorder="big")
            csk_rs_v = (csk_rs_r, csk_rs_s)
            b0e_rs_r = int.from_bytes(b1[448:448 + 32], byteorder="big")
            b0e_rs_s = int.from_bytes(b1[448 + 32:448 + 64], byteorder="big")
            b0e_rs_v = (b0e_rs_r, b0e_rs_s)

            root_sha_v = hash
            csk_sha_v = int.from_bytes(sha256(b1[240:240 + 88]).digest(),
                                       byteorder="big")
            b0_sha_v = int.from_bytes(sha256(b0).digest(), byteorder="big")
        else:
            if self.cert_type == database.BITSTREAM_TYPE_CANCEL:
                b0e_off = 156
                csk_pub_key_v = (0, 0)
                csk_rs_v = (0, 0)
                csk_sha_v = 0
            else:
                b0e_off = 388
                csk_pub_key_x = int.from_bytes(b1[164:164 + 32],
                                               byteorder="big")
                csk_pub_key_y = int.from_bytes(b1[212:212 + 32],
                                               byteorder="big")
                csk_pub_key_v = (csk_pub_key_x, csk_pub_key_y)
                csk_rs_r = int.from_bytes(b1[284:284 + 32], byteorder="big")
                csk_rs_s = int.from_bytes(b1[332:332 + 32], byteorder="big")
                csk_rs_v = (csk_rs_r, csk_rs_s)
                csk_sha_v = int.from_bytes(sha256(b1[152:152 + 128]).digest(),
                                           byteorder="big")

            root_pub_key_x = int.from_bytes(b1[32:32 + 32], byteorder="big")
            root_pub_key_y = int.from_bytes(b1[80:80 + 32], byteorder="big")
            root_pub_key_v = (root_pub_key_x, root_pub_key_y)
            b0e_rs_r = int.from_bytes(b1[b0e_off:b0e_off + 32],
                                      byteorder="big")
            b0e_rs_s = int.from_bytes(b1[b0e_off + 48:b0e_off + 48 + 32],
                                      byteorder="big")
            b0e_rs_v = (b0e_rs_r, b0e_rs_s)
            root_sha_v = hash
            b0_sha_v = int.from_bytes(sha256(b0).digest(), byteorder="big")

        # validate signatures
        if self.cert_type != database.BITSTREAM_TYPE_CANCEL:
            if ecdsa.verify_signature(root_pub_key_v, csk_sha_v, csk_rs_v):
                log.info("Signature of CSK with root key OK")
            else:
                log.error("Signature of CSK with root key mismatch")

            if ecdsa.verify_signature(csk_pub_key_v, b0_sha_v, b0e_rs_v):
                log.info("Signature of Block 0 with CSK OK")
            else:
                log.error("Signature of Block 0 with CSK mismatch")
        else:
            if ecdsa.verify_signature(root_pub_key_v, b0_sha_v, b0e_rs_v):
                log.info("Signature of Block 0 with root key OK")
            else:
                log.error("Signature of Block 0 with root key mismatch")
        return
Exemplo n.º 26
0
    def __init__(self, version='1.1.1g'):
        path = "%s/library" % os.path.dirname(os.path.abspath(__file__))
        self.nanotime = None
        if _platform == "win32" or _platform == "win64":
            dll_name = 'libcrypto-1_1-x64.dll'
        else:
            dll_name = '*libcrypto*.so'

        dlls = glob.glob(os.path.join(path, dll_name))

        self.lib = self._find_openssl_so(version, *dlls)
        common_util.assert_in_error(self.lib, "Failed to find crypto library")

        # Initialize OPEN algorithm
        self.lib.OPENSSL_init_crypto.argtypes = [c_uint, c_void_p]
        self.lib.OPENSSL_init_crypto.restype = None

        # Create new key
        self.lib.EC_KEY_new.argtypes = []
        self.lib.EC_KEY_new.restype = c_void_p

        # Create new group with the curve e
        self.lib.EC_GROUP_new_by_curve_name.argtypes = [c_uint]
        self.lib.EC_GROUP_new_by_curve_name.restype = c_void_p

        # pair the group and key
        self.lib.EC_KEY_set_group.argtypes = [c_void_p, c_void_p]
        self.lib.EC_KEY_set_group.restype = c_int

        # Generate key
        self.lib.EC_KEY_generate_key.argtypes = [c_void_p]
        self.lib.EC_KEY_generate_key.restype = c_int

        # Create BIO
        self.lib.BIO_new.argtypes = [c_void_p]
        self.lib.BIO_new.restype = c_void_p

        # Create BIO method
        self.lib.BIO_s_file.argtypes = []
        self.lib.BIO_s_file.restype = c_void_p

        # Read PEM file
        self.lib.BIO_ctrl.argtypes = [c_void_p, c_int, c_long, c_char_p]
        self.lib.BIO_ctrl.restype = c_int

        # Create encryption
        self.lib.EVP_get_cipherbyname.argtypes = [c_char_p]
        self.lib.EVP_get_cipherbyname.restype = c_void_p

        # Write EC Param to PEM
        self.lib.PEM_write_bio_ECPKParameters.argtypes = [c_void_p, c_void_p]
        self.lib.PEM_write_bio_ECPKParameters.restype = c_int

        # Write key to PEM
        self.lib.PEM_write_bio_ECPrivateKey.argtypes = [
            c_void_p,
            c_void_p,
            c_void_p,
            c_char_p,
            c_int,
            c_void_p,
            c_void_p,
        ]
        self.lib.PEM_write_bio_ECPrivateKey.restype = c_int

        # Write public key to PEM
        self.lib.PEM_write_bio_EC_PUBKEY.argtypes = [c_void_p, c_void_p]
        self.lib.PEM_write_bio_EC_PUBKEY.restype = c_int

        # Read Private key from PEM
        self.lib.PEM_read_bio_ECPrivateKey.argtypes = [
            c_void_p,
            c_void_p,
            c_void_p,
            c_char_p,
        ]
        self.lib.PEM_read_bio_ECPrivateKey.restype = c_void_p

        # Read Public key from PEM
        self.lib.PEM_read_bio_PUBKEY.argtypes = [
            c_void_p, c_void_p, c_void_p, c_char_p
        ]
        self.lib.PEM_read_bio_PUBKEY.restype = c_void_p

        # Get public key
        self.lib.EC_KEY_get0_public_key.argtypes = [c_void_p]
        self.lib.EC_KEY_get0_public_key.restype = c_void_p

        # Convert a public key to key
        self.lib.EVP_PKEY_get1_EC_KEY.argtypes = [c_void_p]
        self.lib.EVP_PKEY_get1_EC_KEY.restype = c_void_p

        # Create new Big Number
        self.lib.BN_new.argtypes = []
        self.lib.BN_new.restype = c_void_p

        # Get group from key
        self.lib.EC_KEY_get0_group.argtypes = [c_void_p]
        self.lib.EC_KEY_get0_group.restype = c_void_p

        # Get EC curve from group
        self.lib.EC_GROUP_get_curve_name.argtypes = [c_void_p]
        self.lib.EC_GROUP_get_curve_name.restype = c_int

        # Generate key from curve
        self.lib.EC_KEY_new_by_curve_name.argtypes = [c_int]
        self.lib.EC_KEY_new_by_curve_name.restype = c_void_p

        # Set public key coordinate info
        self.lib.EC_KEY_set_public_key_affine_coordinates.argtypes = [
            c_void_p,
            c_void_p,
            c_void_p,
        ]
        self.lib.EC_KEY_set_public_key_affine_coordinates.restype = c_int

        # Verify key
        self.lib.EC_KEY_check_key.argtypes = [c_void_p]
        self.lib.EC_KEY_check_key.restype = c_int

        # Set Group ASN1 flag
        self.lib.EC_GROUP_set_asn1_flag.argtypes = [c_void_p, c_int]
        self.lib.EC_GROUP_set_asn1_flag.restype = None

        # Set Group conversion
        self.lib.EC_GROUP_set_point_conversion_form.argtypes = [
            c_void_p, c_int
        ]
        self.lib.EC_GROUP_set_point_conversion_form.restype = None

        # Get XY from of a public key
        self.lib.EC_POINT_get_affine_coordinates_GFp.argtypes = [
            c_void_p,
            c_void_p,
            c_void_p,
            c_void_p,
            c_void_p,
        ]
        self.lib.EC_POINT_get_affine_coordinates_GFp.restype = c_int

        # Get number of bit of Big Number
        self.lib.BN_num_bits.argtypes = [c_void_p]
        self.lib.BN_num_bits.restype = c_int

        # Convert Big Number to Byte array
        self.lib.BN_bn2bin.argtypes = [c_void_p, c_char_p]
        self.lib.BN_bn2bin.restype = c_int

        # Convert Byte array to Big Number
        self.lib.BN_bin2bn.argtypes = [c_char_p, c_int, c_void_p]
        self.lib.BN_bin2bn.restype = c_void_p

        # Convert Big Number to char *
        self.lib.BN_bn2hex.argtypes = [c_void_p]
        self.lib.BN_bn2hex.restype = c_char_p

        self.lib.BN_copy.argtypes = [c_void_p, c_void_p]
        self.lib.BN_copy.restype = c_void_p

        self.lib.ECDSA_SIG_set0.argtypes = [c_void_p, c_void_p, c_void_p]
        self.lib.ECDSA_SIG_set0.restype = c_int

        self.lib.ECDSA_SIG_get0.argtypes = [
            c_void_p, POINTER(c_void_p),
            POINTER(c_void_p)
        ]
        self.lib.ECDSA_SIG_get0.restype = None

        # Convert enum to char *
        self.lib.OBJ_nid2ln.argtypes = [c_int]
        self.lib.OBJ_nid2ln.restype = c_char_p

        # Free Big Number
        self.lib.BN_clear_free.argtypes = [c_void_p]
        self.lib.BN_clear_free.restype = None

        # Free key
        self.lib.EC_KEY_free.argtypes = [c_void_p]
        self.lib.EC_KEY_free.restype = None

        # Free public key
        self.lib.EVP_PKEY_free.argtypes = [c_void_p]
        self.lib.EVP_PKEY_free.restype = None

        # Free group
        self.lib.EC_GROUP_free.argtypes = [c_void_p]
        self.lib.EC_GROUP_free.restype = None

        # Free bio
        self.lib.BIO_free_all.argtypes = [c_void_p]
        self.lib.BIO_free_all.restype = None

        # Sign
        self.lib.ECDSA_do_sign.argtypes = [c_char_p, c_int, c_void_p]
        self.lib.ECDSA_do_sign.restype = POINTER(OPENSSL_SIGNATURE)

        # New signature
        self.lib.ECDSA_SIG_new.argtypes = []
        self.lib.ECDSA_SIG_new.restype = POINTER(OPENSSL_SIGNATURE)

        # Verify
        self.lib.ECDSA_do_verify.argtypes = [
            c_char_p,
            c_int,
            POINTER(OPENSSL_SIGNATURE),
            c_void_p,
        ]
        self.lib.ECDSA_do_verify.restype = c_int

        # Free signature
        self.lib.ECDSA_SIG_free.argtypes = [c_void_p]
        self.lib.ECDSA_SIG_free.restype = None

        # Free generic
        self.lib.CRYPTO_free.argtypes = [c_void_p]
        self.lib.CRYPTO_free.restype = None

        # Initialize
        self.lib.OPENSSL_init_crypto(
            OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_DIGESTS
            | OPENSSL_INIT_LOAD_CONFIG, None)

        # SHA256
        self.lib.SHA256.argtypes = [c_void_p, c_size_t, c_char_p]
        self.lib.SHA256.restype = c_char_p

        self.lib.SHA256_Init.argtypes = [POINTER(OPENSSL_SHA256)]
        self.lib.SHA256_Init.restype = c_int

        self.lib.SHA256_Update.argtypes = [
            POINTER(OPENSSL_SHA256), c_void_p, c_size_t
        ]
        self.lib.SHA256_Update.restype = c_int

        self.lib.SHA256_Final.argtypes = [c_char_p, POINTER(OPENSSL_SHA256)]
        self.lib.SHA256_Final.restype = c_int

        # SHA384
        self.lib.SHA384.argtypes = [c_void_p, c_size_t, c_char_p]
        self.lib.SHA384.restype = c_char_p

        self.lib.SHA384_Init.argtypes = [POINTER(OPENSSL_SHA512)]
        self.lib.SHA384_Init.restype = c_int

        self.lib.SHA384_Update.argtypes = [
            POINTER(OPENSSL_SHA512), c_void_p, c_size_t
        ]
        self.lib.SHA384_Update.restype = c_int

        self.lib.SHA384_Final.argtypes = [c_char_p, POINTER(OPENSSL_SHA512)]
        self.lib.SHA384_Final.restype = c_int

        # SHA512
        self.lib.SHA512.argtypes = [c_void_p, c_size_t, c_char_p]
        self.lib.SHA512.restype = c_char_p

        self.lib.SHA512_Init.argtypes = [POINTER(OPENSSL_SHA512)]
        self.lib.SHA512_Init.restype = c_int

        self.lib.SHA512_Update.argtypes = [
            POINTER(OPENSSL_SHA512), c_void_p, c_size_t
        ]
        self.lib.SHA512_Update.restype = c_int

        self.lib.SHA512_Final.argtypes = [c_char_p, POINTER(OPENSSL_SHA512)]
        self.lib.SHA512_Final.restype = c_int
Exemplo n.º 27
0
    def check_pem_file(self):

        common_util.assert_in_error(os.path.exists(self.file),
                                    "PEM file %s does not exist" % self.file)
        lines = open(self.file, "r")
        private_tracking = 0
        encrypted_tracking = 0
        public_tracking = 0
        for line in lines:
            if line.find("-----BEGIN EC PRIVATE KEY-----") == 0:
                common_util.assert_in_error(
                    private_tracking == 0,
                    ("Basic checking on %s failed. Keyword " +
                     '"-----BEGIN EC PRIVATE KEY-----" is detected twice') %
                    self.file,
                )
                common_util.assert_in_error(
                    encrypted_tracking == 0,
                    ("Basic checking on %s failed. Encrypted " +
                     "Private Key is already detected") % self.file,
                )
                common_util.assert_in_error(
                    public_tracking == 0,
                    ("Basic checking on %s failed. Public Key " +
                     "is already detected") % self.file,
                )
                private_tracking += 1
            elif line.find("-----BEGIN ENCRYPTED PRIVATE KEY-----") == 0:
                common_util.assert_in_error(
                    encrypted_tracking == 0,
                    ("Basic checking on %s failed. Keyword " +
                     '"-----BEGIN ENCRYPTED PRIVATE KEY-----" is ' +
                     "detected twice") % self.file,
                )
                common_util.assert_in_error(
                    private_tracking == 0,
                    ("Basic checking on %s failed. EC Private " +
                     "Key is already detected") % self.file,
                )
                common_util.assert_in_error(
                    public_tracking == 0,
                    ("Basic checking on %s failed. Public " +
                     "Key is already detected") % self.file,
                )
                encrypted_tracking += 1
            elif line.find("-----BEGIN PUBLIC KEY-----") == 0:
                common_util.assert_in_error(
                    public_tracking == 0,
                    ("Basic checking on %s failed. Keyword " +
                     '"-----BEGIN PUBLIC KEY-----" is detected twice') %
                    self.file,
                )
                common_util.assert_in_error(
                    private_tracking == 0,
                    ("Basic checking on %s failed. EC Private " +
                     "Key is already detected") % self.file,
                )
                common_util.assert_in_error(
                    encrypted_tracking == 0,
                    ("Basic checking on %s failed. Encrypted " +
                     "Private Key is already detected") % self.file,
                )
                public_tracking += 1
            elif line.find("-----END EC PRIVATE KEY-----") == 0:
                common_util.assert_in_error(
                    encrypted_tracking == 0,
                    ("Basic checking on %s failed. Encrypted Private " +
                     "Key is already detected") % self.file,
                )
                common_util.assert_in_error(
                    public_tracking == 0,
                    ("Basic checking on %s failed. Public " +
                     "Key is already detected") % self.file,
                )
                common_util.assert_in_error(
                    private_tracking != 0,
                    ("Basic checking on %s failed. Keyword " +
                     '"-----BEGIN EC PRIVATE KEY-----" is not detected ' +
                     'before keyword "-----END EC PRIVATE KEY-----"') %
                    self.file,
                )
                common_util.assert_in_error(
                    private_tracking == 1,
                    ("Basic checking on %s failed. Keyword " +
                     '"-----END EC PRIVATE KEY-----" is detected twice') %
                    self.file,
                )
                private_tracking += 1
            elif line.find("-----END ENCRYPTED PRIVATE KEY-----") == 0:
                common_util.assert_in_error(
                    private_tracking == 0,
                    ("Basic checking on %s failed. EC Private " +
                     "Key is already detected") % self.file,
                )
                common_util.assert_in_error(
                    public_tracking == 0,
                    ("Basic checking on %s failed. Public " +
                     "Key is already detected") % self.file,
                )
                common_util.assert_in_error(
                    encrypted_tracking != 0,
                    ("Basic checking on %s failed. Keyword " +
                     '"-----BEGIN ENCRYPTED PRIVATE KEY-----" ' +
                     "is not detected before keyword " +
                     '"-----END ENCRYPTED PRIVATE KEY-----"') % self.file,
                )
                common_util.assert_in_error(
                    encrypted_tracking == 1,
                    ("Basic checking on %s failed. Keyword " +
                     '"-----END ENCRYPTED PRIVATE KEY-----" ' +
                     "is detected twice") % self.file,
                )
                encrypted_tracking += 1
            elif line.find("-----END PUBLIC KEY-----") == 0:
                common_util.assert_in_error(
                    private_tracking == 0,
                    ("Basic checking on %s failed. EC Private " +
                     "Key is already detected") % self.file,
                )
                common_util.assert_in_error(
                    encrypted_tracking == 0,
                    ("Basic checking on %s failed. Encrypted Private " +
                     "Key is already detected") % self.file,
                )
                common_util.assert_in_error(
                    public_tracking != 0,
                    ("Basic checking on %s failed. Keyword " +
                     '"-----BEGIN PUBLIC KEY-----" is not ' +
                     'detected before keyword "-----END PUBLIC KEY-----"') %
                    self.file,
                )
                common_util.assert_in_error(
                    public_tracking == 1,
                    ("Basic checking on %s failed. Keyword " +
                     '"-----END PUBLIC KEY-----" is detected twice') %
                    self.file,
                )
                public_tracking += 1
        lines.close()
        common_util.assert_in_error(
            (private_tracking == 2 and encrypted_tracking == 0
             and public_tracking == 0)
            or (private_tracking == 0 and encrypted_tracking == 2
                and public_tracking == 0)
            or (private_tracking == 0 and encrypted_tracking == 0
                and public_tracking == 2),
            ("Basic checking on %s failed. Problem in detected " +
             "EC Private, Encrypted Private or Public Key") % self.file,
        )
        return public_tracking == 2
Exemplo n.º 28
0
def main():
    parser = argparse.ArgumentParser(prog='pacsign',
                                     description="Sign PAC bitstreams")
    subparsers = parser.add_subparsers(
        title="Commands",
        description="Image types",
        help="Allowable image types",
        dest="main_command",
    )
    parser_sr = subparsers.add_parser("SR",
                                      aliases=["FIM", "BBS"],
                                      help="Static FPGA image")
    parser_bmc = subparsers.add_parser("BMC",
                                       aliases=["BMC_FW"],
                                       help="BMC image")
    parser_pr = subparsers.add_parser("PR",
                                      aliases=["AFU", "GBS"],
                                      help="Reconfigurable FPGA image")
    parser_print = subparsers.add_parser("print",
                                         help="Print header information")

    add_common_options(parser_sr)
    add_common_options(parser_bmc)
    add_common_options(parser_pr)
    parser_print.add_argument("files",
                              nargs="+",
                              help="List of files whose contents"
                              " are to be printed")
    parser_print.add_argument(
        "-v",
        "--verbose",
        help="Increase verbosity.  Can be specified multiple times",
        action="count",
    )

    args = parser.parse_args()
    if len(sys.argv) == 1:
        parser.print_help()
        sys.exit()

    if not args.verbose:
        args.verbose = 0
    if args.verbose > 2:
        args.verbose = 2

    log.handlers[0].setLevel(LOGLEVELS[args.verbose])

    if args.main_command == "print":
        return reader.print_file_contents(args.files)

    manager = args.HSM_manager.rstrip('_manager')
    # Load HSM handler
    try:
        hsm_manager = importlib.import_module('.{}'.format(manager),
                                              'pacsign.hsm_managers')
    except ImportError as err:
        common_util.assert_in_error(
            False,
            "Error '{}' importing module {}".format(err, args.HSM_manager))
    try:
        importlib.invalidate_caches()
    except AttributeError:
        pass
    try:
        _method = getattr(hsm_manager, "HSM_MANAGER")
    except AttributeError:
        common_util.assert_in_error(
            False, "Invalid key manager module %s" % args.HSM_manager)

    if args.cert_type == "RK_384":
        common_util.assert_in_error(False, "384-bit keys not supported")

    # Validate arguments
    if args.cert_type == "UPDATE":
        common_util.assert_in_error(
            args.input_file is not None and args.output_file is not None,
            "Update requires both an input and output file",
        )
        if os.path.isfile(args.output_file):
            common_util.assert_in_error(
                answer_y_n(
                    args, "Output file {} exists. Overwrite".format(
                        args.output_file)),
                "Aborting.",
            )
        if args.root_key is None:
            common_util.assert_in_error(
                answer_y_n(
                    args,
                    "No root key specified.  Generate unsigned bitstream"),
                "Aborting.",
            )
        if args.code_signing_key is None:
            common_util.assert_in_error(
                answer_y_n(args,
                           "No CSK specified.  Generate unsigned bitstream"),
                "Aborting.",
            )
        if args.root_bitstream is None:
            common_util.assert_in_error(
                answer_y_n(
                    args,
                    "No root entry hash bitstream specified."
                    "  Verification will not be done.  Continue",
                ),
                "Aborting.",
            )
        else:
            common_util.assert_in_error(
                os.path.isfile(args.root_bitstream),
                "File doesn't exist '{}'".format(args.root_bitstream),
            )
        if args.csk_id is not None:
            common_util.assert_in_error(
                False, "CSK ID cannot be specified for update types")

        maker = reader.UPDATE_reader(args, hsm_manager, args.HSM_config)
    elif args.cert_type == "CANCEL":
        common_util.assert_in_error(args.root_key is not None,
                                    "Cancellation type requires a root key")
        if args.code_signing_key is not None:
            common_util.assert_in_error(
                answer_y_n(args, "CSK specified but not required.  Continue"),
                "Aborting.",
            )
        common_util.assert_in_error(
            args.csk_id is not None,
            "CSK ID must be specified for cancellation types")
        common_util.assert_in_error(
            args.input_file is None,
            "Cancellation not allowed with input file.")
        common_util.assert_in_error(args.output_file is not None,
                                    "No output file specified")
        if args.root_bitstream is None:
            common_util.assert_in_error(
                answer_y_n(
                    args,
                    "No root entry hash bitstream specified."
                    "  Verification will not be done.  Continue",
                ),
                "Aborting.",
            )
        else:
            common_util.assert_in_error(
                os.path.isfile(args.root_bitstream),
                "File doesn't exist '{}'".format(args.root_bitstream),
            )
        if os.path.isfile(args.output_file):
            common_util.assert_in_error(
                answer_y_n(
                    args, "Output file {} exists. Overwrite".format(
                        args.output_file)),
                "Aborting.",
            )

        maker = reader.CANCEL_reader(args, hsm_manager, args.HSM_config)
    elif args.cert_type in ["RK_256", "RK_384"]:
        common_util.assert_in_error(
            args.root_key is not None,
            "Root hash programming requires a root key")
        if args.code_signing_key is not None:
            common_util.assert_in_error(
                answer_y_n(args,
                           "CSK specified and will be ignored.  Continue"),
                "Aborting.",
            )
        if args.csk_id is not None:
            common_util.assert_in_error(
                answer_y_n(args,
                           "CSK ID specified and will be ignored.  Continue"),
                "Aborting.",
            )
        common_util.assert_in_error(
            args.input_file is None,
            "Root hash programming not allowed with input file.",
        )
        common_util.assert_in_error(args.output_file is not None,
                                    "No output file specified")
        if args.root_bitstream is not None:
            common_util.assert_in_error(
                False,
                "--root_bitstream option not allowed for hash programming generation.",
            )
        if os.path.isfile(args.output_file):
            common_util.assert_in_error(
                answer_y_n(
                    args, "Output file {} exists. Overwrite".format(
                        args.output_file)),
                "Aborting.",
            )

        maker = reader.RHP_reader(args, hsm_manager, args.HSM_config)

    logging.shutdown()
    return maker.run()