1.1.3 ICM Peripheral Library (ICM)

The Integrity Check Monitor (ICM) is a DMA controller that performs hash calculation over multiple memory regions using transfer descriptors located in memory (ICM Descriptor Area). The Hash function is based on the Secure Hash Algorithm (SHA). The ICM integrates two modes of operation. The first one is used to hash a list of memory regions and save the digests to memory (ICM Hash Area). The second mode is an active monitoring of the memory. In that mode, the hash function is evaluated and compared to the digest located at a predefined memory address (ICM Hash Area). If a mismatch occurs, an interrupt is raised.

Configuring the library

Configure the peripheral library using the MHC.

The MHC can be used to configure the 4 memory regions (without secondary list).

icm_mhc_config
  • "Interrupt Mode" option can be enabled to add interface functions for interrupt support:

    • Interrupts are enable during system initialization

    • ICM_CallbackRegister function can be use to register a callback.

  • "Enable dual input buffer" : If check, set DUALBUFF bit in configuration register. (Higher bandwidth required on system bus)

  • "Automatic switch to compare digest": If check, set ASCD bit in configuration register. (The ICM passes through the Main List once to calculate the message digest of the monitored area. When WRAP = 1 in ICM_RCFG, the ICM begins monitoring).

  • "Bus Burden Control" : If check, set BBC value in configuration register. (The number of system clock cycles between the end of the current processing and the next block transfer is set to 2 exponent BBC . Up to 32,768 cycles can be inserted).

  • "Disable Secondary List Branching" : If check, set SLBDIS bit in configuration register (Branching to the Secondary List is forbidden).

  • "Disable End of Monitoring" : If check, set EOMDIS bit in configuration register (End of Monitoring is forbidden).

  • "Disable Write Back" : If check, set WBDIS bit in configuration register (Write Back operations are forbidden, ICM_RCFG.CDWBN has no effect).

icm_mhc_config_region
  • "Number of Region Descriptor" : Number of regions to configure

  • "Start Address" : The start address of the region.

  • "SHA Algorithm" : The used algorithm to compute hash for this region

  • "SHA Processing Delay" : When SHA1 algorithm is processed, the runtime period is either 85 or 209 clock cycles. When SHA256 or SHA224 algorithm is processed, the runtime period is either 72 or 194 clock cycles.

  • "Disable interrupt events" : Check the events to disable the corresponding interrupt for this region (enabled by default)

  • "Enable End of Monitoring" : The current region descriptor will terminates the Main List. WRAP value has no effect.

  • "Wrap command" : The next region descriptor address loaded is ICM_DSCR register value.

  • "Digest process" : If checked, the digest value is compared to the digest stored in the Hash area. Otherwise, the digest is written to the Hash area.

  • "Size in byte" : Region data size. Should be a multiple of 64.

Using the library

After system initialization and before enabling the ICM, the memory hash address area should be set using the function ICM_SetHashStartAddress. This address should be a multiple of 128 bytes. For each region, 32 bytes are used to store the computed hash:

    /* Hash Buffer were ICM will store the computed hash for each region */
    uint32_t __attribute__((aligned (128))) bufferHash[4][8] = {0};

    /* Set ICM memory address for generated hash */
    ICM_SetHashStartAddress((uint32_t) & bufferHash);

If interrupts are used, the callback function should be set and expected interrupts enabled:

    /* Register ICM Callback */
    ICM_CallbackRegister(ICM_Callback_Function, (uintptr_t)NULL);

    /* Enable Interrupts */
    ICM_InterruptEnable(ICM_INT_MSK_HASH_R0_MASK | ICM_INT_MSK_HASH_R1_MASK |
                        ICM_INT_MSK_HASH_R2_MASK | ICM_INT_MSK_HASH_R3_MASK);

In order to run only one hash of the region, the ICM can be start using ICM_Enable function:

    /* Enable ICM to perform hash of regions */
    ICM_Enable();

To modify the ICM configuration, it should be disabled using the ICM_Disable function:

    /* Disable ICM */
    ICM_Disable();
    /* Wait end of current memory region monitored */
    while ( (ICM_StatusGet() & ICM_STATUS_ENABLE) == ICM_STATUS_ENABLE );

If a first hash has already been performed, the ICM can be run in monitoring mode after disabling the write back feature:

    /* Disable ICM Write back feature */
    ICM_WriteBackDisable(true);

    /* Enable ICM monitor mode */
    ICM_MonitorEnable(ICM_REGION0_MASK | ICM_REGION1_MASK | ICM_REGION2_MASK | ICM_REGION3_MASK);

    /* Enable mismatch interrupts */
    ICM_InterruptEnable(ICM_INT_MSK_DIGEST_MISMATCH_R0_MASK |
                        ICM_INT_MSK_DIGEST_MISMATCH_R1_MASK |
                        ICM_INT_MSK_DIGEST_MISMATCH_R2_MASK |
                        ICM_INT_MSK_DIGEST_MISMATCH_R3_MASK);
    /* Enable ICM */
    ICM_Enable();