| /** |
| * \file dhm.h |
| * |
| * \brief Diffie-Hellman-Merkle key exchange |
| * |
| * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
| * 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. |
| * |
| * This file is part of mbed TLS (https://tls.mbed.org) |
| */ |
| #ifndef MBEDTLS_DHM_H |
| #define MBEDTLS_DHM_H |
| |
| #include "bignum.h" |
| |
| /* |
| * DHM Error codes |
| */ |
| #define MBEDTLS_ERR_DHM_BAD_INPUT_DATA -0x3080 /**< Bad input parameters to function. */ |
| #define MBEDTLS_ERR_DHM_READ_PARAMS_FAILED -0x3100 /**< Reading of the DHM parameters failed. */ |
| #define MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED -0x3180 /**< Making of the DHM parameters failed. */ |
| #define MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED -0x3200 /**< Reading of the public values failed. */ |
| #define MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED -0x3280 /**< Making of the public value failed. */ |
| #define MBEDTLS_ERR_DHM_CALC_SECRET_FAILED -0x3300 /**< Calculation of the DHM secret failed. */ |
| #define MBEDTLS_ERR_DHM_INVALID_FORMAT -0x3380 /**< The ASN.1 data is not formatted correctly. */ |
| #define MBEDTLS_ERR_DHM_ALLOC_FAILED -0x3400 /**< Allocation of memory failed. */ |
| #define MBEDTLS_ERR_DHM_FILE_IO_ERROR -0x3480 /**< Read/write of file failed. */ |
| |
| #if ! defined(MBEDTLS_DEPRECATED_REMOVED) |
| #if defined(MBEDTLS_DEPRECATED_WARNING) |
| #define MBEDTLS_DEPRECATED __attribute__((deprecated)) |
| #else |
| #define MBEDTLS_DEPRECATED |
| #endif |
| #endif |
| |
| /** |
| * RFC 3526, RFC 5114 and RFC 7919 standardize a number of |
| * Diffie-Hellman groups, some of which are included here |
| * for use within the SSL/TLS module and the user's convenience |
| * when configuring the Diffie-Hellman parameters by hand |
| * through \c mbedtls_ssl_conf_dh_param. |
| * |
| * Included are: |
| * RFC 5114 2.2. 2048-bit MODP Group with 224-bit Prime Order Subgroup |
| * RFC 3526 3. 2048-bit MODP Group |
| * RFC 3526 4. 3072-bit MODP Group |
| * RFC 3526 5. 4096-bit MODP Group |
| * RFC 7919 A.1 ffdhe2048 |
| * RFC 7919 A.2 ffdhe3072 |
| * RFC 7919 A.3 ffdhe4096 |
| * RFC 7919 A.4 ffdhe6144 |
| * RFC 7919 A.5 ffdhe8192 |
| * |
| * The constants with suffix "_p" denote the chosen prime moduli, while |
| * the constants with suffix "_g" denote the chosen generator |
| * of the associated prime field. |
| * |
| * All constants are represented as null-terminated strings containing the |
| * hexadecimal presentation of the respective numbers. |
| * |
| * \warning The origin of the primes in RFC 5114 is not documented and |
| * their use therefore constitutes a security risk! |
| * |
| * \deprecated The primes from RFC 5114 are superseded by the primes |
| * from RFC 3526 and RFC 7919 and should no longer be used. |
| * They will be removed in the next major revision. |
| * |
| * The primes from RFC 3526 and RFC 7919 have been generating by the following |
| * trust-worthy procedure: |
| * - Fix N in { 2048, 3072, 4096, 6144, 8192 } and consider the N-bit number |
| * the first and last 64 bits are all 1, and the remaining N - 128 bits of |
| * which are 0x7ff...ff. |
| * - Add the smallest multiple of the first N - 129 bits of the binary expansion |
| * of pi (for RFC 5236) or e (for RFC 7919) to this intermediate bit-string |
| * such that the resulting integer is a safe-prime. |
| * - The result is the respective RFC 3526 / 7919 prime, and the corresponding |
| * generator is always chosen to be 2 (which is a square for these prime, |
| * hence the corresponding subgroup has order (p-1)/2 and avoids leaking a |
| * bit in the private exponent). |
| * |
| * The above description can be validated using the |
| * the program programs/util/rfc_3526_7919_verify. |
| */ |
| |
| const char * const mbedtls_dhm_rfc3526_modp_2048_p; |
| const char * const mbedtls_dhm_rfc3526_modp_2048_g; |
| const char * const mbedtls_dhm_rfc3526_modp_3072_p; |
| const char * const mbedtls_dhm_rfc3526_modp_3072_g; |
| const char * const mbedtls_dhm_rfc3526_modp_4096_p; |
| const char * const mbedtls_dhm_rfc3526_modp_4096_g; |
| |
| const char * const mbedtls_dhm_rfc7919_ffdhe2048_p; |
| const char * const mbedtls_dhm_rfc7919_ffdhe2048_g; |
| const char * const mbedtls_dhm_rfc7919_ffdhe3072_p; |
| const char * const mbedtls_dhm_rfc7919_ffdhe3072_g; |
| const char * const mbedtls_dhm_rfc7919_ffdhe4096_p; |
| const char * const mbedtls_dhm_rfc7919_ffdhe4096_g; |
| const char * const mbedtls_dhm_rfc7919_ffdhe6144_p; |
| const char * const mbedtls_dhm_rfc7919_ffdhe6144_g; |
| const char * const mbedtls_dhm_rfc7919_ffdhe8192_p; |
| const char * const mbedtls_dhm_rfc7919_ffdhe8192_g; |
| |
| #if !defined(MBEDTLS_DEPRECATED_REMOVED) |
| MBEDTLS_DEPRECATED const char * const mbedtls_dhm_rfc5114_modp_2048_p; |
| MBEDTLS_DEPRECATED const char * const mbedtls_dhm_rfc5114_modp_2048_g; |
| #endif |
| |
| /** |
| * \deprecated These macros are superseded by direct access to the corresponding |
| * global variables and will be removed in the next major revision. |
| */ |
| #if !defined(MBEDTLS_DEPRECATED_REMOVED) |
| #define MBEDTLS_DHM_RFC5114_MODP_2048_P mbedtls_dhm_rfc5114_modp_2048_p |
| #define MBEDTLS_DHM_RFC5114_MODP_2048_G mbedtls_dhm_rfc5114_modp_2048_g |
| #define MBEDTLS_DHM_RFC3526_MODP_2048_P mbedtls_dhm_rfc3526_modp_2048_p |
| #define MBEDTLS_DHM_RFC3526_MODP_2048_G mbedtls_dhm_rfc3526_modp_2048_g |
| #define MBEDTLS_DHM_RFC3526_MODP_3072_P mbedtls_dhm_rfc3526_modp_3072_p |
| #define MBEDTLS_DHM_RFC3526_MODP_3072_G mbedtls_dhm_rfc3526_modp_3072_g |
| #define MBEDTLS_DHM_RFC3526_MODP_4096_P mbedtls_dhm_rfc3526_modp_4096_p |
| #define MBEDTLS_DHM_RFC3526_MODP_4096_G mbedtls_dhm_rfc3526_modp_4096_g |
| #endif |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /** |
| * \brief DHM context structure |
| */ |
| typedef struct |
| { |
| size_t len; /*!< size(P) in chars */ |
| mbedtls_mpi P; /*!< prime modulus */ |
| mbedtls_mpi G; /*!< generator */ |
| mbedtls_mpi X; /*!< secret value */ |
| mbedtls_mpi GX; /*!< self = G^X mod P */ |
| mbedtls_mpi GY; /*!< peer = G^Y mod P */ |
| mbedtls_mpi K; /*!< key = GY^X mod P */ |
| mbedtls_mpi RP; /*!< cached R^2 mod P */ |
| mbedtls_mpi Vi; /*!< blinding value */ |
| mbedtls_mpi Vf; /*!< un-blinding value */ |
| mbedtls_mpi pX; /*!< previous X */ |
| } |
| mbedtls_dhm_context; |
| |
| /** |
| * \brief Initialize DHM context |
| * |
| * \param ctx DHM context to be initialized |
| */ |
| void mbedtls_dhm_init( mbedtls_dhm_context *ctx ); |
| |
| /** |
| * \brief Parse the ServerKeyExchange parameters |
| * |
| * \param ctx DHM context |
| * \param p &(start of input buffer), will be increased |
| * by the amount of data read. |
| * \param end end of buffer |
| * |
| * \return 0 if successful, or an MBEDTLS_ERR_DHM_XXX error code |
| */ |
| int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx, |
| unsigned char **p, |
| const unsigned char *end ); |
| |
| /** |
| * \brief Setup and write the ServerKeyExchange parameters |
| * |
| * \param ctx DHM context |
| * \param x_size private value size in bytes |
| * \param output destination buffer |
| * \param olen number of chars written |
| * \param f_rng RNG function |
| * \param p_rng RNG parameter |
| * |
| * \note The destination buffer must be large enough to hold |
| * the modulus, the generator, and the public key, each |
| * wrapped with a 2-byte length field. It is the responsibility |
| * of the caller to ensure that enough space is available. |
| * |
| * \note This function assumes that ctx->P and ctx->G |
| * have already been properly set (for example |
| * using mbedtls_mpi_read_string or mbedtls_mpi_read_binary). |
| * |
| * \return 0 if successful, or an MBEDTLS_ERR_DHM_XXX error code |
| */ |
| int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size, |
| unsigned char *output, size_t *olen, |
| int (*f_rng)(void *, unsigned char *, size_t), |
| void *p_rng ); |
| |
| /** |
| * \brief Import the peer's public value G^Y |
| * |
| * \param ctx DHM context |
| * \param input input buffer |
| * \param ilen size of buffer |
| * |
| * \return 0 if successful, or an MBEDTLS_ERR_DHM_XXX error code |
| */ |
| int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx, |
| const unsigned char *input, size_t ilen ); |
| |
| /** |
| * \brief Create own private value X and export G^X |
| * |
| * \param ctx DHM context |
| * \param x_size private value size in bytes |
| * \param output destination buffer |
| * \param olen size of the destination buffer; |
| * must be at least equal to the size of P, ctx->len |
| * \param f_rng RNG function |
| * \param p_rng RNG parameter |
| * |
| * \note The destination buffer will always be fully written |
| * so as to contain a big-endian presentation of G^X mod P. |
| * If it is larger than ctx->len, it will accordingly be |
| * padded with zero-bytes in the beginning. |
| * |
| * \return 0 if successful, or an MBEDTLS_ERR_DHM_XXX error code |
| */ |
| int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size, |
| unsigned char *output, size_t olen, |
| int (*f_rng)(void *, unsigned char *, size_t), |
| void *p_rng ); |
| |
| /** |
| * \brief Derive and export the shared secret (G^Y)^X mod P |
| * |
| * \param ctx DHM context |
| * \param output destination buffer |
| * \param output_size size of the destination buffer, must be at |
| * at least the size of ctx->len |
| * \param olen on exit, holds the actual number of bytes written |
| * \param f_rng RNG function, for blinding purposes |
| * \param p_rng RNG parameter |
| * |
| * \return 0 if successful, or an MBEDTLS_ERR_DHM_XXX error code |
| * |
| * \note If non-NULL, f_rng is used to blind the input as |
| * countermeasure against timing attacks. Blinding is |
| * automatically used if and only if our secret value X is |
| * re-used and costs nothing otherwise, so it is recommended |
| * to always pass a non-NULL f_rng argument. |
| */ |
| int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx, |
| unsigned char *output, size_t output_size, size_t *olen, |
| int (*f_rng)(void *, unsigned char *, size_t), |
| void *p_rng ); |
| |
| /** |
| * \brief Free and clear the components of a DHM key |
| * |
| * \param ctx DHM context to free and clear |
| */ |
| void mbedtls_dhm_free( mbedtls_dhm_context *ctx ); |
| |
| #if defined(MBEDTLS_ASN1_PARSE_C) |
| /** \ingroup x509_module */ |
| /** |
| * \brief Parse DHM parameters in PEM or DER format |
| * |
| * \param dhm DHM context to be initialized |
| * \param dhmin input buffer |
| * \param dhminlen size of the buffer |
| * (including the terminating null byte for PEM data) |
| * |
| * \return 0 if successful, or a specific DHM or PEM error code |
| */ |
| int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin, |
| size_t dhminlen ); |
| |
| #if defined(MBEDTLS_FS_IO) |
| /** \ingroup x509_module */ |
| /** |
| * \brief Load and parse DHM parameters |
| * |
| * \param dhm DHM context to be initialized |
| * \param path filename to read the DHM Parameters from |
| * |
| * \return 0 if successful, or a specific DHM or PEM error code |
| */ |
| int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path ); |
| #endif /* MBEDTLS_FS_IO */ |
| #endif /* MBEDTLS_ASN1_PARSE_C */ |
| |
| /** |
| * \brief Checkup routine |
| * |
| * \return 0 if successful, or 1 if the test failed |
| */ |
| int mbedtls_dhm_self_test( int verbose ); |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* dhm.h */ |