def test_sb_write_all_available_region(self, bl, memType):
        sb_commandDictionay['writeMemory'].cumulativeWrite = False

        startAddress, endAddress, length = common_util.get_available_memory_region(
            bl, memType)
        sb_commandDictionay['writeMemory'].length = length
        sb_commandDictionay[
            'writeMemory'].data = common_util.generate_random_data_file(
                bl, startAddress, length)
        sb_commandDictionay['writeMemory'].dataType = 'file_bin'
        sb_commandDictionay['writeMemory'].startAddress = startAddress
        sb_commandDictionay['writeMemory'].endAddress = startAddress + length
        sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                                 'writeMemory')
        status, results = bl.receive_sb_file(sbFilePath)
        assert status == bootloader.status.kStatus_Success

        # Read back the data from memory
        readFile = os.path.join(bl.vectorsDir, 'read_data_from_memory.bin')
        status, results = bl.read_memory(startAddress, length, readFile)
        assert status == bootloader.status.kStatus_Success

        # The two data files should be the same.
        with open(sb_commandDictionay['writeMemory'].data, 'rb') as fileObj1:
            data1 = fileObj1.read()
            fileObj1.close()
        with open(readFile, 'rb') as fileObj2:
            data2 = fileObj2.read()
            fileObj2.close()

        assert data1 == data2
    def test_sb_fill_all_available_memory(self, bl, memType, pattern_format):
        sb_commandDictionay['fillMemory'].cumulativeFill = False

        startAddress, endAddress, length = common_util.get_available_memory_region(
            bl, memType)
        # ---------------------------------------------------------------------------------
        if pattern_format == 'byte':
            pattern = kFilledValue & 0xFF
        elif pattern_format == 'short':
            pattern = kFilledValue & 0xFFFF
        elif pattern_format == 'word':
            pattern = kFilledValue & 0xFFFFFFFF
        # ---------------------------------------------------------------------------------
        sb_commandDictionay['fillMemory'].pattern = pattern
        sb_commandDictionay['fillMemory'].patternFormat = pattern_format
        sb_commandDictionay['fillMemory'].startAddress = startAddress
        sb_commandDictionay['fillMemory'].endAddress = startAddress + length
        sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                                 'fillMemory')
        status, results = bl.receive_sb_file(sbFilePath)
        assert status == bootloader.status.kStatus_Success
        # Read back the filling data and compare with the filling data.
        read_file = os.path.join(bl.vectorsDir, 'read_data_from_memory.bin')
        status, results = bl.read_memory(startAddress, length, read_file)
        assert common_util.is_fill_memory_correct(read_file, length, pattern,
                                                  pattern_format) == True
    def test_sb_write_unaligned_address(self, bl, memType):
        sb_commandDictionay['writeMemory'].cumulativeWrite = False

        startAddress, endAddress, length = common_util.get_available_memory_region(
            bl, memType)
        # Here we just need a small amount data for this case. Set the length as 1KB.
        length = 0x400
        alignedBase = bl.target.programAlignmentSize
        for offset in range(1, alignedBase):
            sb_commandDictionay['writeMemory'].length = length
            sb_commandDictionay['writeMemory'].dataType = 'file_bin'
            sb_commandDictionay[
                'writeMemory'].startAddress = startAddress + offset
            sb_commandDictionay[
                'writeMemory'].endAddress = startAddress + length + offset
            sb_commandDictionay[
                'writeMemory'].data = common_util.generate_random_data_file(
                    bl, sb_commandDictionay['writeMemory'].startAddress,
                    length)
            sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                                     'writeMemory')
            status, results = bl.receive_sb_file(sbFilePath)
            if memType == 'flash':
                assert status == bootloader.status.kStatus_FlashAlignmentError
            elif memType == 'ram':
                assert status == bootloader.status.kStatus_Success
Пример #4
0
    def test_encrypt_noncontiguous_sections_within_512bytes(self, bl):
        # Get the path of the QCB bin file path
        qcbBinFile = os.path.abspath(
            os.path.join(bl.vectorsDir, 'QSPI', kQspiConfigBlockFile))

        # Use two keyblob regions to encrypt two non-contiguous setion data
        # The first keyblob region
        sbCmdDict[
            'otfadDecryption'].OTFAD_CTX0_START_ADDR = 0x68002300  # keyblob start address
        sbCmdDict[
            'otfadDecryption'].OTFAD_CTX0_END_ADDR = 0x680023FF  # keyblob end address
        sbCmdDict[
            'otfadDecryption'].OTFAD_CTX0_KEY = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
        sbCmdDict['otfadDecryption'].OTFAD_CTX0_CTR = "FFFFFFFFFFFFFFFF"

        # Section data 0 needs to be encrypted
        sbCmdDict['otfadDecryption'].encrypted_type_0 = 'encrypt_write'
        sbCmdDict[
            'otfadDecryption'].encrypted_data_0 = qcbBinFile  # Here can be any other bin files
        # Only encrypt 16 bytes data
        encrypted_data_size_0 = 16
        sbCmdDict['otfadDecryption'].data_location_start_0 = sbCmdDict[
            'otfadDecryption'].OTFAD_CTX0_START_ADDR
        sbCmdDict['otfadDecryption'].data_location_end_0 = sbCmdDict[
            'otfadDecryption'].data_location_start_0 + encrypted_data_size_0

        # The second keyblob region
        sbCmdDict[
            'otfadDecryption'].OTFAD_CTX1_START_ADDR = 0x68002400  # keyblob start address
        sbCmdDict[
            'otfadDecryption'].OTFAD_CTX1_END_ADDR = 0x680027FF  # keyblob end address
        sbCmdDict[
            'otfadDecryption'].OTFAD_CTX1_KEY = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
        sbCmdDict['otfadDecryption'].OTFAD_CTX1_CTR = "FFFFFFFFFFFFFFFF"
        # Section data 1 needs to be encrypted
        sbCmdDict['otfadDecryption'].encrypted_type_1 = 'encrypt_write'
        sbCmdDict[
            'otfadDecryption'].encrypted_data_1 = qcbBinFile  # Here can be any other bin files
        # Only encrypt 16 bytes data
        encrypted_data_size_1 = 16
        sbCmdDict['otfadDecryption'].data_location_start_1 = sbCmdDict[
            'otfadDecryption'].OTFAD_CTX1_START_ADDR
        sbCmdDict['otfadDecryption'].data_location_end_1 = sbCmdDict[
            'otfadDecryption'].data_location_start_1 + encrypted_data_size_1

        # Enable the qspi in bd file
        sbCmdDict['enableQspi'].qspiConfigBlock = qcbBinFile
        sbCmdDict['enableQspi'].qcbLocation = 0x20000000
        # Erase qspi flash in bd file
        sbCmdDict['flashEraseRegion'].startAddress = 0x68000000
        sbCmdDict['flashEraseRegion'].endAddress = 0x68004000

        # Generate sb file according to the parameters
        sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                                 'enableQspi',
                                                 'flashEraseRegion',
                                                 'otfadDecryption')
        status, results = bl.receive_sb_file(sbFilePath)
        # Obviously, the qspi flash 0x68002400 ~ 0x68002500 is cumulative programmed. So send this sb file to target will get QSPI Flash Command Failure
        assert status == bootloader.status.kStatus_Success
    def test_sb_jump_to_sp_pc_with_arg(self, bl, hasArg):
        # Extract SP and PC address from app demo bin file, and then jump to SP and PC without argument
        (elfFile, hexFile, binFile) = common_util.get_led_demo_path(bl)

        sb_commandDictionay['writeMemory'].cumulativeWrite = False
        sb_commandDictionay['writeMemory'].data = binFile
        sb_commandDictionay['writeMemory'].dataType = 'app_bin'
        sb_commandDictionay[
            'writeMemory'].startAddress = bl.target.BL_APP_VECTOR_TABLE_ADDRESS
        sb_commandDictionay['writeMemory'].endAddress = sb_commandDictionay[
            'writeMemory'].startAddress + os.path.getsize(binFile)

        sb_commandDictionay['jumpStackPoint'].hasArg = hasArg
        if hasArg:
            # Set the argument as random 32-bit data if has.
            sb_commandDictionay['jumpStackPoint'].arg = random.randint(
                0, 0xffffffff)
        else:
            sb_commandDictionay['jumpStackPoint'].arg = None
        # Generate sb file
        sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                                 'writeMemory',
                                                 'jumpStackPoint')
        # After excuting receive-sb-file the led will blink immediately and blhost returns kStatus_AbortDataPhase.
        status, results = bl.receive_sb_file(sbFilePath)
        assert status == bootloader.status.kStatus_AbortDataPhase
        # Send command to blhost, it will fail
        status, results = bl.get_property(
            bootloader.properties.kPropertyTag_CurrentVersion)
        status != bootloader.status.kStatus_Success
        # Let led blink for some time so that we can see the correct phenomenon.
        time.sleep(3)
    def test_sb_jump_to_pc_address(self, bl):
        # Extract PC address from app demo bin file, and then jump to PC.
        # The case can pass on K80 while fail on L5K. Jump will not support jump to explicit address, but only support jump to app entry point
        (elfFile, hexFile, binFile) = common_util.get_led_demo_path(bl)

        sb_commandDictionay['writeMemory'].cumulativeWrite = False
        sb_commandDictionay['writeMemory'].data = binFile
        sb_commandDictionay['writeMemory'].dataType = 'app_bin'
        sb_commandDictionay[
            'writeMemory'].startAddress = bl.target.BL_APP_VECTOR_TABLE_ADDRESS
        sb_commandDictionay['writeMemory'].endAddress = sb_commandDictionay[
            'writeMemory'].startAddress + os.path.getsize(binFile)

        # Generate sb file
        sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                                 'writeMemory',
                                                 'jumpEntryPoint')
        # After excuting receive-sb-file the led will blink immediately and blhost returns kStatus_AbortDataPhase.
        status, results = bl.receive_sb_file(sbFilePath)
        assert status == bootloader.status.kStatus_AbortDataPhase
        # Send command to blhost, it will fail
        status, results = bl.get_property(
            bootloader.properties.kPropertyTag_CurrentVersion)
        status != bootloader.status.kStatus_Success
        # Let led blink for some time so that we can see the correct phenomenon.
        time.sleep(3)
Пример #7
0
    def test_encrypt_data_with_its_start_address_not_match_keyblob_start_address(
            self, bl):
        # Get the path of the QCB bin file path
        qcbBinFile = os.path.abspath(
            os.path.join(bl.vectorsDir, 'QSPI', kQspiConfigBlockFile))

        # Only use one keyblob region
        sbCmdDict[
            'otfadDecryption'].OTFAD_CTX0_START_ADDR = 0x68001000  # keyblob start address
        sbCmdDict[
            'otfadDecryption'].OTFAD_CTX0_END_ADDR = 0x6800FFFF  # keyblob end address
        sbCmdDict[
            'otfadDecryption'].OTFAD_CTX0_KEY = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
        sbCmdDict['otfadDecryption'].OTFAD_CTX0_CTR = "FFFFFFFFFFFFFFFF"

        sbCmdDict['otfadDecryption'].encrypted_type_0 = 'encrypt_write'
        # Encrypt the qspi config block data. Here can be any bin files
        sbCmdDict['otfadDecryption'].encrypted_data_0 = qcbBinFile
        # Get the encrypted data size
        data_size = os.path.getsize(
            sbCmdDict['otfadDecryption'].encrypted_data_0)
        # The start address does not match the keyblob start address
        sbCmdDict['otfadDecryption'].data_location_start_0 = sbCmdDict[
            'otfadDecryption'].OTFAD_CTX0_START_ADDR + 0x1000
        sbCmdDict['otfadDecryption'].data_location_end_0 = sbCmdDict[
            'otfadDecryption'].data_location_start_0 + data_size

        # Enable the qspi in bd file
        sbCmdDict['enableQspi'].qspiConfigBlock = qcbBinFile
        sbCmdDict['enableQspi'].qcbLocation = 0x20000000
        # Erase qspi flash in bd file
        sbCmdDict['flashEraseRegion'].startAddress = 0x68000000
        sbCmdDict['flashEraseRegion'].endAddress = 0x68006000

        # Generate sb file according to the parameters
        sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                                 'enableQspi',
                                                 'flashEraseRegion',
                                                 'otfadDecryption')
        status, results = bl.receive_sb_file(sbFilePath)
        assert status == bootloader.status.kStatus_Success

        plaintext = qcbBinFile
        # Read back the ciphertext
        ciphertext = os.path.join(bl.vectorsDir, 'read_data_from_memory.bin')
        status, results = bl.read_memory(
            sbCmdDict['otfadDecryption'].data_location_start_0, data_size,
            ciphertext)
        assert status == bootloader.status.kStatus_Success

        # The plaintext should not be the same with the ciphertext
        with open(plaintext, 'rb') as plain_Obj:
            plain_data = plain_Obj.read()
            plain_Obj.close()
        with open(ciphertext, 'rb') as cipher_Obj:
            ciphter_data = cipher_Obj.read()
            cipher_Obj.close()

        assert plain_data != ciphter_data
Пример #8
0
 def test_erase_all_QSPI_with_sb_file(self, bl):
     # Get qspi block data
     sbCmdDict['enableQspi'].qspiConfigBlock = os.path.abspath(
         os.path.join(bl.vectorsDir, 'QSPI', kQspiConfigBlockFile))
     # Get the location of the qspi block data
     sbCmdDict['enableQspi'].qcbLocation = 0x20000000
     # Generate sb file
     sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                              'enableQspi',
                                              'qspiFlashEraseAll')
     print sbFilePath
     status, results = bl.receive_sb_file(sbFilePath)
     assert status == bootloader.status.kStatus_Success
 def test_sb_load_nothing_to_nonzero_size_space(self, bl):
     # data size is zero while start address is not equal to end address (return kStatusRomLdrChecksum)
     sb_commandDictionay['writeMemory'].cumulativeWrite = False
     sb_commandDictionay['writeMemory'].length = 0
     sb_commandDictionay['writeMemory'].dataType = 'file_bin'
     sb_commandDictionay['writeMemory'].startAddress = 0x1000
     sb_commandDictionay['writeMemory'].endAddress = 0x2000
     sb_commandDictionay[
         'writeMemory'].data = common_util.generate_random_data_file(
             bl, sb_commandDictionay['writeMemory'].startAddress,
             sb_commandDictionay['writeMemory'].length)
     sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                              'writeMemory')
     status, results = bl.receive_sb_file(sbFilePath)
     assert status == bootloader.status.kStatusRomLdrIdNotFound
 def test_sb_erase_out_of_range(self, bl, memType):
     startAddress, endAddress, length = common_util.get_available_memory_region(
         bl, memType)
     # Here we just need a small amount data for this case. Set the erase length as 1 sector.
     length = common_util.get_flash_sector_size(bl)
     # Make sure the start_addr is anligned and near the end of the memory region.
     sb_commandDictionay[
         'flashEraseRegion'].startAddress = endAddress + 1 - bl.target.eraseAlignmentSize
     sb_commandDictionay[
         'flashEraseRegion'].endAddress = sb_commandDictionay[
             'flashEraseRegion'].startAddress + length
     sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                              'flashEraseRegion')
     status, results = bl.receive_sb_file(sbFilePath)
     assert status == bootloader.status.kStatusMemoryRangeInvalid
    def test_sb_erase_available_flash_region(self, bl, availableFlashSize):
        startAddress, endAddress, length = common_util.get_available_memory_region(
            bl, 'flash')
        # 1. Get actual erased length according to the parameter
        if availableFlashSize == 'zero':
            length = 0
        elif availableFlashSize == 'oneSectorSize':
            length = common_util.get_flash_sector_size(bl)
        elif availableFlashSize == 'allAvailableSize':
            length = length
        # 2. erase with blhost command
        status, results = bl.flash_erase_region(startAddress, length)
        assert status == bootloader.status.kStatus_Success
        # 3. write random data to [startAddress, endAddress]
        randomFile = common_util.generate_random_data_file(
            bl, startAddress, length)
        status, results = bl.write_memory(startAddress, randomFile)
        assert status == bootloader.status.kStatus_Success
        # 4. generate sb file and erase with sb command
        sb_commandDictionay['flashEraseRegion'].startAddress = startAddress
        sb_commandDictionay[
            'flashEraseRegion'].endAddress = startAddress + length
        sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                                 'flashEraseRegion')
        status, results = bl.receive_sb_file(sbFilePath)
        assert status == bootloader.status.kStatus_Success
        # 5. read data from [startAddress, endAddress]
        filePath = os.path.join(bl.vectorsDir, 'read_data_from_memory.bin')
        status, results == bl.read_memory(startAddress, length, filePath)
        assert status == bootloader.status.kStatus_Success
        # 6. verify all the data are FF
        flag = True
        fileObj = open(filePath, 'rb')
        for i in range(0, length):
            fileObj.seek(i)
            data_tmp = fileObj.read(1)
            if ord(data_tmp) != 0xFF:
                flag = False
                break
        fileObj.close()
        assert flag == True

        if bl.target.bootloaderType == bootsources.kBootROM_ExecuteROM:
            # 7. unsecure the flash
            status, results = bl.flash_erase_all_unsecure()
            assert status == bootloader.status.kStatus_Success
        else:
            pass
    def test_sb_erase_all_internal_flash(self, bl):
        # 1. generate sb file with "erase all" and send the sb file to target, should be success
        sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                                 'internalFlashEraseAll')
        status, results = bl.receive_sb_file(sbFilePath)
        assert status == bootloader.status.kStatus_Success
        # 2. get flash region that can be erased by 'erase all' with sb file
        startAddress, endAddress, length = common_util.get_available_memory_region(
            bl, 'flash')
        # 3. write random data to [startAddress, endAddress], should be success
        randomFile = common_util.generate_random_data_file(
            bl, startAddress, length)
        status, results = bl.write_memory(startAddress, randomFile)
        assert status == bootloader.status.kStatus_Success
        # 4. erase all the internal flash with sb file, should be success
        status, results = bl.receive_sb_file(sbFilePath)
        assert status == bootloader.status.kStatus_Success
        # 5. read data from [startAddress, endAddress]
        filePath = os.path.join(bl.vectorsDir, 'read_data_from_memory.bin')
        status, results == bl.read_memory(startAddress, length, filePath)
        assert status == bootloader.status.kStatus_Success
        # 6. verify all the data are FF
        flag = True
        fileObj = open(filePath, 'rb')
        for i in range(0, length):
            fileObj.seek(i)
            data_tmp = fileObj.read(1)
            if ord(data_tmp) != 0xFF:
                flag = False
                break
        fileObj.close()
        assert flag == True

        if bl.target.bootloaderType == bootsources.kBootROM_ExecuteROM:
            # 7. reset the target, flash should be in secure state
            status, results = bl.reset()
            assert status == bootloader.status.kStatus_Success
            time.sleep(2)
            status, results = bl.get_property(
                bootloader.properties.kPropertyTag_FlashSecurityState)
            assert status == bootloader.status.kStatus_Success
            assert results[0] == 1
            # 8. unsecure the flash
            status, results = bl.flash_erase_all_unsecure()
            assert status == bootloader.status.kStatus_Success
        else:
            pass
    def test_sb_fill_all_reserved_region(self, bl, memType):
        sb_commandDictionay['fillMemory'].cumulativeFill = False

        startAddress, endAddress, length = common_util.get_reserved_memory_region(
            bl, memType)
        if length == 0:
            pass  # ROM has no reserved flash region
        else:
            sb_commandDictionay['fillMemory'].pattern = kFilledValue
            sb_commandDictionay['fillMemory'].patternFormat = 'word'
            sb_commandDictionay['fillMemory'].startAddress = startAddress
            sb_commandDictionay[
                'fillMemory'].endAddress = startAddress + length
            sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                                     'fillMemory')
            status, results = bl.receive_sb_file(sbFilePath)
            assert status == bootloader.status.kStatusMemoryRangeInvalid
 def test_sb_fill_memory_out_of_range(self, bl, memType):
     sb_commandDictionay['fillMemory'].cumulativeFill = False
     sb_commandDictionay['fillMemory'].pattern = kFilledValue
     sb_commandDictionay['fillMemory'].patternFormat = 'word'
     startAddress, endAddress, length = common_util.get_available_memory_region(
         bl, memType)
     # Here we just need a small amount data for this case. Set the length as 1KB.
     length = 0x400
     # Make sure the start_addr is anligned and near the end of the memory region.
     sb_commandDictionay[
         'fillMemory'].startAddress = endAddress + 1 - bl.target.programAlignmentSize
     sb_commandDictionay['fillMemory'].endAddress = sb_commandDictionay[
         'fillMemory'].startAddress + length
     sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                              'fillMemory')
     status, results = bl.receive_sb_file(sbFilePath)
     assert status == bootloader.status.kStatusMemoryRangeInvalid
 def test_sb_erase_unaligned_length(self, bl, memType):
     startAddress, endAddress, length = common_util.get_available_memory_region(
         bl, memType)
     # Here we just need a small amount data for this case. Set the length as 1KB.
     length = 0x400
     alignBase = bl.target.eraseAlignmentSize
     for i in range(1, alignBase):
         sb_commandDictionay['flashEraseRegion'].startAddress = startAddress
         sb_commandDictionay[
             'flashEraseRegion'].endAddress = startAddress + length + i
         sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                                  'flashEraseRegion')
         status, results = bl.receive_sb_file(sbFilePath)
         if memType == 'flash':
             assert status == bootloader.status.kStatus_FlashAlignmentError
         elif memType == 'ram':
             # erase ram region (including available region and reserved reigion) should return kStatus_FlashAddressError
             assert status == bootloader.status.kStatus_FlashAddressError
 def test_sb_erase_all_reserved_region(self, bl, memType):
     startAddress, endAddress, length = common_util.get_reserved_memory_region(
         bl, memType)
     sb_commandDictionay['flashEraseRegion'].startAddress = startAddress
     sb_commandDictionay[
         'flashEraseRegion'].endAddress = startAddress + length
     sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                              'flashEraseRegion')
     status, results = bl.receive_sb_file(sbFilePath)
     if memType == 'flash':
         # ROM has no reserved region, erase zero length flash should return kStatus_Success, otherwise kStatusMemoryRangeInvalid
         if length == 0:
             assert status == bootloader.status.kStatus_Success
         else:
             assert status == bootloader.status.kStatusMemoryRangeInvalid
     elif memType == 'ram':
         # erase ram region (including available region and reserved reigion) should return kStatus_FlashAddressError
         assert status == bootloader.status.kStatus_FlashAddressError
    def test_sb_cumulative_fill(self, bl, memType):
        sb_commandDictionay['fillMemory'].cumulativeFill = True
        sb_commandDictionay['fillMemory'].pattern = kFilledValue
        sb_commandDictionay['fillMemory'].patternFormat = 'word'

        startAddress, endAddress, length = common_util.get_available_memory_region(
            bl, memType)
        # Here we just need a small amount data for this case. Set the length as 1KB.
        length = 0x400
        sb_commandDictionay['fillMemory'].startAddress = startAddress
        sb_commandDictionay['fillMemory'].endAddress = startAddress + length
        sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                                 'fillMemory')
        status, results = bl.receive_sb_file(sbFilePath)
        if memType == 'flash':
            assert status == bootloader.status.kStatus_FlashCommandFailure or status == bootloader.status.kStatusMemoryCumulativeWrite
        elif memType == 'ram':
            assert status == bootloader.status.kStatus_Success
 def test_sb_jump_to_entry_point(self, bl):
     # .out and .elf file has entry point while .bin file doesn't have.
     (elfFile, hexFile, binFile) = common_util.get_led_demo_path(bl)
     sb_commandDictionay['writeMemory'].cumulativeWrite = False
     sb_commandDictionay['writeMemory'].data = elfFile
     sb_commandDictionay['writeMemory'].dataType = 'app_out'
     # Generate sb file
     sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                              'writeMemory',
                                              'jumpEntryPoint')
     # After excuting receive-sb-file the led will blink immediately and blhost returns kStatus_AbortDataPhase.
     status, results = bl.receive_sb_file(sbFilePath)
     assert status == bootloader.status.kStatus_AbortDataPhase
     # Send command to blhost, it will fail
     status, results = bl.get_property(
         bootloader.properties.kPropertyTag_CurrentVersion)
     status != bootloader.status.kStatus_Success
     # Let led blink for some time so that we can see the correct phenomenon.
     time.sleep(3)
    def test_sb_write_all_reserved_region(self, bl, memType):
        sb_commandDictionay['writeMemory'].cumulativeWrite = False

        startAddress, endAddress, length = common_util.get_reserved_memory_region(
            bl, memType)
        if length == 0:
            pass  # ROM has no flash reserved region.
        else:
            sb_commandDictionay['writeMemory'].length = length
            sb_commandDictionay[
                'writeMemory'].data = common_util.generate_random_data_file(
                    bl, startAddress, length)
            sb_commandDictionay['writeMemory'].dataType = 'file_bin'
            sb_commandDictionay['writeMemory'].startAddress = startAddress
            sb_commandDictionay[
                'writeMemory'].endAddress = startAddress + length
            sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                                     'writeMemory')
            status, results = bl.receive_sb_file(sbFilePath)
            assert status == bootloader.status.kStatusMemoryRangeInvalid
 def test_sb_flash_erase_unsecure(self, bl):
     if bl.target.bootloaderType != bootsources.kBootROM_ExecuteROM:
         pytest.skip('This case only supports the ROM-resident bootloader.')
     else:
         # 1. erase all the flash
         status, results = bl.flash_erase_all()
         assert status == bootloader.status.kStatus_Success
         # 2. generate sb file with "erase unsecure all" and send the sb file to target
         sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                                  'flashEraseAllUnsecure')
         status, results = bl.receive_sb_file(sbFilePath)
         assert status == bootloader.status.kStatus_Success
         # 3. reset target
         status, results = bl.reset()
         assert status == bootloader.status.kStatus_Success
         time.sleep(2)
         # 4. check the flash security state, should be unsecure.
         status, results = bl.get_property(
             bootloader.properties.kPropertyTag_FlashSecurityState)
         assert status == bootloader.status.kStatus_Success
         assert results[0] == 0
 def test_sb_erase_available_ram_region(self, bl, availableRamSize):
     startAddress, endAddress, length = common_util.get_available_memory_region(
         bl, 'ram')
     # 1. Get actual erased length according to the parameter
     if availableRamSize == 'zero':
         length = 0
     elif availableRamSize == 'oneSectorSize':
         length = common_util.get_flash_sector_size(bl)
     elif availableRamSize == 'allAvailableSize':
         length = length
     # 2. generate sb file and erase with sb command
     sb_commandDictionay['flashEraseRegion'].startAddress = startAddress
     sb_commandDictionay[
         'flashEraseRegion'].endAddress = startAddress + length
     sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                              'flashEraseRegion')
     status, results = bl.receive_sb_file(sbFilePath)
     if length == 0:
         assert status == bootloader.status.kStatus_Success
     else:
         # erase ram region (including available region and reserved reigion) should return kStatus_FlashAddressError
         assert status == bootloader.status.kStatus_FlashAddressError
Пример #22
0
    def test_enable_QSPI_with_sb_file(self, bl, qcbLocation):
        # Operate qspi flash will fail before enable qspi
        startAddress, actualLength = get_QSPI_flash_address_and_length(
            1, 'Sectors', 'StartOfMemory')
        # Creat random file that contains actualLength bytes.
        randomFile = common_util.generate_random_data_file(
            bl, startAddress, actualLength)
        status, results = bl.write_memory(startAddress, randomFile)
        assert status == bootloader.status.kStatus_QspiNotConfigured

        # Get qspi block data
        sbCmdDict['enableQspi'].qspiConfigBlock = os.path.abspath(
            os.path.join(bl.vectorsDir, 'QSPI', kQspiConfigBlockFile))
        # Get the location of the qspi block data
        sbCmdDict['enableQspi'].qcbLocation = qcbLocation
        # Generate sb file
        sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                                 'internalFlashEraseAll',
                                                 'enableQspi')
        status, results = bl.receive_sb_file(sbFilePath)
        if qcbLocation == 0:
            if bl.target.bootloaderType == bootsources.kBootFlash_ExecuteFlash:
                # The memory address 0x0 is in the reserved region for flash-resident bootloader.
                assert status == bootloader.status.kStatusMemoryRangeInvalid
            else:
                # Cannot enable QSPI at 0x0 even it is available.
                assert status == bootloader.status.kStatus_InvalidArgument

            # Operate qspi flash will fail
            status, results = bl.flash_erase_region(startAddress, actualLength)
            assert status == bootloader.status.kStatus_QspiNotConfigured
        else:
            assert status == bootloader.status.kStatus_Success
            # Operate qspi flash will be successful after enable qspi
            status, results = bl.flash_erase_region(startAddress, actualLength)
            assert status == bootloader.status.kStatus_Success
    def test_sb_program_4bytes_ifr(self, bl):
        if not bl.target.hasErasableIFR:
            pytest.skip('\nThis chip has no erasable IFR.\n')
        else:
            # Progam the erasable IFR from index 0x30 ~ 0x33
            sb_commandDictionay['programIfr'].ifrIndex1 = 0x30
            sb_commandDictionay['programIfr'].ifrValue1 = 0xFFFFFFFF
            sb_commandDictionay['programIfr'].ifrIndex2 = 0x31
            sb_commandDictionay['programIfr'].ifrValue2 = 0xFFFFFFFF
            sb_commandDictionay['programIfr'].ifrIndex3 = 0x32
            sb_commandDictionay['programIfr'].ifrValue3 = 0xFFFFFFFF
            sb_commandDictionay['programIfr'].ifrIndex4 = 0x33
            sb_commandDictionay['programIfr'].ifrValue4 = 0xFFFFFFFF
            # Generate sb file
            sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                                     'programIfr')
            status, results = bl.receive_sb_file(sbFilePath)
            assert status == bootloader.status.kStatus_Success

            # Read back the IFR values from the index 0x30 to 0x33, and verify the program values.
            status, results = bl.flash_read_once(
                sb_commandDictionay['programIfr'].ifrIndex1, 4)
            assert status == bootloader.status.kStatus_Success
            assert results[1] == sb_commandDictionay['programIfr'].ifrValue1
            status, results = bl.flash_read_once(
                sb_commandDictionay['programIfr'].ifrIndex2, 4)
            assert status == bootloader.status.kStatus_Success
            assert results[1] == sb_commandDictionay['programIfr'].ifrValue2
            status, results = bl.flash_read_once(
                sb_commandDictionay['programIfr'].ifrIndex3, 4)
            assert status == bootloader.status.kStatus_Success
            assert results[1] == sb_commandDictionay['programIfr'].ifrValue3
            status, results = bl.flash_read_once(
                sb_commandDictionay['programIfr'].ifrIndex4, 4)
            assert status == bootloader.status.kStatus_Success
            assert results[1] == sb_commandDictionay['programIfr'].ifrValue4
Пример #24
0
    def test_receive_sb_file_with_flash_secure(self, bl, encryptionType,
                                               dataType, mmcauDataResident):
        if encryptionType == 'unencrypted':
            # Reset the target after flash-erase-all in the setup function so that flash is in secure state.
            status, results = bl.reset()
            assert status == bootloader.status.kStatus_Success
            # Wait for some time to make sure the target is successfully reset.
            time.sleep(2)
            # Check the state of the flash, should be in secure
            status, results = bl.get_property(
                bootloader.properties.kPropertyTag_FlashSecurityState)
            assert results[0] == 1

            # Initialize the sbCmdDict which will be used to generate sb file in sb_command.py.
            init_sbCmdDict(bl, encryptionType, dataType, mmcauDataResident)
            # Generate sb file
            if dataType == 'app_bin':
                sbFilePath = sb_command.generate_sb_file(
                    bl, encryptionType, '', 'writeMemory', 'reset')
            elif dataType == 'string' or dataType == 'function':
                sbFilePath = sb_command.generate_sb_file(
                    bl, encryptionType, '', 'writeMemory')
            # Send the unencrypted sb file to target.
            status, results = bl.receive_sb_file(sbFilePath)
            # Target cannot receive the unencrypted sb file when flash is secure
            assert status == bootloader.status.kStatusRomLdrSecureOnly
            # Delete the sb file
            os.remove(sbFilePath)

        elif bl.target.isEncryptionSupported == True:
            # 1. Program the encryption key to the specified area
            if encryptionType == 'zeroKeyEncrypted':
                key = '00000000000000000000000000000000'
                program_encryption_key(bl, key)
            elif encryptionType == 'nonZeroKeyEncrypted':
                # The encryption key is a string type with length of 32, each character must be 0~F.
                # Generate a random encryption key.
                keyValueFrom = '0123456789ABCDEF'
                key = ''.join(
                    random.sample(keyValueFrom, 16) +
                    random.sample(keyValueFrom, 16))
                program_encryption_key(bl, key)
            else:
                raise ValueError('Invalid encryptionType parameter.')

            # 2. Write BCA data and mmcau data to memory.
            if bl.target.encryptionModuleType == encryptiontypes.kEncryptionType_LTC:
                pass
            elif bl.target.encryptionModuleType == encryptiontypes.kEncryptionType_mmCAU:
                # In the ROM code such as K80, L5K, though it supports the hardware security
                # encryption/decryption operations via CAU coprocessor which is connected to PPB,
                # it uses the software to implement the security encryption/decryption operations.
                # So we must place the mmCAU security functions to the mmcauConfigPointer address
                # whose value will be given in the Bootloader Configuration Area (BCA).                #
                #
                # While for the flash-resident bootloader, it uses the hardware implementation if
                # the target supports it, so it's no need to use the mmCAU security functions and
                # operate the Bootloader Configuration Area (BCA).
                if bl.target.bootloaderType == bootsources.kBootROM_ExecuteROM:
                    mmcauDataAddress = get_MMCAU_function_ready(
                        bl, mmcauDataResident)
                elif bl.target.bootloaderType == bootsources.kBootFlash_ExecuteFlash:
                    pass

            else:
                raise ValueError('Invalid encryptionModuleType.')

            # 3. Reset the target so that the BCA data can be used, and flash is in secure state.
            #    We can use flash-erase-all and reset to set flash in secure state for ROM.
            status, results = bl.reset()
            assert status == bootloader.status.kStatus_Success
            # Wait for some time to make sure the target is successfully reset.
            time.sleep(2)

            # 4. Check the state of the flash, should be in secure
            status, results = bl.get_property(
                bootloader.properties.kPropertyTag_FlashSecurityState)
            assert results[0] == 1

            # 5. Send sb file to target.
            # 5.1 Initialize the sbCmdDict which will be used to generate sb file in sb_command.py.
            init_sbCmdDict(bl, encryptionType, dataType, mmcauDataResident)
            # 5.2 Generate sb file
            if dataType == 'app_bin':
                sbFilePath = sb_command.generate_sb_file(
                    bl, encryptionType, key, 'writeMemory', 'reset')
            elif dataType == 'string' or dataType == 'function':
                sbFilePath = sb_command.generate_sb_file(
                    bl, encryptionType, key, 'writeMemory')
            # 5.3 Send the encrypted sb file to target.
            status, results = bl.receive_sb_file(sbFilePath)
            # 5.4 Delete the sb file
            os.remove(sbFilePath)

            if dataType == 'string':
                assert status == bootloader.status.kStatus_Success
            elif dataType == 'function':
                assert status == bootloader.status.kStatus_Success
                # Call the function will fail because flash is secure.
                status, results = bl.call(
                    sbCmdDict['writeMemory'].startAddress + 1, 0)
                assert status == bootloader.status.kStatus_SecurityViolation
            elif dataType == 'app_bin':
                # After excuting receive-sb-file the led will blink immediately and blhost returns kStatus_AbortDataPhase.
                assert status == bootloader.status.kStatus_AbortDataPhase
                # Let led blink for some time so that we can see the correct phenomenon.
                time.sleep(8)
                # Send command to the target will have no response.
                status, results = bl.get_property(
                    bootloader.properties.kPropertyTag_CurrentVersion)
                assert status != bootloader.status.kStatus_Success

        else:
            pytest.skip(
                "This case should be skipped, because current test platform doesn't support security related feature."
            )
Пример #25
0
    def test_download_encrypted_app_with_encrypted_sb_file(self, bl):
        # Get the led demo that running in the qspi flash
        app_exists, qspiDemo = common_util.get_led_demo_path(
            bl, 'app_srec', running_in_qspi_flash=True)
        if app_exists == False:
            # if not exist the app file, should mark the case as SKIPPED but not FAILED
            print qspiDemo
            pytest.skip("\nDo not find the app demo srec file.")
        else:
            # Get the path of the QCB bin file path
            qcbBinFile = os.path.abspath(
                os.path.join(bl.vectorsDir, 'QSPI', kQspiConfigBlockFile))
            sbCmdDict['otfadDecryption'].qspiDemo = qspiDemo
            # Check if the led demo code is located at 0x68001000
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX0_START_ADDR = 0x68001000  # keyblob start address
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX0_END_ADDR = 0x68001FFF  # keyblob end address
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX0_KEY = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
            sbCmdDict['otfadDecryption'].OTFAD_CTX0_CTR = "FFFFFFFFFFFFFFFF"

            sbCmdDict[
                'otfadDecryption'].encrypted_type_0 = 'encrypt_appSrecFile'

            sbCmdDict[
                'otfadDecryption'].Key_Encryption_Key = "00f1e2d3c4b5a69788796a5b4c3d2e1f"
            # Check if the keyBlobPointer is 0x1000 in the BCA
            sbCmdDict['otfadDecryption'].kek_location = 0x1000

            # Enable the qspi in bd file
            sbCmdDict['enableQspi'].qspiConfigBlock = qcbBinFile
            sbCmdDict['enableQspi'].qcbLocation = 0x20000000
            # Erase qspi flash in bd file
            sbCmdDict['flashEraseRegion'].startAddress = 0x68000000
            sbCmdDict['flashEraseRegion'].endAddress = 0x68002000

            # Erase the whole flash
            status, results = bl.flash_erase_all()
            assert status == bootloader.status.kStatus_Success

            # Generate encrypted sb file
            sb_file_encryption_key = '000102030405060708090a0b0c0d0e0f'
            sbFilePath = sb_command.generate_sb_file(bl, 'nonZeroKeyEncrypted',
                                                     sb_file_encryption_key,
                                                     'enableQspi',
                                                     'flashEraseRegion',
                                                     'otfadDecryption')

            # Get the sb file IFR key according to the given sb_file_encryption_key
            key1, key2, key3, key4 = sb_command.convert_32bit_key(
                sb_file_encryption_key)

            # Program the key to IFR
            key = [key1, key2, key3, key4]
            for i in range(0, len(key)):
                status, results = bl.flash_program_once(0x30 + i, 4, key[i])
                assert status == bootloader.status.kStatus_Success

            # Reset the target and let it be in secure
            status, results = bl.reset()
            assert status == bootloader.status.kStatus_Success
            time.sleep(2)

            # Check if flash is in secure
            status, results = bl.get_property(
                bootloader.properties.kPropertyTag_FlashSecurityState)
            assert status == bootloader.status.kStatus_Success
            assert results[0] == 1

            # Send the encrypted sb file to target
            status, results = bl.receive_sb_file(sbFilePath)
            assert status == bootloader.status.kStatus_Success

            # Reset the target we can see the led blinking
            status, results = bl.reset()
            assert status == bootloader.status.kStatus_Success
            # Let led blink for some time so that we can see the correct phenomenon.
            time.sleep(3)

            # Now communicate with bootloader, it has no response which means OTFAD decrypts the app successfully
            status, results = bl.get_property(
                bootloader.properties.kPropertyTag_CurrentVersion)
            assert status != bootloader.status.kStatus_Success
Пример #26
0
    def test_decrypt_four_nonoverlapped_regions(self, bl):
        # Get the led demo that running in the qspi flash
        app_exists, qspiDemo = common_util.get_led_demo_path(
            bl, 'app_srec', running_in_qspi_flash=True)
        if app_exists == False:
            # if not exist the app file, should mark the case as SKIPPED but not FAILED
            print qspiDemo
            pytest.skip("\nDo not find the app demo srec file.")
        else:
            # Get the path of the QCB bin file path
            qcbBinFile = os.path.abspath(
                os.path.join(bl.vectorsDir, 'QSPI', kQspiConfigBlockFile))

            sbCmdDict['otfadDecryption'].qspiDemo = qspiDemo
            # The first keyblob region. App demo is encrypted and decrypted in this region.
            # Check if the app demo code is located at 0x68001000.
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX0_START_ADDR = 0x68001000  # keyblob start address
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX0_END_ADDR = 0x68001FFF  # keyblob end address
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX0_KEY = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
            sbCmdDict['otfadDecryption'].OTFAD_CTX0_CTR = "FFFFFFFFFFFFFFFF"

            sbCmdDict[
                'otfadDecryption'].encrypted_type_0 = 'encrypt_appSrecFile'

            # The second keyblob region
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX1_START_ADDR = 0x68002000  # keyblob start address
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX1_END_ADDR = 0x68002FFF  # keyblob end address
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX1_KEY = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
            sbCmdDict['otfadDecryption'].OTFAD_CTX1_CTR = "FFFFFFFFFFFFFFFF"

            sbCmdDict['otfadDecryption'].encrypted_type_1 = 'encrypt_write'
            sbCmdDict[
                'otfadDecryption'].encrypted_data_1 = qcbBinFile  # Here can be any other bin files
            sbCmdDict['otfadDecryption'].data_location_start_1 = sbCmdDict[
                'otfadDecryption'].OTFAD_CTX1_START_ADDR
            encrypt_data_size_1 = os.path.getsize(
                sbCmdDict['otfadDecryption'].encrypted_data_1)
            sbCmdDict['otfadDecryption'].data_location_end_1 = sbCmdDict[
                'otfadDecryption'].data_location_start_1 + encrypt_data_size_1

            # The third keyblob region
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX2_START_ADDR = 0x68003000  # keyblob start address
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX2_END_ADDR = 0x68003FFF  # keyblob end address
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX2_KEY = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
            sbCmdDict['otfadDecryption'].OTFAD_CTX2_CTR = "FFFFFFFFFFFFFFFF"

            sbCmdDict['otfadDecryption'].encrypted_type_2 = 'encrypt_write'
            sbCmdDict[
                'otfadDecryption'].encrypted_data_2 = qcbBinFile  # Here can be any other bin files
            sbCmdDict['otfadDecryption'].data_location_start_2 = sbCmdDict[
                'otfadDecryption'].OTFAD_CTX2_START_ADDR
            encrypt_data_size_2 = os.path.getsize(
                sbCmdDict['otfadDecryption'].encrypted_data_2)
            sbCmdDict['otfadDecryption'].data_location_end_2 = sbCmdDict[
                'otfadDecryption'].data_location_start_2 + encrypt_data_size_2

            # The fourth keyblob region
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX3_START_ADDR = 0x68004000  # keyblob start address
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX3_END_ADDR = 0x68004FFF  # keyblob end address
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX3_KEY = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
            sbCmdDict['otfadDecryption'].OTFAD_CTX3_CTR = "FFFFFFFFFFFFFFFF"

            sbCmdDict['otfadDecryption'].encrypted_type_3 = 'encrypt_write'
            sbCmdDict[
                'otfadDecryption'].encrypted_data_3 = qcbBinFile  # Here can be any other bin files
            sbCmdDict['otfadDecryption'].data_location_start_3 = sbCmdDict[
                'otfadDecryption'].OTFAD_CTX3_START_ADDR
            encrypt_data_size_3 = os.path.getsize(
                sbCmdDict['otfadDecryption'].encrypted_data_3)
            sbCmdDict['otfadDecryption'].data_location_end_3 = sbCmdDict[
                'otfadDecryption'].data_location_start_3 + encrypt_data_size_3

            sbCmdDict[
                'otfadDecryption'].Key_Encryption_Key = "5391e2d3c4b5a69788796a5b4c3d2e1f"
            # Check if the keyBlobPointer is 0x1000 in the BCA
            sbCmdDict['otfadDecryption'].kek_location = 0x1000

            # Enable the qspi in bd file
            sbCmdDict['enableQspi'].qspiConfigBlock = qcbBinFile
            sbCmdDict['enableQspi'].qcbLocation = 0x20000000
            # Erase qspi flash in bd file
            sbCmdDict['flashEraseRegion'].startAddress = 0x68000000
            sbCmdDict['flashEraseRegion'].endAddress = 0x68005000

            # Generate encrypted sb file and send the sb file to target
            sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                                     'enableQspi',
                                                     'flashEraseRegion',
                                                     'otfadDecryption')
            status, results = bl.receive_sb_file(sbFilePath)
            assert status == bootloader.status.kStatus_Success

            # ---------------------------------------------------------------------------------------------------
            # Check if the data in these four independent keyblob regions can be successfully decrypted by OTFAD.
            # ---------------------------------------------------------------------------------------------------
            # 1. Reset the target, the led will blink, which means OTFAD decrypts the first keyblob region data.
            status, results = bl.reset()
            assert status == bootloader.status.kStatus_Success
            time.sleep(3)

            # 2. Communicate with bootloader, it will have no response.
            status, results = bl.get_property(
                bootloader.properties.kPropertyTag_CurrentVersion)
            assert status != bootloader.status.kStatus_Success

            # 3. Use JLink to read data from the other three keyblob regions
            decrypted_data_1 = bl.target.read(
                sbCmdDict['otfadDecryption'].data_location_start_1,
                encrypt_data_size_1)
            decrypted_data_2 = bl.target.read(
                sbCmdDict['otfadDecryption'].data_location_start_2,
                encrypt_data_size_2)
            decrypted_data_3 = bl.target.read(
                sbCmdDict['otfadDecryption'].data_location_start_3,
                encrypt_data_size_3)

            # 4. Compare the decryption data with the pliantext
            with open(qcbBinFile, 'rb') as fileObj:
                plaintext = fileObj.read()
                fileObj.close()
            assert decrypted_data_1 == plaintext
            assert decrypted_data_2 == plaintext
            assert decrypted_data_3 == plaintext
Пример #27
0
    def test_encrypt_decrypt_overlapped_region(self, bl):
        # Get the led demo that running in the qspi flash
        app_exists, qspiDemo = common_util.get_led_demo_path(
            bl, running_in_qspi_flash=True)
        if app_exists == False:
            # if not exist the app file, should mark the case as SKIPPED but not FAILED
            print qspiDemo
            pytest.skip("\nDo not find the app demo srec file.")
        else:
            # Get the path of the QCB bin file path
            qcbBinFile = os.path.abspath(
                os.path.join(bl.vectorsDir, 'QSPI', kQspiConfigBlockFile))

            sbCmdDict['otfadDecryption'].qspiDemo = qspiDemo
            # Check if the led demo code is located at 0x68001000
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX0_START_ADDR = 0x68001000  # keyblob start address
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX0_END_ADDR = 0x68001FFF  # keyblob end address
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX0_KEY = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
            sbCmdDict['otfadDecryption'].OTFAD_CTX0_CTR = "FFFFFFFFFFFFFFFF"
            # Encrypt app demo
            sbCmdDict[
                'otfadDecryption'].encrypted_type_0 = 'encrypt_appSrecFile'

            # The second keyblob region
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX1_START_ADDR = 0x68002000  # keyblob start address
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX1_END_ADDR = 0x68002FFF  # keyblob end address
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX1_KEY = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
            sbCmdDict['otfadDecryption'].OTFAD_CTX1_CTR = "FFFFFFFFFFFFFFFF"
            # Encrypt data in the overlapped region (0x68002000 ~ 0x68002FFF)
            sbCmdDict['otfadDecryption'].encrypted_type_1 = 'encrypt_write'
            sbCmdDict[
                'otfadDecryption'].encrypted_data_1 = qcbBinFile  # Here can be any other bin files
            sbCmdDict['otfadDecryption'].data_location_start_1 = sbCmdDict[
                'otfadDecryption'].OTFAD_CTX1_START_ADDR
            encrypt_data_size_1 = os.path.getsize(
                sbCmdDict['otfadDecryption'].encrypted_data_1)
            sbCmdDict['otfadDecryption'].data_location_end_1 = sbCmdDict[
                'otfadDecryption'].data_location_start_1 + encrypt_data_size_1

            # The third keyblob region, which is overlapped with the second keyblob region
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX2_START_ADDR = 0x68002000  # keyblob start address
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX2_END_ADDR = 0x68003FFF  # keyblob end address
            sbCmdDict[
                'otfadDecryption'].OTFAD_CTX2_KEY = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
            sbCmdDict['otfadDecryption'].OTFAD_CTX2_CTR = "FFFFFFFFFFFFFFFF"
            # Encrypt data in the undefined region
            sbCmdDict['otfadDecryption'].encrypted_type_2 = 'encrypt_write'
            sbCmdDict[
                'otfadDecryption'].encrypted_data_2 = qcbBinFile  # Here can be any other bin files
            sbCmdDict[
                'otfadDecryption'].data_location_start_2 = 0x68004000  # undefined keyblob region
            encrypt_data_size_2 = os.path.getsize(
                sbCmdDict['otfadDecryption'].encrypted_data_2)
            sbCmdDict['otfadDecryption'].data_location_end_2 = sbCmdDict[
                'otfadDecryption'].data_location_start_2 + encrypt_data_size_2

            sbCmdDict[
                'otfadDecryption'].Key_Encryption_Key = "5391e2d3c4b5a69788796a5b4c3d2e1f"
            # Check if the keyBlobPointer is 0x1000 in the BCA
            sbCmdDict['otfadDecryption'].kek_location = 0x1000

            # Enable the qspi in bd file
            sbCmdDict['enableQspi'].qspiConfigBlock = qcbBinFile
            sbCmdDict['enableQspi'].qcbLocation = 0x20000000
            # Erase qspi flash in bd file
            sbCmdDict['flashEraseRegion'].startAddress = 0x68000000
            sbCmdDict['flashEraseRegion'].endAddress = 0x68005000

            # Generate encrypted sb file and send the sb file to target
            sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                                     'enableQspi',
                                                     'flashEraseRegion',
                                                     'otfadDecryption')
            status, results = bl.receive_sb_file(sbFilePath)
            assert status == bootloader.status.kStatus_Success

            # ----------------------------------------------------------------------------------------------
            # Check if elftosb.exe encrypts the overlapped region (will encrypt), and
            # check if the elftosb.exe encrypts the undefined region (will not encrypt)
            # ----------------------------------------------------------------------------------------------
            # 1. Get the original data that will be encrypted in the overlapped region
            with open(sbCmdDict['otfadDecryption'].encrypted_data_1,
                      'rb') as fileObj:
                original_data_overlapped = fileObj.read()
                fileObj.close()

            # 2. Get data from the overlapped region after encryption
            binFile = os.path.join(bl.vectorsDir, 'read_data_from_memory.bin')
            status, results = bl.read_memory(
                sbCmdDict['otfadDecryption'].data_location_start_1,
                encrypt_data_size_1, binFile)
            assert status == bootloader.status.kStatus_Success
            with open(binFile, 'rb') as fileObj:
                encrypted_data_overlapped = fileObj.read()
                fileObj.close()
            # elftosb encrypts the overlapped region, so encrypted_data_overlapped is not equal to original_data_overlapped
            assert encrypted_data_overlapped != original_data_overlapped

            # 3. Get the original data that will be encrypted in the undefined region
            with open(sbCmdDict['otfadDecryption'].encrypted_data_2,
                      'rb') as fileObj:
                original_data_undefined = fileObj.read()
                fileObj.close()

            # 4. Get data from the undefined region after encryption
            binFile = os.path.join(bl.vectorsDir, 'read_data_from_memory.bin')
            status, results = bl.read_memory(
                sbCmdDict['otfadDecryption'].data_location_start_2,
                encrypt_data_size_2, binFile)
            assert status == bootloader.status.kStatus_Success
            with open(binFile, 'rb') as fileObj:
                encrypted_data_undefined = fileObj.read()
                fileObj.close()
            # elftosb does not encrypt the undefined region, so encrypted_data_undefined is equal to original_data_undefined
            assert encrypted_data_undefined == original_data_undefined

            # 5. Reset the target we can see the led blinking. OTFAD starts to decrypt after app running.
            status, results = bl.reset()
            assert status == bootloader.status.kStatus_Success
            # Let led blink for some time so that we can see the correct phenomenon.
            time.sleep(3)

            # 6. Now communicate with bootloader, it has no response which means OTFAD decrypts the app successfully
            status, results = bl.get_property(
                bootloader.properties.kPropertyTag_CurrentVersion)
            assert status != bootloader.status.kStatus_Success

            # 7. Get data from the overlapped region after decryption
            decrypted_data_overlapped = bl.target.read(
                sbCmdDict['otfadDecryption'].data_location_start_1,
                encrypt_data_size_1)
            # OTFAD does not decrypt the overlapped region, so decrypted_data_overlapped is equal to encrypted_data_overlapped
            assert decrypted_data_overlapped == encrypted_data_overlapped

            # 8. Get data from the undefined region after decryption
            decrypted_data_undefined = bl.target.read(
                sbCmdDict['otfadDecryption'].data_location_start_2,
                encrypt_data_size_2)
            # OTFAD does not decrypt the undefined region, so decrypted_data_undefined is equal to encrypted_data_undefined
            assert decrypted_data_undefined == encrypted_data_undefined
Пример #28
0
    def test_encrypt_filled_pattern(self, bl):
        # Get the path of the QCB bin file path
        qcbBinFile = os.path.abspath(
            os.path.join(bl.vectorsDir, 'QSPI', kQspiConfigBlockFile))

        # Only use one keyblob region
        qspi_config_block = os.path.abspath(
            os.path.join(bl.vectorsDir, 'QSPI', kQspiConfigBlockFile))
        sbCmdDict[
            'otfadDecryption'].OTFAD_CTX0_START_ADDR = 0x68001000  # keyblob start address
        sbCmdDict[
            'otfadDecryption'].OTFAD_CTX0_END_ADDR = 0x68001FFF  # keyblob end address
        sbCmdDict[
            'otfadDecryption'].OTFAD_CTX0_KEY = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
        sbCmdDict['otfadDecryption'].OTFAD_CTX0_CTR = "FFFFFFFFFFFFFFFF"

        sbCmdDict['otfadDecryption'].encrypted_type_0 = 'encrypt_fill'
        # Encrypt the qspi config block data
        sbCmdDict['otfadDecryption'].encrypted_data_0 = 0x12  # filled pattern
        # Fill 1KB data pattern to have a test
        data_size = 0x400
        # Let the start address matchs the keyblob start address
        sbCmdDict['otfadDecryption'].data_location_start_0 = sbCmdDict[
            'otfadDecryption'].OTFAD_CTX0_START_ADDR
        sbCmdDict['otfadDecryption'].data_location_end_0 = sbCmdDict[
            'otfadDecryption'].data_location_start_0 + data_size

        # Enable the qspi in bd file
        sbCmdDict['enableQspi'].qspiConfigBlock = qcbBinFile
        sbCmdDict['enableQspi'].qcbLocation = 0x20000000
        # Erase qspi flash in bd file
        sbCmdDict['flashEraseRegion'].startAddress = 0x68000000
        sbCmdDict['flashEraseRegion'].endAddress = 0x68006000

        # Generate sb file according to the parameters
        sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                                 'enableQspi',
                                                 'flashEraseRegion',
                                                 'otfadDecryption')
        status, results = bl.receive_sb_file(sbFilePath)
        assert status == bootloader.status.kStatus_Success

        plaintext = common_util.generate_file_according_to_filled_pattern(
            bl, sbCmdDict['otfadDecryption'].encrypted_data_0, 'byte',
            data_size)
        # Read back the ciphertext
        ciphertext = os.path.join(bl.vectorsDir, 'read_data_from_memory.bin')
        status, results = bl.read_memory(
            sbCmdDict['otfadDecryption'].data_location_start_0, data_size,
            ciphertext)
        assert status == bootloader.status.kStatus_Success

        # The plaintext should not be the same with the ciphertext
        with open(plaintext, 'rb') as plain_Obj:
            plain_data = plain_Obj.read()
            plain_Obj.close()
        with open(ciphertext, 'rb') as cipher_Obj:
            ciphter_data = cipher_Obj.read()
            cipher_Obj.close()

        assert plain_data != ciphter_data
 def test_sb_reset_target(self, bl):
     # if app not exist, just generate reset command in sb file
     sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                              'reset')
     status, results = bl.receive_sb_file(sbFilePath)
     assert status == bootloader.status.kStatus_AbortDataPhase
    def test_sb_call_a_function_with_arg(self, bl, hasArg):
        ''' 
        Step 1: Design a function, below is the code in the main.c file.
        ==================================== main.c (start)==========================================
        #include <stdio.h>
        #include <stdint.h>
        #define SysTick_BASE_ADDR       0xE000E010
        #define SYST_RVR_OFFSET         0x04
        #define SYST_RVR_ADDR           (SysTick_BASE_ADDR + SYST_RVR_OFFSET)
        //This function to program the SysTick Reload Value Register (SYST_RVR), which is a 24-bit register.
        //Scenario 1: with one input arguement.
        int program_SYST_RVR_register_with_arg(unsigned int reload_value)
        {
            *((volatile uint32_t*)SYST_RVR_ADDR) = reload_value;
            return 0;
        }
        //Scenario 2: with no input arguement.
        int program_SYST_RVR_register_without_arg(void)
        {
            *((volatile uint32_t*)SYST_RVR_ADDR) = 0x123456; // Program the fix value
            return 0;
        }
        int main()
        {
            return 0;
        }
        ==================================== main.c (end)==========================================
        Step 2: Create an IAR project and add the main.c to the project.
        Step 3: Set the IAR Options-->Linker-->Library-->Entry symbol as the function name 
                (i.e program_SYST_RVR_register_with_arg or program_SYST_RVR_register_without_arg)
        Step 4: Modify the default linker file (Options-->Linker-->Config-->Edit-->Memory Regions-->IROM1 Start: 0xA000)
        Step 5: Build the project and generate the out file 
                (program_SYST_RVR_register_with_arg.out or program_SYST_RVR_register_without_arg).
        '''
        print(
            "Use Jlink to read the SysTick Reload Value Register(24bits) and get the original value:"
        )
        originalValueBinFile = bl.target.dump_memory(SYST_RVR_ADDR, 4)
        fileObj = file(originalValueBinFile, 'rb')
        data = fileObj.read()
        fileObj.close()
        originalValue = ord(data[0]) | (ord(data[1]) << 8) | (
            ord(data[2]) << 16) | (ord(data[3]) << 24)
        print("The original value of SysTick Reload Value Register: 0x%x" %
              (originalValue))

        if hasArg:
            sb_commandDictionay['call'].hasArg = True
            sb_commandDictionay['call'].arg = random.randint(0, 0x00ffffff)
            outFilePath = os.path.join(
                bl.vectorsDir, 'call_function',
                'program_SYST_RVR_register_with_arg.out')
        else:
            sb_commandDictionay['call'].hasArg = False
            sb_commandDictionay['call'].arg = 0x123456
            outFilePath = os.path.join(
                bl.vectorsDir, 'call_function',
                'program_SYST_RVR_register_without_arg.out')
        if not os.path.exists(outFilePath):
            print("Cannot find the out file: %s" % outFilePath)
            raise ValueError("Cannot find the out file: %s" % outFilePath)
        else:
            # Initialize the dictionary
            sb_commandDictionay['writeMemory'].cumulativeWrite = False
            sb_commandDictionay['writeMemory'].data = outFilePath
            sb_commandDictionay['writeMemory'].dataType = 'app_out'

            sb_commandDictionay['flashEraseRegion'].startAddress = 0xA000
            sb_commandDictionay['flashEraseRegion'].endAddress = 0xB000

            # generate sb file
            sbFilePath = sb_command.generate_sb_file(bl, 'unencrypted', '',
                                                     'flashEraseRegion',
                                                     'writeMemory', 'call')
            print(
                "Call a function to program 0x%x to the SysTick Reload Value Register in the sb file:"
                % (sb_commandDictionay['call'].arg)),
            status, results = bl.receive_sb_file(sbFilePath)
            assert status == bootloader.status.kStatus_Success
            os.remove(sbFilePath)
            '''Note: Here we can use both JLink and blhost command to read the SysTick Reload Value Register,
                     but better use JLink, because for some platforms such as L5K, this register is not in the 
                     defined regions in g_memoryMap, which is defined in memory_map_#platform.c file, so when 
                     using read-mmeory to read this register, blhost always returns kStatusMemoryRangeInvalid.
            '''
            # Read SysTick Reload Value Register(24bits) and compare it with the input arg, should be equal.
            programmedValueBinFile = bl.target.dump_memory(SYST_RVR_ADDR, 4)
            fileObj = file(programmedValueBinFile, 'rb')
            data = fileObj.read()
            fileObj.close()
            programmedValue = ord(data[0]) | (ord(data[1]) << 8) | (
                ord(data[2]) << 16) | (ord(data[3]) << 24)
            print(
                "After calling the function, the value of SysTick Reload Value Register is changing to 0x%x"
                % (programmedValue))
            if programmedValue == sb_commandDictionay['call'].arg:
                print("0x%x == 0x%x, call the function successfully!" %
                      (programmedValue, sb_commandDictionay['call'].arg))
                testResult = True
            else:
                print("0x%x != 0x%x, call the function fail!" %
                      (programmedValue, sb_commandDictionay['call'].arg))
                testResult = False
            assert testResult == True

            print(
                "Use Jlink to write the original value back to the SysTick Reload Value Register(24bits):"
            )
            bl.target.restore_memory(SYST_RVR_ADDR, originalValueBinFile)