Skip to content

Implement EC-JPAKE - #11961

Open
AlexLanzano wants to merge 4 commits into
wolfSSL:masterfrom
AlexLanzano:ec-jpake
Open

AlexLanzano wants to merge 4 commits into
wolfSSL:masterfrom
AlexLanzano:ec-jpake

Conversation

@AlexLanzano

@AlexLanzano AlexLanzano commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

Description

Adds EC-JPAKE (RFC 8236 with RFC 8235 Schnorr proofs, profiled per
draft-cragie-tls-ecjpake-01) to wolfCrypt, plus the DTLS 1.2 cipher suite
TLS_ECJPAKE_WITH_AES_128_CCM_8 used for Thread commissioning.

EC-JPAKE is necessary for Thread network commissioning. MBedTLS provides
this but is going EOL. It would be a good thing for wolfssl to add support for
so users of this have an alternative

  • wolfCrypt API in wolfssl/wolfcrypt/ecjpake.h: wc_EcJpakeInit, Free,
    Write/ReadRound1, Write/ReadRound2, DeriveSecret. Messages use the
    TLS encodings. Peer points and proofs are fully validated, and calls must
    follow protocol order.
  • DTLS: round one in the ecjpake_key_kp_pair extension, round two in
    ServerKeyExchange/ClientKeyExchange, no certificates. New
    wolfSSL_CTX_set_ecjpake_password() / wolfSSL_set_ecjpake_password().
    Code points come from the Thread specification.
  • Enable with --enable-ecjpake (-DWOLFSSL_ECJPAKE=yes). Requires ECC and
    SHA-256; not supported with --enable-sp-math.

Testing

  • wolfcrypt/test/test.c: known answer tests against an independent
    implementation, handshakes with matching and mismatched passwords, and
    negative tests for malformed, mutated and reflected messages and API misuse.
  • tests/api/test_ecjpake.c: DTLS 1.2 handshake, wrong password, suite
    negotiation, bad proof, password setters.
  • Ran both suites with --enable-ecjpake --enable-dtls --enable-aesccm: all pass.

Implement EC-JPAKE (RFC 8236 Section 3) with Schnorr NIZK proofs
(RFC 8235 Section 3), profiled as in draft-cragie-tls-ecjpake-01, the
profile used by Thread commissioning: P-256, SHA-256, "client"/"server"
identities, PMS = SHA-256(K.x), and the TLS ECJPAKEKeyKP and
ECSchnorrZKP wire structures.

- New API in wolfssl/wolfcrypt/ecjpake.h: wc_EcJpakeInit/Free,
  wc_EcJpakeWrite/ReadRound1, wc_EcJpakeWrite/ReadRound2 and
  wc_EcJpakeDeriveSecret. Round messages use the TLS encoding so the
  (D)TLS layer can carry them directly.
- Peer points are fully validated, every proof is verified against the
  peer identity, and a shared secret that reduces to zero is rejected.
  Secret scalars go through wc_ecc_mulmod_ex2 with RNG blinding.
- Calls must follow the protocol order; repeated or out of order calls
  return BAD_STATE_E.
- Enable with --enable-ecjpake or -DWOLFSSL_ECJPAKE=yes (defines
  WOLFCRYPT_HAVE_ECJPAKE). Requires ECC and SHA-256; not supported with
  --enable-sp-math.
- wolfcrypt/test/test.c: known answer tests for both roles using
  vectors from an independent implementation of the specifications,
  full handshakes with matching and mismatched passwords, and negative
  tests covering malformed encodings, out of range values, corrupted
  and reflected proofs, round binding, buffer sizes and API misuse.
Implement TLS_ECJPAKE_WITH_AES_128_CCM_8 from draft-cragie-tls-ecjpake-01,
DTLS 1.2 only.

- Round one in the ecjpake_key_kp_pair hello extension; kept across HVR.
- Round two in ServerKeyExchange and ClientKeyExchange; no certificates.
- EC-JPAKE failures send handshake_failure.
- Add wolfSSL_CTX_set_ecjpake_password() and wolfSSL_set_ecjpake_password().
- Codepoints 0xC0,0xFF and 256 come from the Thread specification.
- Add tests/api/test_ecjpake.c.
@AlexLanzano AlexLanzano self-assigned this Nov 2, 2026
Copilot AI balanced review requested due to automatic review settings November 2, 2026 22:50
@github-actions

github-actions Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

MemBrowse Memory Report · Explore what changed →

gcc-arm-cortex-m0plus

  • FLASH: .text +32 B (+0.0%, 70,711 B / 262,144 B, total: 27% used)

gcc-arm-cortex-m3

  • FLASH: .text +64 B (+0.0%, 131,489 B / 262,144 B, total: 50% used)

gcc-arm-cortex-m4

  • FLASH: .text +192 B (+0.1%, 208,624 B / 262,144 B, total: 80% used)

gcc-arm-cortex-m4-baremetal

  • FLASH: .text +64 B (+0.1%, 73,399 B / 262,144 B, total: 28% used)

gcc-arm-cortex-m4-crypto-only

  • FLASH: .text +128 B (+0.1%, 181,715 B / 262,144 B, total: 69% used)

gcc-arm-cortex-m4-dtls13

  • FLASH: .text +256 B (+0.1%, 195,480 B / 1,048,576 B, total: 19% used)

gcc-arm-cortex-m4-openssl-compat

  • FLASH: .rodata +16 B, .text +1,152 B (+0.1%, 798,220 B / 1,048,576 B, total: 76% used)

gcc-arm-cortex-m4-pkcs7

  • FLASH: .text +128 B (+0.1%, 222,804 B / 262,144 B, total: 85% used)

gcc-arm-cortex-m4-pq

  • FLASH: .text +320 B (+0.1%, 312,144 B / 1,048,576 B, total: 30% used)

gcc-arm-cortex-m4-rsa-only

  • FLASH: .text +128 B (+0.0%, 342,792 B / 1,048,576 B, total: 33% used)

gcc-arm-cortex-m4-tls12

  • FLASH: .text +64 B (+0.0%, 132,241 B / 262,144 B, total: 50% used)

gcc-arm-cortex-m4-tls13

  • FLASH: .text +384 B (+0.2%, 249,122 B / 262,144 B, total: 95% used)

gcc-arm-cortex-m7

  • FLASH: .text +256 B (+0.1%, 208,688 B / 262,144 B, total: 80% used)

gcc-arm-cortex-m7-pq

  • FLASH: .text +384 B (+0.1%, 313,040 B / 1,048,576 B, total: 30% used)

gcc-arm-cortex-m7-tls13

  • FLASH: .text +384 B (+0.2%, 249,122 B / 262,144 B, total: 95% used)

stm32-sim-stm32h753

  • FLASH: .text -896 B (-0.4%, 203,692 B / 2,097,152 B, total: 10% used)

zephyr-frdm_rw612

  • FLASH: text -56 B (-0.0%, 283,984 B / 67,108,864 B, total: 0% used)

No memory changes detected for:


Catch memory regressions in CI with MemBrowse. Free for open source.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Secret-dependent variable-time inversion and a client-only build failure remain unresolved, alongside EC-JPAKE negotiation, password-state, and buffer-sizing defects.

5 open issues
What changed in this PR

Adds EC-JPAKE password-authenticated key exchange to wolfCrypt and integrates it with DTLS 1.2 for Thread commissioning.

Changes:

  • Introduces P-256/SHA-256 EC-JPAKE APIs, proof validation, and secret derivation.
  • Adds the DTLS cipher suite, handshake extensions, and password setters.
  • Adds build options, known-answer tests, and handshake and malformed-message tests.
File Description
wolfssl/​wolfcrypt/​include.am Installs the EC-JPAKE public header.
wolfssl/​wolfcrypt/​ecjpake.h Declares EC-JPAKE APIs and state.
wolfssl/​ssl.h Declares DTLS password setters.
wolfssl/​internal.h Adds suite definitions and handshake state.
wolfcrypt/​test/​test.h Declares the cryptographic self-test.
wolfcrypt/​test/​test.c Adds known-answer and negative tests.
wolfcrypt/​src/​ecjpake.c Implements EC-JPAKE exchanges and proofs.
tests/​api/​test_tls.c Excludes EC-JPAKE from certificate-based record tests.
tests/​api/​test_ossl_sk.c Adds cipher-description expectations.
tests/​api/​test_ecjpake.h Declares and groups API tests.
tests/​api/​test_ecjpake.c Tests DTLS negotiation, proofs, and passwords.
tests/​api/​include.am Includes API tests in Autotools builds.
tests/​api.c Registers EC-JPAKE API tests.
src/​tls.c Implements round-one handshake extensions.
src/​ssl.c Adds key-exchange and authentication labels.
src/​ssl_api_hs.c Supports password-based server authentication.
src/​ssl_api_dtls.c Implements password setters.
src/​keys.c Defines cipher-suite parameters.
src/​internal.c Integrates key exchange, negotiation, and cleanup.
src/​include.am Includes the cryptographic implementation.
configure.ac Adds the Autotools feature option and checks.
CMakeLists.txt Adds the CMake option and API test source.
cmake/​options.h.in Exports the feature macro.
cmake/​functions.cmake Selects EC-JPAKE library sources.

Review effort: Balanced

Comment thread src/tls.c Resolved
Comment thread wolfcrypt/src/ecjpake.c Resolved
Comment thread src/internal.c Resolved
Comment thread src/ssl_api_dtls.c Resolved
Comment thread src/tls.c Resolved
- Use constant time mapping for EC-JPAKE point multiplication.
- Fix client only build (TLSX_SetResponse not compiled).
- Size MAX_ENCRYPT_SZ for the client round two message.
- Reject password changes once the exchange has started.
- Require secp256r1 in the client's groups for the suite.
- Add explicit API test guards and new negotiation/password tests.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Secret-dependent scalar arithmetic exposes nonce-dependent timing even in hardened builds, and clearing an unfinished handshake leaves EC-JPAKE state allocated, blocking password replacement on retry.

2 open issues
5 resolved since last review

Review effort: Balanced

Comment thread wolfcrypt/src/ecjpake.c Resolved
Comment thread src/ssl_api_dtls.c Resolved
- Use constant time subtraction for the Schnorr proof response.
- Free EC-JPAKE state in wolfSSL_clear() so the password can change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants