in nimble/drivers/dialog_cmac/src/ble_hw.c [253:337]
__asm__ volatile (".syntax unified \n"
" ldm %[ptr]!, {r1, r2, r3, r4} \n"
" ldr %[ptr], =%[reg] \n"
" stm %[ptr]!, {r1, r2, r3, r4} \n"
: [ptr] "+l" (src)
: [reg] "i" (&CMAC->CM_CRYPTO_KEY_31_0_REG)
: "r1", "r2", "r3", "r4", "memory");
CMAC->CM_EV_SET_REG = CMAC_CM_EV_SET_REG_EV_CRYPTO_START_Msk;
}
}
void
ble_hw_resolv_proc_enable(void)
{
assert(!g_ble_hw_resolv_proc.f_active);
CMAC->CM_CRYPTO_CTRL_REG = CMAC_CM_CRYPTO_CTRL_REG_CM_CRYPTO_SW_REQ_ABORT_Msk;
CMAC->CM_CRYPTO_CTRL_REG = CMAC_CM_CRYPTO_CTRL_REG_CM_CRYPTO_ECB_ENC_EN_Msk |
CMAC_CM_CRYPTO_CTRL_REG_CM_CRYPTO_IN_SEL_Msk |
CMAC_CM_CRYPTO_CTRL_REG_CM_CRYPTO_OUT_SEL_Msk |
CMAC_CM_CRYPTO_CTRL_REG_CM_CRYPTO_ENC_DECN_Msk;
CMAC->CM_CRYPTO_IN_ADR2_REG = (uint32_t)g_ble_hw_resolv_proc.crypto_prand_in;
CMAC->CM_CRYPTO_OUT_ADR_REG = (uint32_t)g_ble_hw_resolv_proc.crypto_e_out;
g_ble_hw_resolv_proc.irk = g_ble_hw_resolv_list.irk;
g_ble_hw_resolv_proc.irk_end = g_ble_hw_resolv_list.irk +
g_ble_hw_resolv_list.count;
g_ble_hw_resolv_proc.f_configured = 1;
g_ble_hw_resolv_proc.f_active = 0;
/*
* It would be better to enable IRQ in ble_hw_resolv_proc_start, but this
* would introduce a bit of latency when starting resolving procedure and
* we need to save every us possible there in order to be able to resolve
* RPA on time.
*/
NVIC_ClearPendingIRQ(CRYPTO_IRQn);
NVIC_EnableIRQ(CRYPTO_IRQn);
}
void
ble_hw_resolv_proc_disable(void)
{
g_ble_hw_resolv_proc.f_configured = 0;
g_ble_hw_resolv_proc.f_active = 0;
g_ble_hw_resolv_proc.f_match = 0;
g_ble_hw_resolv_proc.f_done = 1;
NVIC_DisableIRQ(CRYPTO_IRQn);
}
void
ble_hw_resolv_proc_reset(const uint8_t *addr)
{
g_ble_hw_resolv_proc.f_match = 0;
}
void
ble_hw_resolv_proc_start(const uint8_t *addr)
{
assert(g_ble_hw_resolv_proc.f_configured);
/* crypto_prand_in is already zeroed so prand is properly padded */
g_ble_hw_resolv_proc.crypto_prand_in[3] = get_be24(&addr[3]) << 8;
g_ble_hw_resolv_proc.hash = get_be24(&addr[0]);
g_ble_hw_resolv_proc.f_match = 0;
g_ble_hw_resolv_proc.f_done = 0;
g_ble_hw_resolv_proc.f_active = 1;
ble_hw_resolv_proc_next();
}
void
CRYPTO_IRQHandler(void)
{
uint32_t hash;
CMAC->CM_EXC_STAT_REG = CMAC_CM_EXC_STAT_REG_EXC_CRYPTO_Msk;
hash = g_ble_hw_resolv_proc.crypto_e_out[3] >> 8;
if (g_ble_hw_resolv_proc.hash == hash) {