| /** |
| * \file ecdh.h |
| * |
| * \brief This file contains ECDH definitions and functions. |
| * |
| * The Elliptic Curve Diffie-Hellman (ECDH) protocol is an anonymous |
| * key agreement protocol allowing two parties to establish a shared |
| * secret over an insecure channel. Each party must have an |
| * elliptic-curve public–private key pair. |
| * |
| * For more information, see <em>NIST SP 800-56A Rev. 2: Recommendation for |
| * Pair-Wise Key Establishment Schemes Using Discrete Logarithm |
| * Cryptography</em>. |
| */ |
| /* |
| * Copyright The Mbed TLS Contributors |
| * SPDX-License-Identifier: Apache-2.0 |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may |
| * not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef MBEDTLS_ECDH_H |
| #define MBEDTLS_ECDH_H |
| #include "mbedtls/private_access.h" |
| |
| #include "mbedtls/build_info.h" |
| |
| #include "mbedtls/ecp.h" |
| |
| /* |
| * Mbed TLS supports two formats for ECDH contexts (#mbedtls_ecdh_context |
| * defined in `ecdh.h`). For most applications, the choice of format makes |
| * no difference, since all library functions can work with either format, |
| * except that the new format is incompatible with MBEDTLS_ECP_RESTARTABLE. |
| |
| * The new format used when this option is disabled is smaller |
| * (56 bytes on a 32-bit platform). In future versions of the library, it |
| * will support alternative implementations of ECDH operations. |
| * The new format is incompatible with applications that access |
| * context fields directly and with restartable ECP operations. |
| */ |
| |
| #if defined(MBEDTLS_ECP_RESTARTABLE) |
| #define MBEDTLS_ECDH_LEGACY_CONTEXT |
| #else |
| #undef MBEDTLS_ECDH_LEGACY_CONTEXT |
| #endif |
| |
| #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) |
| #undef MBEDTLS_ECDH_LEGACY_CONTEXT |
| #include "everest/everest.h" |
| #endif |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /** |
| * Defines the source of the imported EC key. |
| */ |
| typedef enum |
| { |
| MBEDTLS_ECDH_OURS, /**< Our key. */ |
| MBEDTLS_ECDH_THEIRS, /**< The key of the peer. */ |
| } mbedtls_ecdh_side; |
| |
| #if !defined(MBEDTLS_ECDH_LEGACY_CONTEXT) |
| /** |
| * Defines the ECDH implementation used. |
| * |
| * Later versions of the library may add new variants, therefore users should |
| * not make any assumptions about them. |
| */ |
| typedef enum |
| { |
| MBEDTLS_ECDH_VARIANT_NONE = 0, /*!< Implementation not defined. */ |
| MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0,/*!< The default Mbed TLS implementation */ |
| #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) |
| MBEDTLS_ECDH_VARIANT_EVEREST /*!< Everest implementation */ |
| #endif |
| } mbedtls_ecdh_variant; |
| |
| /** |
| * The context used by the default ECDH implementation. |
| * |
| * Later versions might change the structure of this context, therefore users |
| * should not make any assumptions about the structure of |
| * mbedtls_ecdh_context_mbed. |
| */ |
| typedef struct mbedtls_ecdh_context_mbed |
| { |
| mbedtls_ecp_group MBEDTLS_PRIVATE(grp); /*!< The elliptic curve used. */ |
| mbedtls_mpi MBEDTLS_PRIVATE(d); /*!< The private key. */ |
| mbedtls_ecp_point MBEDTLS_PRIVATE(Q); /*!< The public key. */ |
| mbedtls_ecp_point MBEDTLS_PRIVATE(Qp); /*!< The value of the public key of the peer. */ |
| mbedtls_mpi MBEDTLS_PRIVATE(z); /*!< The shared secret. */ |
| #if defined(MBEDTLS_ECP_RESTARTABLE) |
| mbedtls_ecp_restart_ctx MBEDTLS_PRIVATE(rs); /*!< The restart context for EC computations. */ |
| #endif |
| } mbedtls_ecdh_context_mbed; |
| #endif |
| |
| /** |
| * |
| * \warning Performing multiple operations concurrently on the same |
| * ECDSA context is not supported; objects of this type |
| * should not be shared between multiple threads. |
| * \brief The ECDH context structure. |
| */ |
| typedef struct mbedtls_ecdh_context |
| { |
| #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) |
| mbedtls_ecp_group MBEDTLS_PRIVATE(grp); /*!< The elliptic curve used. */ |
| mbedtls_mpi MBEDTLS_PRIVATE(d); /*!< The private key. */ |
| mbedtls_ecp_point MBEDTLS_PRIVATE(Q); /*!< The public key. */ |
| mbedtls_ecp_point MBEDTLS_PRIVATE(Qp); /*!< The value of the public key of the peer. */ |
| mbedtls_mpi MBEDTLS_PRIVATE(z); /*!< The shared secret. */ |
| int MBEDTLS_PRIVATE(point_format); /*!< The format of point export in TLS messages. */ |
| mbedtls_ecp_point MBEDTLS_PRIVATE(Vi); /*!< The blinding value. */ |
| mbedtls_ecp_point MBEDTLS_PRIVATE(Vf); /*!< The unblinding value. */ |
| mbedtls_mpi MBEDTLS_PRIVATE(_d); /*!< The previous \p d. */ |
| #if defined(MBEDTLS_ECP_RESTARTABLE) |
| int MBEDTLS_PRIVATE(restart_enabled); /*!< The flag for restartable mode. */ |
| mbedtls_ecp_restart_ctx MBEDTLS_PRIVATE(rs); /*!< The restart context for EC computations. */ |
| #endif /* MBEDTLS_ECP_RESTARTABLE */ |
| #else |
| uint8_t MBEDTLS_PRIVATE(point_format); /*!< The format of point export in TLS messages |
| as defined in RFC 4492. */ |
| mbedtls_ecp_group_id MBEDTLS_PRIVATE(grp_id);/*!< The elliptic curve used. */ |
| mbedtls_ecdh_variant MBEDTLS_PRIVATE(var); /*!< The ECDH implementation/structure used. */ |
| union |
| { |
| mbedtls_ecdh_context_mbed MBEDTLS_PRIVATE(mbed_ecdh); |
| #if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) |
| mbedtls_ecdh_context_everest MBEDTLS_PRIVATE(everest_ecdh); |
| #endif |
| } MBEDTLS_PRIVATE(ctx); /*!< Implementation-specific context. The |
| context in use is specified by the \c var |
| field. */ |
| #if defined(MBEDTLS_ECP_RESTARTABLE) |
| uint8_t MBEDTLS_PRIVATE(restart_enabled); /*!< The flag for restartable mode. Functions of |
| an alternative implementation not supporting |
| restartable mode must return |
| MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED error |
| if this flag is set. */ |
| #endif /* MBEDTLS_ECP_RESTARTABLE */ |
| #endif /* MBEDTLS_ECDH_LEGACY_CONTEXT */ |
| } |
| mbedtls_ecdh_context; |
| |
| /** |
| * \brief Check whether a given group can be used for ECDH. |
| * |
| * \param gid The ECP group ID to check. |
| * |
| * \return \c 1 if the group can be used, \c 0 otherwise |
| */ |
| int mbedtls_ecdh_can_do( mbedtls_ecp_group_id gid ); |
| |
| /** |
| * \brief This function generates an ECDH keypair on an elliptic |
| * curve. |
| * |
| * This function performs the first of two core computations |
| * implemented during the ECDH key exchange. The second core |
| * computation is performed by mbedtls_ecdh_compute_shared(). |
| * |
| * \see ecp.h |
| * |
| * \param grp The ECP group to use. This must be initialized and have |
| * domain parameters loaded, for example through |
| * mbedtls_ecp_load() or mbedtls_ecp_tls_read_group(). |
| * \param d The destination MPI (private key). |
| * This must be initialized. |
| * \param Q The destination point (public key). |
| * This must be initialized. |
| * \param f_rng The RNG function to use. This must not be \c NULL. |
| * \param p_rng The RNG context to be passed to \p f_rng. This may be |
| * \c NULL in case \p f_rng doesn't need a context argument. |
| * |
| * \return \c 0 on success. |
| * \return Another \c MBEDTLS_ERR_ECP_XXX or |
| * \c MBEDTLS_MPI_XXX error code on failure. |
| */ |
| int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, |
| int (*f_rng)(void *, unsigned char *, size_t), |
| void *p_rng ); |
| |
| /** |
| * \brief This function computes the shared secret. |
| * |
| * This function performs the second of two core computations |
| * implemented during the ECDH key exchange. The first core |
| * computation is performed by mbedtls_ecdh_gen_public(). |
| * |
| * \see ecp.h |
| * |
| * \note If \p f_rng is not NULL, it is used to implement |
| * countermeasures against side-channel attacks. |
| * For more information, see mbedtls_ecp_mul(). |
| * |
| * \param grp The ECP group to use. This must be initialized and have |
| * domain parameters loaded, for example through |
| * mbedtls_ecp_load() or mbedtls_ecp_tls_read_group(). |
| * \param z The destination MPI (shared secret). |
| * This must be initialized. |
| * \param Q The public key from another party. |
| * This must be initialized. |
| * \param d Our secret exponent (private key). |
| * This must be initialized. |
| * \param f_rng The RNG function to use. This must not be \c NULL. |
| * \param p_rng The RNG context to be passed to \p f_rng. This may be |
| * \c NULL if \p f_rng is \c NULL or doesn't need a |
| * context argument. |
| * |
| * \return \c 0 on success. |
| * \return Another \c MBEDTLS_ERR_ECP_XXX or |
| * \c MBEDTLS_MPI_XXX error code on failure. |
| */ |
| int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z, |
| const mbedtls_ecp_point *Q, const mbedtls_mpi *d, |
| int (*f_rng)(void *, unsigned char *, size_t), |
| void *p_rng ); |
| |
| /** |
| * \brief This function initializes an ECDH context. |
| * |
| * \param ctx The ECDH context to initialize. This must not be \c NULL. |
| */ |
| void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx ); |
| |
| /** |
| * \brief This function sets up the ECDH context with the information |
| * given. |
| * |
| * This function should be called after mbedtls_ecdh_init() but |
| * before mbedtls_ecdh_make_params(). There is no need to call |
| * this function before mbedtls_ecdh_read_params(). |
| * |
| * This is the first function used by a TLS server for ECDHE |
| * ciphersuites. |
| * |
| * \param ctx The ECDH context to set up. This must be initialized. |
| * \param grp_id The group id of the group to set up the context for. |
| * |
| * \return \c 0 on success. |
| */ |
| int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx, |
| mbedtls_ecp_group_id grp_id ); |
| |
| /** |
| * \brief This function frees a context. |
| * |
| * \param ctx The context to free. This may be \c NULL, in which |
| * case this function does nothing. If it is not \c NULL, |
| * it must point to an initialized ECDH context. |
| */ |
| void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx ); |
| |
| /** |
| * \brief This function generates an EC key pair and exports its |
| * in the format used in a TLS ServerKeyExchange handshake |
| * message. |
| * |
| * This is the second function used by a TLS server for ECDHE |
| * ciphersuites. (It is called after mbedtls_ecdh_setup().) |
| * |
| * \see ecp.h |
| * |
| * \param ctx The ECDH context to use. This must be initialized |
| * and bound to a group, for example via mbedtls_ecdh_setup(). |
| * \param olen The address at which to store the number of Bytes written. |
| * \param buf The destination buffer. This must be a writable buffer of |
| * length \p blen Bytes. |
| * \param blen The length of the destination buffer \p buf in Bytes. |
| * \param f_rng The RNG function to use. This must not be \c NULL. |
| * \param p_rng The RNG context to be passed to \p f_rng. This may be |
| * \c NULL in case \p f_rng doesn't need a context argument. |
| * |
| * \return \c 0 on success. |
| * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of |
| * operations was reached: see \c mbedtls_ecp_set_max_ops(). |
| * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. |
| */ |
| int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen, |
| unsigned char *buf, size_t blen, |
| int (*f_rng)(void *, unsigned char *, size_t), |
| void *p_rng ); |
| |
| /** |
| * \brief This function parses the ECDHE parameters in a |
| * TLS ServerKeyExchange handshake message. |
| * |
| * \note In a TLS handshake, this is the how the client |
| * sets up its ECDHE context from the server's public |
| * ECDHE key material. |
| * |
| * \see ecp.h |
| * |
| * \param ctx The ECDHE context to use. This must be initialized. |
| * \param buf On input, \c *buf must be the start of the input buffer. |
| * On output, \c *buf is updated to point to the end of the |
| * data that has been read. On success, this is the first byte |
| * past the end of the ServerKeyExchange parameters. |
| * On error, this is the point at which an error has been |
| * detected, which is usually not useful except to debug |
| * failures. |
| * \param end The end of the input buffer. |
| * |
| * \return \c 0 on success. |
| * \return An \c MBEDTLS_ERR_ECP_XXX error code on failure. |
| * |
| */ |
| int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx, |
| const unsigned char **buf, |
| const unsigned char *end ); |
| |
| /** |
| * \brief This function sets up an ECDH context from an EC key. |
| * |
| * It is used by clients and servers in place of the |
| * ServerKeyEchange for static ECDH, and imports ECDH |
| * parameters from the EC key information of a certificate. |
| * |
| * \see ecp.h |
| * |
| * \param ctx The ECDH context to set up. This must be initialized. |
| * \param key The EC key to use. This must be initialized. |
| * \param side Defines the source of the key. Possible values are: |
| * - #MBEDTLS_ECDH_OURS: The key is ours. |
| * - #MBEDTLS_ECDH_THEIRS: The key is that of the peer. |
| * |
| * \return \c 0 on success. |
| * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. |
| * |
| */ |
| int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, |
| const mbedtls_ecp_keypair *key, |
| mbedtls_ecdh_side side ); |
| |
| /** |
| * \brief This function generates a public key and exports it |
| * as a TLS ClientKeyExchange payload. |
| * |
| * This is the second function used by a TLS client for ECDH(E) |
| * ciphersuites. |
| * |
| * \see ecp.h |
| * |
| * \param ctx The ECDH context to use. This must be initialized |
| * and bound to a group, the latter usually by |
| * mbedtls_ecdh_read_params(). |
| * \param olen The address at which to store the number of Bytes written. |
| * This must not be \c NULL. |
| * \param buf The destination buffer. This must be a writable buffer |
| * of length \p blen Bytes. |
| * \param blen The size of the destination buffer \p buf in Bytes. |
| * \param f_rng The RNG function to use. This must not be \c NULL. |
| * \param p_rng The RNG context to be passed to \p f_rng. This may be |
| * \c NULL in case \p f_rng doesn't need a context argument. |
| * |
| * \return \c 0 on success. |
| * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of |
| * operations was reached: see \c mbedtls_ecp_set_max_ops(). |
| * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. |
| */ |
| int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen, |
| unsigned char *buf, size_t blen, |
| int (*f_rng)(void *, unsigned char *, size_t), |
| void *p_rng ); |
| |
| /** |
| * \brief This function parses and processes the ECDHE payload of a |
| * TLS ClientKeyExchange message. |
| * |
| * This is the third function used by a TLS server for ECDH(E) |
| * ciphersuites. (It is called after mbedtls_ecdh_setup() and |
| * mbedtls_ecdh_make_params().) |
| * |
| * \see ecp.h |
| * |
| * \param ctx The ECDH context to use. This must be initialized |
| * and bound to a group, for example via mbedtls_ecdh_setup(). |
| * \param buf The pointer to the ClientKeyExchange payload. This must |
| * be a readable buffer of length \p blen Bytes. |
| * \param blen The length of the input buffer \p buf in Bytes. |
| * |
| * \return \c 0 on success. |
| * \return An \c MBEDTLS_ERR_ECP_XXX error code on failure. |
| */ |
| int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx, |
| const unsigned char *buf, size_t blen ); |
| |
| /** |
| * \brief This function derives and exports the shared secret. |
| * |
| * This is the last function used by both TLS client |
| * and servers. |
| * |
| * \note If \p f_rng is not NULL, it is used to implement |
| * countermeasures against side-channel attacks. |
| * For more information, see mbedtls_ecp_mul(). |
| * |
| * \see ecp.h |
| |
| * \param ctx The ECDH context to use. This must be initialized |
| * and have its own private key generated and the peer's |
| * public key imported. |
| * \param olen The address at which to store the total number of |
| * Bytes written on success. This must not be \c NULL. |
| * \param buf The buffer to write the generated shared key to. This |
| * must be a writable buffer of size \p blen Bytes. |
| * \param blen The length of the destination buffer \p buf in Bytes. |
| * \param f_rng The RNG function to use. This must not be \c NULL. |
| * \param p_rng The RNG context. This may be \c NULL if \p f_rng |
| * doesn't need a context argument. |
| * |
| * \return \c 0 on success. |
| * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of |
| * operations was reached: see \c mbedtls_ecp_set_max_ops(). |
| * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. |
| */ |
| int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen, |
| unsigned char *buf, size_t blen, |
| int (*f_rng)(void *, unsigned char *, size_t), |
| void *p_rng ); |
| |
| #if defined(MBEDTLS_ECP_RESTARTABLE) |
| /** |
| * \brief This function enables restartable EC computations for this |
| * context. (Default: disabled.) |
| * |
| * \see \c mbedtls_ecp_set_max_ops() |
| * |
| * \note It is not possible to safely disable restartable |
| * computations once enabled, except by free-ing the context, |
| * which cancels possible in-progress operations. |
| * |
| * \param ctx The ECDH context to use. This must be initialized. |
| */ |
| void mbedtls_ecdh_enable_restart( mbedtls_ecdh_context *ctx ); |
| #endif /* MBEDTLS_ECP_RESTARTABLE */ |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* ecdh.h */ |