diff --git a/Documentation/components/crypto.rst b/Documentation/components/crypto.rst index 4674ddca7cc52..fcc4bb9b1ca0a 100644 --- a/Documentation/components/crypto.rst +++ b/Documentation/components/crypto.rst @@ -192,6 +192,12 @@ Key Management Operations The cryptodev module provides comprehensive key management interfaces: +**Key Derivation** + +- PBKDF2: + - CRYPTO_PBKDF2_HMAC_SHA1 + - CRYPTO_PBKDF2_HMAC_SHA256 + **Key Generation** - CRK_GENERATE_AES_KEY: Generate AES key data with specified key ID diff --git a/boards/xtensa/esp32/esp32-devkitc/configs/crypto/defconfig b/boards/xtensa/esp32/esp32-devkitc/configs/crypto/defconfig index ccbda9a762da0..ccf65c78d1b50 100644 --- a/boards/xtensa/esp32/esp32-devkitc/configs/crypto/defconfig +++ b/boards/xtensa/esp32/esp32-devkitc/configs/crypto/defconfig @@ -44,6 +44,7 @@ CONFIG_NSH_BUILTIN_APPS=y CONFIG_NSH_FILEIOSIZE=512 CONFIG_NSH_READLINE=y CONFIG_NSH_STRERROR=y +CONFIG_TESTING_CRYPTO_PBKDF2=y CONFIG_PREALLOC_TIMERS=0 CONFIG_RAM_SIZE=314688 CONFIG_RAM_START=0x20000000 diff --git a/crypto/cryptodev.c b/crypto/cryptodev.c index 183c7b59a0baf..b4d4ec5f5ddfe 100644 --- a/crypto/cryptodev.c +++ b/crypto/cryptodev.c @@ -264,6 +264,8 @@ static int cryptof_ioctl(FAR struct file *filep, case CRYPTO_SHA2_384: case CRYPTO_SHA2_512: case CRYPTO_CRC32: + case CRYPTO_PBKDF2_HMAC_SHA1: + case CRYPTO_PBKDF2_HMAC_SHA256: thash = true; break; default: @@ -470,6 +472,11 @@ static int cryptodev_op(FAR struct csession *cse, crp.crp_mac = cop->mac; } + if (cop->iterations) + { + crp.crp_iter = cop->iterations; + } + /* try the fast path first */ crp.crp_flags = CRYPTO_F_IOV | CRYPTO_F_NOQUEUE; diff --git a/crypto/cryptosoft.c b/crypto/cryptosoft.c index cfb151b056a1a..bbc6c3be186db 100644 --- a/crypto/cryptosoft.c +++ b/crypto/cryptosoft.c @@ -1156,6 +1156,9 @@ int swcr_authcompute(FAR struct cryptop *crp, case CRYPTO_SHA2_256_HMAC: case CRYPTO_SHA2_384_HMAC: case CRYPTO_SHA2_512_HMAC: + case CRYPTO_PBKDF2_HMAC_SHA1: + case CRYPTO_PBKDF2_HMAC_SHA256: + if (sw->sw_octx == NULL) { return -EINVAL; @@ -1656,12 +1659,14 @@ int swcr_newsession(FAR uint32_t *sid, FAR struct cryptoini *cri) axf = &auth_hash_hmac_md5_96; goto authcommon; case CRYPTO_SHA1_HMAC: + case CRYPTO_PBKDF2_HMAC_SHA1: axf = &auth_hash_hmac_sha1_96; goto authcommon; case CRYPTO_RIPEMD160_HMAC: axf = &auth_hash_hmac_ripemd_160_96; goto authcommon; case CRYPTO_SHA2_256_HMAC: + case CRYPTO_PBKDF2_HMAC_SHA256: axf = &auth_hash_hmac_sha2_256_128; goto authcommon; case CRYPTO_SHA2_384_HMAC: @@ -1892,6 +1897,8 @@ int swcr_freesession(uint64_t tid) case CRYPTO_SHA2_256_HMAC: case CRYPTO_SHA2_384_HMAC: case CRYPTO_SHA2_512_HMAC: + case CRYPTO_PBKDF2_HMAC_SHA1: + case CRYPTO_PBKDF2_HMAC_SHA256: axf = swd->sw_axf; if (swd->sw_ictx) @@ -2047,7 +2054,11 @@ int swcr_process(struct cryptop *crp) } break; + case CRYPTO_PBKDF2_HMAC_SHA1: + case CRYPTO_PBKDF2_HMAC_SHA256: + swcr_pbkdf2(crp, crd, sw, crp->crp_buf); + break; case CRYPTO_MD5: case CRYPTO_POLY1305: case CRYPTO_RIPEMD160: @@ -2090,6 +2101,71 @@ int swcr_process(struct cryptop *crp) return 0; } +int swcr_pbkdf2(FAR struct cryptop *crp, + FAR struct cryptodesc *crd, + FAR struct swcr_data *swd, + caddr_t buf) +{ + uint8_t U[64]; + uint8_t T[64]; + uint8_t macbuf[64]; + uint8_t ictx[256]; + 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; + + for (blocknum = 1; generated < crp->crp_olen; blocknum++) + { + uint8_t saltblk[crp->crp_ilen + 4]; + + memcpy(saltblk, crp->crp_buf, crp->crp_ilen); + *(uint32_t *)(saltblk + crp->crp_ilen) = htobe32(blocknum); + + memcpy(ictx, swd->sw_ictx, swd->sw_axf->ctxsize); + memcpy(&swd->sw_ctx, ictx, swd->sw_axf->ctxsize); + + crd_dummy.crd_skip = 0; + crd_dummy.crd_flags = 0; + + /* U1 */ + + crd_dummy.crd_len = crp->crp_ilen + 4; + swcr_authcompute(&crp_dummy, &crd_dummy, swd, (caddr_t)saltblk); + + memcpy(U, macbuf, swd->sw_axf->hashsize); + memcpy(T, U, swd->sw_axf->hashsize); + + /* U2..Uc */ + + for (i = 1; i < crp->crp_iter; i++) + { + memcpy(&swd->sw_ctx, ictx, swd->sw_axf->ctxsize); + + crd_dummy.crd_len = swd->sw_axf->hashsize; + swcr_authcompute(&crp_dummy, &crd_dummy, swd, (caddr_t)U); + + memcpy(U, macbuf, swd->sw_axf->hashsize); + + for (j = 0; j < swd->sw_axf->hashsize; j++) + T[j] ^= U[j]; + } + + size_t tocopy = MIN(crp->crp_olen - generated, + swd->sw_axf->hashsize); + + memcpy(crp->crp_mac + generated, T, tocopy); + generated += tocopy; + } + + return 0; +} + int swcr_mod_exp(struct cryptkop *krp) { uint8_t *input = (uint8_t *)krp->krp_param[0].crp_p; @@ -2353,6 +2429,8 @@ void swcr_init(void) algs[CRYPTO_CRC32] = CRYPTO_ALG_FLAG_SUPPORTED; algs[CRYPTO_AES_CMAC] = CRYPTO_ALG_FLAG_SUPPORTED; algs[CRYPTO_AES_128_CMAC] = CRYPTO_ALG_FLAG_SUPPORTED; + algs[CRYPTO_PBKDF2_HMAC_SHA1] = CRYPTO_ALG_FLAG_SUPPORTED; + algs[CRYPTO_PBKDF2_HMAC_SHA256] = CRYPTO_ALG_FLAG_SUPPORTED; algs[CRYPTO_ESN] = CRYPTO_ALG_FLAG_SUPPORTED; crypto_register(swcr_id, algs, swcr_newsession, diff --git a/include/crypto/cryptodev.h b/include/crypto/cryptodev.h index 049b7f41f3e95..f58f1b38e4386 100644 --- a/include/crypto/cryptodev.h +++ b/include/crypto/cryptodev.h @@ -135,8 +135,10 @@ #define CRYPTO_CRC32 35 #define CRYPTO_AES_CMAC 36 #define CRYPTO_AES_128_CMAC 37 -#define CRYPTO_ESN 38 /* Support for Extended Sequence Numbers */ -#define CRYPTO_ALGORITHM_MAX 38 /* Keep updated */ +#define CRYPTO_PBKDF2_HMAC_SHA1 38 +#define CRYPTO_PBKDF2_HMAC_SHA256 39 +#define CRYPTO_ESN 40 /* Support for Extended Sequence Numbers */ +#define CRYPTO_ALGORITHM_MAX 40 /* Keep updated */ /* Algorithm flags */ @@ -235,6 +237,7 @@ struct cryptop caddr_t crp_dst; caddr_t crp_iv; caddr_t crp_aad; + int crp_iter; }; #define CRYPTO_BUF_IOV 0x1 @@ -408,6 +411,7 @@ struct crypt_op */ uint16_t flags; + uint32_t iterations; unsigned len; unsigned olen; unsigned ivlen; diff --git a/include/crypto/cryptosoft.h b/include/crypto/cryptosoft.h index 1523a8bf497c0..dd9aef9ebc0ea 100644 --- a/include/crypto/cryptosoft.h +++ b/include/crypto/cryptosoft.h @@ -91,6 +91,8 @@ int swcr_authenc(FAR struct cryptop *); int swcr_compdec(FAR struct cryptodesc *, FAR struct swcr_data *, caddr_t, int); int swcr_rsa_verify(FAR struct cryptkop *); +int swcr_pbkdf2(FAR struct cryptop *, FAR struct cryptodesc *, + FAR struct swcr_data *, caddr_t); int swcr_process(FAR struct cryptop *); int swcr_kprocess(FAR struct cryptkop *); int swcr_newsession(FAR uint32_t *, FAR struct cryptoini *);