arch/xtensa/esp32: Add support for hardware accelerated PBKDF2

This adds support for the PBKDF2 algorithm in the ESP32 crypto
driver. Here, it will take advantage of the hardware-accelerated
implementation of SHA.

Signed-off-by: Vlad Pruteanu <pruteanuvlad1611@yahoo.com>
This commit is contained in:
Vlad Pruteanu
2026-04-08 11:21:45 +03:00
committed by Xiang Xiao
parent 4f1a3356f9
commit ad168fdf2d
3 changed files with 101 additions and 5 deletions
@@ -410,7 +410,7 @@ RSA No
RTC Yes
SD/MMC Yes SPI based SD card driver
SDIO No
SHA Yes Also supports HMAC-SHA(1/256)
SHA Yes Also supports HMAC-SHA(1/256) and PBKDF2
SPI Yes
SPIFLASH Yes
SPIRAM Yes
+99 -4
View File
@@ -25,6 +25,8 @@
#include <errno.h>
#include <stddef.h>
#include <sys/queue.h>
#include <sys/param.h>
#include <endian.h>
#include <crypto/cryptodev.h>
#include <crypto/xform.h>
@@ -59,7 +61,7 @@ const struct auth_hash g_auth_hash_sha1_esp32 =
{
CRYPTO_SHA1, "SHA1",
0, 20, 12, sizeof(struct esp32_sha_context_s),
0,
HMAC_SHA1_BLOCK_LEN,
sha1_init, NULL, NULL,
sha_update,
sha_final
@@ -69,7 +71,7 @@ const struct auth_hash g_auth_hash_sha2_256_esp32 =
{
CRYPTO_SHA2_256, "SHA256",
0, 32, 12, sizeof(struct esp32_sha_context_s),
0,
HMAC_SHA2_256_BLOCK_LEN,
sha256_init, NULL, NULL,
sha_update,
sha_final
@@ -79,7 +81,7 @@ const struct auth_hash g_auth_hash_sha2_384_esp32 =
{
CRYPTO_SHA2_384, "SHA384",
0, 48, 12, sizeof(struct esp32_sha_context_s),
0,
HMAC_SHA2_384_BLOCK_LEN,
sha384_init, NULL, NULL,
sha_update,
sha_final
@@ -89,7 +91,7 @@ const struct auth_hash g_auth_hash_sha2_512_esp32 =
{
CRYPTO_SHA2_512, "SHA512",
0, 64, 12, sizeof(struct esp32_sha_context_s),
0,
HMAC_SHA2_512_BLOCK_LEN,
sha512_init, NULL, NULL,
sha_update,
sha_final
@@ -334,6 +336,8 @@ static int authcompute(struct cryptop *crp, struct cryptodesc *crd,
{
case CRYPTO_SHA1_HMAC:
case CRYPTO_SHA2_256_HMAC:
case CRYPTO_PBKDF2_HMAC_SHA1:
case CRYPTO_PBKDF2_HMAC_SHA256:
if (data->hw_octx == NULL)
{
return -EINVAL;
@@ -364,6 +368,88 @@ static int authcompute(struct cryptop *crp, struct cryptodesc *crd,
return 0;
}
static void esp32_pbkdf2_rekey(struct esp32_crypto_data *data,
const struct auth_hash *axf,
const caddr_t key, size_t klen)
{
uint8_t keybuf[128];
size_t k;
memcpy(keybuf, key, klen);
for (k = 0; k < klen; k++)
keybuf[k] ^= HMAC_IPAD_VAL;
axf->init(data->hw_ictx);
axf->update(data->hw_ictx, keybuf, klen);
axf->update(data->hw_ictx, hmac_ipad_buffer, axf->blocksize - klen);
axf->init(data->hw_octx);
}
int esp32_pbkdf2(struct cryptop *crp,
struct cryptodesc *crd,
struct esp32_crypto_data *data,
caddr_t buf)
{
const struct auth_hash *axf = data->hw_axf;
uint8_t U[64];
uint8_t T[64];
uint8_t macbuf[64];
uint8_t key_backup[128];
char key_work[128];
struct cryptop crp_dummy;
struct cryptodesc crd_dummy;
size_t generated = 0;
uint32_t blocknum;
uint32_t i;
uint32_t j;
crp_dummy.crp_mac = (caddr_t)macbuf;
crd_dummy.crd_key = key_work;
crd_dummy.crd_klen = crd->crd_klen;
for (blocknum = 1; generated < crp->crp_olen; blocknum++)
{
uint8_t saltblk[crp->crp_ilen + 4];
uint32_t block_be = htobe32(blocknum);
memcpy(saltblk, crp->crp_buf, crp->crp_ilen);
memcpy(saltblk + crp->crp_ilen, &block_be, 4);
/* U1 */
esp32_pbkdf2_rekey(data, axf, crd->crd_key, crd->crd_klen / 8);
memcpy(key_work, crd->crd_key, crd->crd_klen / 8);
crd_dummy.crd_len = crp->crp_ilen + 4;
authcompute(&crp_dummy, &crd_dummy, data, (caddr_t)saltblk);
memcpy(U, macbuf, axf->hashsize);
memcpy(T, U, axf->hashsize);
/* U2..Uc */
for (i = 1; i < crp->crp_iter; i++)
{
uint8_t u_prev[64];
memcpy(u_prev, U, axf->hashsize);
esp32_pbkdf2_rekey(data, axf, crd->crd_key, crd->crd_klen / 8);
memcpy(key_work, crd->crd_key, crd->crd_klen / 8);
crd_dummy.crd_len = axf->hashsize;
authcompute(&crp_dummy, &crd_dummy, data, (caddr_t)u_prev);
memcpy(U, macbuf, axf->hashsize);
for (j = 0; j < axf->hashsize; j++)
T[j] ^= U[j];
}
size_t tocopy = MIN(crp->crp_olen - generated, axf->hashsize);
memcpy(crp->crp_mac + generated, T, tocopy);
generated += tocopy;
}
return 0;
}
/****************************************************************************
* Name: esp32_newsession
*
@@ -474,9 +560,11 @@ static int esp32_newsession(uint32_t *sid, struct cryptoini *cri)
data->hw_axf = axf;
break;
case CRYPTO_SHA1_HMAC:
case CRYPTO_PBKDF2_HMAC_SHA1:
axf = &g_auth_hash_hmac_sha1_esp32;
goto common__hmac;
case CRYPTO_SHA2_256_HMAC:
case CRYPTO_PBKDF2_HMAC_SHA256:
axf = &g_auth_hash_hmac_sha256_esp32;
goto common__hmac;
common__hmac:
@@ -699,6 +787,11 @@ static int esp32_process(struct cryptop *crp)
return crp->crp_etype;
}
break;
case CRYPTO_PBKDF2_HMAC_SHA1:
case CRYPTO_PBKDF2_HMAC_SHA256:
esp32_pbkdf2(crp, crd, data, crp->crp_buf);
break;
default:
return -EINVAL;
}
@@ -733,6 +826,8 @@ void hwcr_init(void)
algs[CRYPTO_SHA2_512] = CRYPTO_ALG_FLAG_SUPPORTED;
algs[CRYPTO_SHA1_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
algs[CRYPTO_SHA2_256_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
algs[CRYPTO_PBKDF2_HMAC_SHA1] = CRYPTO_ALG_FLAG_SUPPORTED;
algs[CRYPTO_PBKDF2_HMAC_SHA256] = CRYPTO_ALG_FLAG_SUPPORTED;
esp32_sha_init();
crypto_register(hwcr_id, algs, esp32_newsession,
@@ -60,4 +60,5 @@ CONFIG_SYSTEM_NSH=y
CONFIG_TESTING_CRYPTO=y
CONFIG_TESTING_CRYPTO_HASH=y
CONFIG_TESTING_CRYPTO_HASH_DISABLE_MD5=y
CONFIG_TESTING_CRYPTO_PBKDF2=y
CONFIG_UART0_SERIAL_CONSOLE=y