Exemple #1
0
    def _calc_rotkh(self, keys: List[PublicKey]) -> bytes:
        """Calculate ROTKH (Root Of Trust Key Hash).

        :param keys: List of Keys to compute ROTKH.
        :return: Value of ROTKH with right width.
        :raises SPSDKPfrError: Algorithm width doesn't fit into ROTKH field.
        """
        # the data structure use for computing final ROTKH is 4*32B long
        # 32B is a hash of individual keys
        # 4 is the max number of keys, if a key is not provided the slot is filled with '\x00'
        # The LPC55S3x has two options to compute ROTKH, so it's needed to be
        # detected the right algorithm and mandatory warn user about this selection because
        # it's MUST correspond to settings in eFuses!
        reg_rotkh = self.registers.find_reg("ROTKH")
        width = reg_rotkh.width
        if isinstance(keys[0], rsa.RSAPublicKey):
            algorithm_width = 256
        else:
            algorithm_width = keys[0].key_size

        if algorithm_width > width:
            raise SPSDKPfrError("The ROTKH field is smaller than used algorithm width.")

        key_hashes = [calc_pub_key_hash(key, openssl_backend, algorithm_width) for key in keys]
        data = [
            key_hashes[i] if i < len(key_hashes) else bytes(algorithm_width // 8) for i in range(4)
        ]
        return openssl_backend.hash(bytearray().join(data), f"sha{algorithm_width}").ljust(
            width // 8, b"\x00"
        )
Exemple #2
0
    def export(self,
               add_hash: bool = False,
               compute_inverses: bool = False) -> bytes:
        """Generate binary output."""
        data = bytearray(self.BINARY_SIZE)
        for reg in self._get_registers(exclude_computed=False):
            name = reg.attrib["name"]
            width = parse_int(reg.attrib["width"])
            offset = parse_int(reg.attrib["offset"])
            assert width == 32, "Don't know how to handle non-32b registers"
            register = self._export_register(name, compute_inverses)
            # rewriting 4B at the time
            data[offset:offset + 4] = register

        # ROTKH may or may not be present, derived class defines its presense
        if self.HAS_ROTKH:
            rotkh_data = self.rotkh or self._calc_rotkh()
            rothk_start = self._get_rotkh_start_address()
            data[rothk_start:rothk_start + self.ROTKH_SIZE] = rotkh_data

        if add_hash:
            sha_start = self._get_sha_start_address()
            data[sha_start:sha_start + self.SHA_SIZE] = openssl_backend.hash(
                data[:sha_start])
        return bytes(data)
Exemple #3
0
 def _calc_rotkh(self) -> bytes:
     """Calculate ROTKH (Root Of Trust Key Hash)."""
     # the data structure use for computing final ROTKH is 4*32B long
     # 32B is a hash of individual keys
     # 4 is the max number of keys, if a key is not provided the slot is filled with '\x00'
     assert self.keys, f"Key's were not set, can't compute ROTKH"
     key_hashes = [calc_pub_key_hash(key, openssl_backend) for key in self.keys]
     data = [key_hashes[i] if i < len(key_hashes) else bytes(32) for i in range(4)]
     return openssl_backend.hash(bytearray().join(data))
def test_hash():
    plain_text = b'testestestestestestestestestestestestestestestestestestestest'
    text_sha256 = unhexlify(
        "41116FE4EFB90A050AABB83419E19BF2196A0E76AB8E3034C8D674042EE23621")
    calc_sha256 = openssl_backend.hash(plain_text, 'sha256')
    assert calc_sha256 == text_sha256