DH_KEY.C the analysis of the DH algorithm in OpenSSL open source program

Source: Internet
Author: User

/* Implements the default Dh_method provided by OpenSSL, enabling the generation of a DH public key based on key parameters, and generating a shared key based on the DH public key (one party) and the DH private key (the other) for key exchange */#include <stdio.h># Include "Cryptlib.h" #include <openssl/bn.h> #include <openssl/rand.h>//implement pseudo-random number generation, support user-defined random number generation # include <openssl/dh.h>static int Generate_key (DH *dh); static int Compute_key (unsigned char *key, const bignum *pub_key, DH * DH); static int dh_bn_mod_exp (const DH *DH, Bignum *r, const bignum *a, const bignum *p, const BI Gnum *m, Bn_ctx *ctx, Bn_mont_ctx *m_ctx); R=a^p% mstatic int dh_init (DH *dh), static int dh_finish (DH *dh), int dh_generate_key (DH *dh)//Generate Public private key {#ifdef OPENSSL _fips if (Fips_mode () &&! ( Dh->meth->flags & Dh_flag_fips_method) &&! (Dh->flags & Dh_flag_non_fips_allow))        {Dherr (Dh_f_dh_generate_key, Dh_r_non_fips_method);    return 0; } #endif return Dh->meth->generate_key (DH); Generates a public private key, stored in the Public private key attribute of the DH struct}//the function int dh_compute_key (unsigned ch) based on the other public key and the own DH key to generate the shared keyAr *key, const bignum *pub_key, DH *dh) {#ifdef openssl_fips if (Fips_mode () &&! ( Dh->meth->flags & Dh_flag_fips_method) &&! (Dh->flags & Dh_flag_non_fips_allow))        {Dherr (Dh_f_dh_compute_key, Dh_r_non_fips_method);    return 0;   } #endif return Dh->meth->compute_key (Key, Pub_key, DH);    The results are saved in key}int dh_compute_key_padded (unsigned char *key, const bignum *pub_key, DH *dh) {int RV, pad;    RV = Dh->meth->compute_key (key, Pub_key, DH);    if (RV <= 0) return RV;  Pad = bn_num_bytes (dh->p)-RV;        Returns the number of bytes of dh->p if (Pad > 0) {memmove (key + pad, key, RV);    memset (key, 0, pad); } return RV + pad;} Static Dh_method Dh_ossl = {"OpenSSL DH METHOD", Generate_key, Compute_key, Dh_bn_mod_exp, Dh_init, Dh_ Finish, 0, NULL, null};const dh_method *dh_openssl (void) {return &dh_ossl;} The static int Generate_key (DH *dh)//is called by Dh_generate_key, where the specific implementation of {int OK = 0;    int generate_new_key = 0;    unsigned l;  Bn_ctx *ctx;    New context structure Bn_mont_ctx *mont = NULL;    Bignum *pub_key = null, *priv_key = NULL;    CTX = Bn_ctx_new ();    if (CTX = = NULL) goto err;  if (Dh->priv_key = = NULL) {Priv_key = Bn_new ();        Gets the private key if (Priv_key = = NULL) goto err;    Generate_new_key = 1;    } Else Priv_key = dh->priv_key;  if (Dh->pub_key = = NULL) {Pub_key = Bn_new ();    Gets the public key, temporarily if (Pub_key = = NULL) goto err;    } Else Pub_key = dh->pub_key;                                      if (Dh->flags & dh_flag_cache_mont_p) {MONT = bn_mont_ctx_set_locked (&dh->method_mont_p,        CRYPTO_LOCK_DH, Dh->p, CTX);    if (!mont) goto err; if (Generate_new_key) {if (dh->q) {do {if (!bn_rand_range (Priv_key, dh->q))            ensure priv_key<dh->q goto err; } while(Bn_is_zero (priv_key) | |        Bn_is_one (Priv_key));             } else {/* secret exponent length */L = dh->length? Dh->length:bn_num_bits (Dh->p)-1;        if (!bn_rand (Priv_key, l, 0, 0)) goto err;        }} {Bignum LOCAL_PRK;        Bignum *PRK;            if ((Dh->flags & dh_flag_no_exp_consttime) = = 0) {bn_init (&AMP;LOCAL_PRK);            PRK = &local_prk;        Bn_with_flags (PRK, Priv_key, bn_flg_consttime);        } else PRK = Priv_key;    Really generate public key if (!dh->meth->bn_mod_exp (DH, Pub_key, Dh->g, PRK, Dh->p, CTX, Mont)) Goto err;   } Dh->pub_key = Pub_key;    The public private key is assigned to the DH structure dh->priv_key = Priv_key; OK = 1;    Err:if (ok! = 1) dherr (Dh_f_generate_key, err_r_bn_lib);    if (Pub_key! = null) && (Dh->pub_key = = null)) Bn_free (Pub_key); if (Priv_key! = null) && (Dh->priv_key = = null)) Bn_free (prIv_key);    Bn_ctx_free (CTX); return (OK);} Called by Dh_compute_key, here the concrete implementation of the static int compute_key (unsigned char *key, const bignum *pub_key, DH *dh) {Bn_ctx *ctx = NU    LL;    Bn_mont_ctx *mont = NULL;    Bignum *tmp;    int ret =-1;    int Check_result;        if (Bn_num_bits (dh->p) > Openssl_dh_max_modulus_bits) {dherr (Dh_f_compute_key, Dh_r_modulus_too_large);    Goto err;  } CTX = Bn_ctx_new ();    New context Structure if (CTX = = NULL) goto err;    Bn_ctx_start (CTX);    TMP = Bn_ctx_get (CTX);        if (Dh->priv_key = = NULL) {dherr (Dh_f_compute_key, Dh_r_no_private_value);    Goto err;                                      } if (Dh->flags & dh_flag_cache_mont_p) {MONT = bn_mont_ctx_set_locked (&dh->method_mont_p,        CRYPTO_LOCK_DH, Dh->p, CTX); if ((Dh->flags & dh_flag_no_exp_consttime) = = 0) {/* XXX */bn_set_flags (Dh->priv_key, BN        _flg_consttime); } if (!mont) gotoErr } if (! Dh_check_pub_key (DH, Pub_key, &check_result) | |        Check_result) {//Check public key rationality Dherr (Dh_f_compute_key, Dh_r_invalid_pubkey);    Goto err; } if (!dh->//tep=pub_key ^ Dh->priv_key% dh->p,tmp is key meth->bn_mod_exp (DH, tmp, Pub_key,        Dh->priv_key, Dh->p, CTX, Mont)) {Dherr (Dh_f_compute_key, err_r_bn_lib);    Goto err; } ret = Bn_bn2bin (TMP, key);        Convert to byte storage: big-endian, deposit key in Err:if (CTX! = NULL) {bn_ctx_end (CTX);    Bn_ctx_free (CTX); } return (ret);}                         static int dh_bn_mod_exp (const DH *DH, Bignum *r, const bignum *a, const bignum *p, Const Bignum *m, Bn_ctx *ctx, Bn_mont_ctx *m_ctx) {/* * If A is only one word long and constant time is F     Alse, use the faster * exponenentiation function. */if (a->top = = 1 && ((Dh->flags & dh_flag_no_exp_consttime)! = 0)) {Bn_ulong a = a->d[0]        ; Return BN_MOD_EXP_mont_word (R, A, p, M, CTX, M_ctx); } else return Bn_mod_exp_mont (R, a, p, M, CTX, m_ctx);}    static int dh_init (DH *dh)//initialization function {dh->flags |= dh_flag_cache_mont_p; return (1);}    static int dh_finish (DH *dh)//End Function {if (dh->method_mont_p) Bn_mont_ctx_free (dh->method_mont_p); return (1);}

OpenSSL open source program DH algorithm parsing dh_key.c

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.