@@ -1888,6 +1888,69 @@ int wc_ecc_ctx_reset(ecEncCtx* ctx, WC_RNG* rng); /* reset for use again w/o al
18881888int wc_ecc_ctx_set_algo (ecEncCtx * ctx , byte encAlgo , byte kdfAlgo ,
18891889 byte macAlgo );
18901890
1891+ /*!
1892+ \ingroup ECC
1893+
1894+ \brief This function selects the type of key an ecEncCtx object operates
1895+ on. It can optionally be called after wc_ecc_ctx_new.
1896+
1897+ ECC_CURVE_DEF, the default, means the key pointers handed to the ECIES
1898+ functions are ecc_key pointers. ECC_X25519 and ECC_X448 mean they are
1899+ curve25519_key and curve448_key pointers respectively, in which case they
1900+ must be passed to wc_ecc_encrypt_ex2 and wc_ecc_decrypt_ex2 - the
1901+ ecc_key-typed wc_ecc_encrypt, wc_ecc_encrypt_ex and wc_ecc_decrypt reject a
1902+ context configured for a Montgomery curve.
1903+
1904+ Individual ECC curves are not selectable here: for an ecc_key the curve is
1905+ carried by the key itself. This is a key type selector only.
1906+
1907+ \return 0 Returned upon successfully setting the key type.
1908+ \return NOT_COMPILED_IN Returned if the curve is compiled in but its ECIES
1909+ support is not. See WOLFSSL_ECIES_X25519 and WOLFSSL_ECIES_X448.
1910+ \return BAD_FUNC_ARG Returned if the given ecEncCtx object is NULL or
1911+ curveId is not one of the three values above.
1912+
1913+ \param ctx pointer to the ecEncCtx for which to set the key type
1914+ \param curveId ECC_CURVE_DEF, ECC_X25519 or ECC_X448
1915+
1916+ \note The setting survives wc_ecc_ctx_reset, so a context can be reused
1917+ across the REQ/RESP rounds without reconfiguring it.
1918+
1919+ _Example_
1920+ \code
1921+ ecEncCtx* ctx;
1922+ // initialize ctx
1923+ if (wc_ecc_ctx_set_curve_id(ctx, ECC_X25519) != 0) {
1924+ // error setting the key type
1925+ }
1926+ \endcode
1927+
1928+ \sa wc_ecc_ctx_new
1929+ \sa wc_ecc_ctx_get_curve_id
1930+ \sa wc_ecc_encrypt_ex2
1931+ \sa wc_ecc_decrypt_ex2
1932+ */
1933+
1934+ int wc_ecc_ctx_set_curve_id (ecEncCtx * ctx , int curveId );
1935+
1936+ /*!
1937+ \ingroup ECC
1938+
1939+ \brief This function reads back the key type configured on an ecEncCtx
1940+ object with wc_ecc_ctx_set_curve_id.
1941+
1942+ \return 0 Returned upon successfully reading the key type.
1943+ \return BAD_FUNC_ARG Returned if either argument is NULL.
1944+
1945+ \param ctx pointer to the ecEncCtx to read
1946+ \param curveId pointer to an int that receives ECC_CURVE_DEF, ECC_X25519
1947+ or ECC_X448
1948+
1949+ \sa wc_ecc_ctx_set_curve_id
1950+ */
1951+
1952+ int wc_ecc_ctx_get_curve_id (ecEncCtx * ctx , int * curveId );
1953+
18911954/*!
18921955 \ingroup ECC
18931956
@@ -2243,6 +2306,113 @@ int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
22432306int wc_ecc_decrypt (ecc_key * privKey , ecc_key * pubKey , const byte * msg ,
22442307 word32 msgSz , byte * out , word32 * outSz , ecEncCtx * ctx );
22452308
2309+ /*!
2310+ \ingroup ECC
2311+
2312+ \brief This function encrypts the given message using ECIES, as
2313+ wc_ecc_encrypt_ex does, but takes the keys as void pointers so that a
2314+ Montgomery-curve key can be used. The type the pointers actually have is
2315+ whatever wc_ecc_ctx_set_curve_id selected on ctx: ecc_key for
2316+ ECC_CURVE_DEF, curve25519_key for ECC_X25519, curve448_key for ECC_X448.
2317+
2318+ For the Montgomery curves the ephemeral public key is placed at the front
2319+ of the message as a raw little-endian u-coordinate - 32 bytes for X25519,
2320+ 56 for X448 - with no format byte and no compression. This is the RFC 7748
2321+ encoding used by the TLS key_share extension and by HPKE.
2322+
2323+ \return 0 Returned upon successfully encrypting the message.
2324+ \return BAD_FUNC_ARG Returned if privKey, pubKey, msg, out or outSz is
2325+ NULL, or if compressed is set for a Montgomery curve.
2326+ \return BUFFER_E Returned if the supplied output buffer is too small.
2327+ \return NOT_COMPILED_IN Returned if the selected DEM or curve support is
2328+ not built in.
2329+
2330+ \param privKey pointer to the sender's private key, of the type ctx
2331+ selects. This is normally an ephemeral key, fresh for each message.
2332+ \param pubKey pointer to the peer's public key, of the type ctx selects
2333+ \param msg pointer to the buffer holding the message to encrypt
2334+ \param msgSz size of the buffer to encrypt
2335+ \param out pointer to the buffer in which to store the ciphertext
2336+ \param outSz pointer to a word32 holding the available size in out; on
2337+ success, holds the number of bytes written
2338+ \param ctx pointer to an ecEncCtx object. Mandatory for the Montgomery
2339+ curves: the key type cannot be recovered from a NULL context, and passing
2340+ NULL there would make this function read a curve25519_key or curve448_key
2341+ as though it were an ecc_key.
2342+ \param compressed whether to export the ephemeral public key as a
2343+ compressed point. ECC only; must be 0 for a Montgomery curve.
2344+
2345+ \note The crypto callback (WOLF_CRYPTO_CB) ECIES hooks take ecc_key
2346+ pointers and are therefore bypassed for the Montgomery curves.
2347+
2348+ _Example_
2349+ \code
2350+ byte msg[32]; // padded to the DEM block size
2351+ byte out[CURVE25519_PUB_KEY_SIZE + sizeof(msg) + WC_SHA256_DIGEST_SIZE];
2352+ word32 outSz = sizeof(out);
2353+ curve25519_key eph, peer;
2354+ ecEncCtx* ctx;
2355+ // initialize eph with a fresh key pair and peer with the peer public key
2356+
2357+ ctx = wc_ecc_ctx_new(0, &rng);
2358+ if (wc_ecc_ctx_set_curve_id(ctx, ECC_X25519) != 0) {
2359+ // error selecting the key type
2360+ }
2361+ if (wc_ecc_encrypt_ex2(&eph, &peer, msg, sizeof(msg), out, &outSz, ctx, 0)
2362+ != 0) {
2363+ // error encrypting message
2364+ }
2365+ \endcode
2366+
2367+ \sa wc_ecc_decrypt_ex2
2368+ \sa wc_ecc_ctx_set_curve_id
2369+ \sa wc_ecc_encrypt_ex
2370+ */
2371+
2372+ int wc_ecc_encrypt_ex2 (void * privKey , void * pubKey , const byte * msg ,
2373+ word32 msgSz , byte * out , word32 * outSz , ecEncCtx * ctx , int compressed );
2374+
2375+ /*!
2376+ \ingroup ECC
2377+
2378+ \brief This function decrypts a message produced by wc_ecc_encrypt_ex2.
2379+ The keys are void pointers whose actual type is whatever
2380+ wc_ecc_ctx_set_curve_id selected on ctx.
2381+
2382+ For the Montgomery curves the peer's ephemeral public key is read from the
2383+ front of the message and validated - wc_curve25519_check_public or
2384+ wc_curve448_check_public - before the shared secret is derived. That check
2385+ requires a canonical encoding with the high bit clear, which is what
2386+ wc_ecc_encrypt_ex2 produces.
2387+
2388+ \return 0 Returned upon successfully decrypting the message.
2389+ \return BAD_FUNC_ARG Returned if privKey, msg, out or outSz is NULL, or
2390+ the input is too short to hold a message.
2391+ \return BUFFER_E Returned if the supplied output buffer is too small.
2392+ \return HASH_TYPE_E Returned if the message MAC does not verify.
2393+ \return AES_GCM_AUTH_E Returned if an AES-GCM DEM fails to authenticate.
2394+
2395+ \param privKey pointer to the recipient's private key, of the type ctx
2396+ selects
2397+ \param pubKey optional pointer to storage of the type ctx selects, which
2398+ receives the peer's ephemeral public key. May be NULL, in which case
2399+ temporary storage is used.
2400+ \param msg pointer to the ciphertext to decrypt
2401+ \param msgSz size of the ciphertext
2402+ \param out pointer to the buffer in which to store the plaintext
2403+ \param outSz pointer to a word32 holding the available size in out; on
2404+ success, holds the number of bytes written
2405+ \param ctx pointer to an ecEncCtx object. Mandatory for the Montgomery
2406+ curves, for the same reason as in wc_ecc_encrypt_ex2.
2407+
2408+ \sa wc_ecc_encrypt_ex2
2409+ \sa wc_ecc_ctx_set_curve_id
2410+ \sa wc_ecc_decrypt
2411+ */
2412+
2413+ int wc_ecc_decrypt_ex2 (void * privKey , void * pubKey , const byte * msg ,
2414+ word32 msgSz , byte * out , word32 * outSz , ecEncCtx * ctx );
2415+
22462416
22472417/*!
22482418 \ingroup ECC
0 commit comments