コード例 #1
0
def get_mbi_class(config: Dict[str, Any]) -> Type["MasterBootImage"]:
    """Get Master Boot Image class.

    :raises SPSDKUnsupportedImageType: The invalid configuration.
    :return: MBI Class.
    """
    schema_cfg = ValidationSchemas.get_schema_file(MBIMG_SCH_FILE)
    with open(DEVICE_FILE) as f:
        device_cfg = YAML(typ="safe").load(f)
    # Validate needed configuration to recognize MBI class
    check_config(config, [schema_cfg["image_type"], schema_cfg["family"]])
    try:
        target = get_key_by_val(config["outputImageExecutionTarget"],
                                device_cfg["map_tables"]["targets"])
        authentication = get_key_by_val(
            config["outputImageAuthenticationType"],
            device_cfg["map_tables"]["authentication"])
        family = config["family"]

        cls_name = device_cfg["devices"][family]["images"][target][
            authentication]
    except (KeyError, SPSDKValueError) as exc:
        raise SPSDKUnsupportedImageType(
            "The type of requested Master boot image is not supported for that device."
        ) from exc

    return globals()[cls_name]
コード例 #2
0
def generate_trustzone_binary(tzm_conf: click.File) -> None:
    """Generate TrustZone binary from json configuration file."""
    config_data = load_configuration(tzm_conf.name)
    check_config(config_data, TrustZone.get_validation_schemas())
    trustzone = TrustZone.from_config(config_data)
    tz_data = trustzone.export()
    output_file = config_data["tzpOutputFile"]
    write_file(tz_data, output_file, mode="wb")
    click.echo(f"Success. (Trustzone binary: {output_file} created.)")
コード例 #3
0
def test_schema_invalid_validator():
    """Basic test of scheme validator."""
    schema = {
        "type": "object",
        "properties": {
            "n1": {"type": "invalid_type"},
        },
    }
    with pytest.raises(SPSDKError):
        check_config({}, [schema])
コード例 #4
0
def test_schema_validator_required(test_vector, result):
    """Basic test of scheme validator."""
    schema = {
        "type": "object",
        "properties": {
            "n1": {"type": ["number", "string"], "format": "number"},
            "n2": {"type": "string"},
        },
        "required": ["n1"],
    }

    if result:
        check_config(test_vector, [schema])
    else:
        with pytest.raises(SPSDKError):
            check_config(test_vector, [schema])
コード例 #5
0
    def __init__(
        self,
        mboot: McuBoot,
        user_pck: bytes,
        oem_share_input: bytes,
        info_print: Callable,
        container_conf: str = None,
        workspace: str = None,
    ) -> None:
        """Initialization of device HSM class. Its design to create provisioned SB3 file.

        :param mboot: mBoot communication interface.
        :param oem_share_input: OEM share input data.
        :param user_pck: USER PCK key.
        :param container_conf: Optional elftosb configuration file (to specify user list of SB commands).
        :param workspace: Optional folder to store middle results.
        :raises SPSDKError: In case of any vulnerability.
        """
        self.mboot = mboot
        self.user_pck = user_pck
        self.oem_share_input = oem_share_input
        self.info_print = info_print
        self.workspace = workspace
        if self.workspace and not os.path.isdir(self.workspace):
            os.mkdir(self.workspace)

        # store input of OEM_SHARE_INPUT to workspace in case that is generated randomly
        self.store_temp_res("OEM_SHARE_INPUT.BIN", self.oem_share_input)

        # Default value that could be given from SB3 configuration container
        self.timestamp = None
        self.sb3_descr = "SB3 SB_KEK"
        self.sb3_fw_ver = 0

        # Check the configuration file and options to update by user config
        self.config_data = None
        if container_conf:
            config_data = load_configuration(container_conf)
            # validate input configration
            check_config(config_data, DeviceHsm.get_validation_schemas())
            self.sb3_fw_ver = config_data.get("firmwareVersion") or self.sb3_fw_ver
            self.sb3_descr = config_data.get("description") or self.sb3_descr
            if "timestamp" in config_data:
                self.timestamp = value_to_int(str(config_data.get("timestamp")))

        self.wrapped_user_pck = bytes()
        self.final_sb = bytes()
コード例 #6
0
def generate_master_boot_image(image_conf: click.File) -> None:
    """Generate MasterBootImage from json configuration file.

    :param image_conf: master boot image json configuration file.
    """
    config_data = load_configuration(image_conf.name)
    mbi_cls = get_mbi_class(config_data)
    check_config(config_data, mbi_cls.get_validation_schemas())
    mbi = mbi_cls()
    mbi.load_from_config(config_data)
    mbi_data = mbi.export()

    mbi_output_file_path = config_data["masterBootOutputFile"]
    write_file(mbi_data, mbi_output_file_path, mode="wb")

    click.echo(
        f"Success. (Master Boot Image: {mbi_output_file_path} created.)")
コード例 #7
0
    def __init__(self, data: dict) -> None:
        """Create object out of data loaded from elf2sb configuration file."""
        # Validate input
        sch_cfg = ValidationSchemas.get_schema_file(MBIMG_SCH_FILE)
        sch_crypto_cfg = ValidationSchemas.get_schema_file(CRYPTO_SCH_FILE)
        val_schemas = [
            sch_cfg[x] for x in ["cert_prv_key", "signing_root_prv_key"]
        ]
        val_schemas.extend([
            sch_crypto_cfg[x]
            for x in ["certificate_v2_chain_id", "certificate_root_keys"]
        ])
        check_config(data, val_schemas)

        self.config_data = data
        self.private_key = data.get("mainCertPrivateKeyFile") or data.get(
            "mainRootCertPrivateKeyFile")
        if not self.private_key:
            raise SPSDKError(
                "Private key not specified (mainCertPrivateKeyFile or mainRootCertPrivateKeyFile)"
            )
        public_keys: List[Optional[str]] = [
            data.get(f"rootCertificate{idx}File") for idx in range(4)
        ]
        # filter out None and empty values
        self.public_keys = list(filter(None, public_keys))
        for org, filtered in zip(public_keys, self.public_keys):
            if org != filtered:
                raise SPSDKError(
                    "There are gaps in rootCertificateXFile definition")
        # look for keyID; can't use "or" because 0 is a valid number although it's a "falsy" value
        data_main_cert_index = data.get("mainCertChainId")
        if data_main_cert_index is None:
            data_main_cert_index = data.get("mainRootCertId")
        if data_main_cert_index is None:
            raise SPSDKError(
                "Main Cert ID not specified (mainCertChainId or mainRootCertId)"
            )
        root_cert_file = data.get(f"rootCertificate{data_main_cert_index}File")
        if not root_cert_file:
            raise SPSDKError(
                f"rootCertificate{data_main_cert_index}File doesn't exist")
        self.public_key_index = self.public_keys.index(root_cert_file)
コード例 #8
0
def generate_secure_binary_31(container_conf: click.File) -> None:
    """Geneate SecureBinary image from json configuration file.

    :param container_conf: configuration file
    :raises SPSDKError: Raised when there is no signing key
    """
    config_data = load_configuration(container_conf.name)
    schemas = SecureBinary31.get_validation_schemas(
        include_test_configuration=True)
    schemas.append(
        ValidationSchemas.get_schema_file(SB3_SCH_FILE)["sb3_output"])
    check_config(config_data, schemas)
    sb3 = SecureBinary31.load_from_config(config_data)
    sb3_data = sb3.export()

    sb3_output_file_path = config_data["containerOutputFile"]
    write_file(sb3_data, sb3_output_file_path, mode="wb")

    click.echo(
        f"Success. (Secure binary 3.1: {sb3_output_file_path} created.)")
コード例 #9
0
def test_schema_validator(tmpdir, test_vector, result):
    """Basic test of scheme validator."""
    schema = {
        "type": "object",
        "properties": {
            "n1": {
                "type": ["number", "string"],
                "format": "number"
            },
            "s1": {
                "type": "string"
            },
            "f1": {
                "type": "string",
                "format": "file"
            },
            "f2": {
                "type": "string",
                "format": "optional_file"
            },
            "d1": {
                "type": "string",
                "format": "dir"
            },
        },
    }
    # Create temporary test file
    with open(os.path.join(tmpdir, "testfile.bin"), "wb") as f:
        f.write(bytes(16))

    os.mkdir(os.path.join(tmpdir, "testdir"))

    with use_working_directory(tmpdir):
        if result:
            check_config(test_vector, [schema])
        else:
            with pytest.raises(SPSDKError):
                check_config(test_vector, [schema])