crypto: stm32/cryp - reorder hw initialization

The CRYP IP checks the written key depending of the configuration, it's
safer to write the whole configuration to hardware then the key to avoid
unexpected key rejection.

Signed-off-by: Nicolas Toromanoff <nicolas.toromanoff@foss.st.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Nicolas Toromanoff 2021-11-30 08:55:01 +01:00 коммит произвёл Herbert Xu
Родитель 4b898d5cfa
Коммит 95fe2253cc
1 изменённых файлов: 28 добавлений и 15 удалений

Просмотреть файл

@ -232,6 +232,11 @@ static inline int stm32_cryp_wait_busy(struct stm32_cryp *cryp)
!(status & SR_BUSY), 10, 100000); !(status & SR_BUSY), 10, 100000);
} }
static inline void stm32_cryp_enable(struct stm32_cryp *cryp)
{
writel_relaxed(readl_relaxed(cryp->regs + CRYP_CR) | CR_CRYPEN, cryp->regs + CRYP_CR);
}
static inline int stm32_cryp_wait_enable(struct stm32_cryp *cryp) static inline int stm32_cryp_wait_enable(struct stm32_cryp *cryp)
{ {
u32 status; u32 status;
@ -534,9 +539,6 @@ static int stm32_cryp_hw_init(struct stm32_cryp *cryp)
/* Disable interrupt */ /* Disable interrupt */
stm32_cryp_write(cryp, CRYP_IMSCR, 0); stm32_cryp_write(cryp, CRYP_IMSCR, 0);
/* Set key */
stm32_cryp_hw_write_key(cryp);
/* Set configuration */ /* Set configuration */
cfg = CR_DATA8 | CR_FFLUSH; cfg = CR_DATA8 | CR_FFLUSH;
@ -562,24 +564,37 @@ static int stm32_cryp_hw_init(struct stm32_cryp *cryp)
/* AES ECB/CBC decrypt: run key preparation first */ /* AES ECB/CBC decrypt: run key preparation first */
if (is_decrypt(cryp) && if (is_decrypt(cryp) &&
((hw_mode == CR_AES_ECB) || (hw_mode == CR_AES_CBC))) { ((hw_mode == CR_AES_ECB) || (hw_mode == CR_AES_CBC))) {
stm32_cryp_write(cryp, CRYP_CR, cfg | CR_AES_KP | CR_CRYPEN); /* Configure in key preparation mode */
stm32_cryp_write(cryp, CRYP_CR, cfg | CR_AES_KP);
/* Set key only after full configuration done */
stm32_cryp_hw_write_key(cryp);
/* Start prepare key */
stm32_cryp_enable(cryp);
/* Wait for end of processing */ /* Wait for end of processing */
ret = stm32_cryp_wait_busy(cryp); ret = stm32_cryp_wait_busy(cryp);
if (ret) { if (ret) {
dev_err(cryp->dev, "Timeout (key preparation)\n"); dev_err(cryp->dev, "Timeout (key preparation)\n");
return ret; return ret;
} }
cfg |= hw_mode | CR_DEC_NOT_ENC;
/* Apply updated config (Decrypt + algo) and flush */
stm32_cryp_write(cryp, CRYP_CR, cfg);
} else {
cfg |= hw_mode;
if (is_decrypt(cryp))
cfg |= CR_DEC_NOT_ENC;
/* Apply config and flush */
stm32_cryp_write(cryp, CRYP_CR, cfg);
/* Set key only after configuration done */
stm32_cryp_hw_write_key(cryp);
} }
cfg |= hw_mode;
if (is_decrypt(cryp))
cfg |= CR_DEC_NOT_ENC;
/* Apply config and flush (valid when CRYPEN = 0) */
stm32_cryp_write(cryp, CRYP_CR, cfg);
switch (hw_mode) { switch (hw_mode) {
case CR_AES_GCM: case CR_AES_GCM:
case CR_AES_CCM: case CR_AES_CCM:
@ -606,9 +621,7 @@ static int stm32_cryp_hw_init(struct stm32_cryp *cryp)
} }
/* Enable now */ /* Enable now */
cfg |= CR_CRYPEN; stm32_cryp_enable(cryp);
stm32_cryp_write(cryp, CRYP_CR, cfg);
return 0; return 0;
} }