/* Check DH's own parameters, DH Public key size is appropriate */#include <stdio.h> #include "cryptlib.h" #include <openssl/bn.h>/Custom OpenSSL Implement the structure of large number management and its functions # include <openssl/dh.h>/*-* Check that P was a safe prime and * if G is 2, 3 or 5, Check the It is a s Uitable Generator * where * for 2, p mod = = one * for 3, p mod = = 5 * For 5, p mod = = 3 or 7 * should hold. */int Dh_check (const DH *DH, int *ret)//Check that the DH parameter size is appropriate {int ok = 0; CTX is a context-sensitive structure that can be created with Bn_ctx_new and Bn_ctx_free to release it bn_ctx *ctx = NULL; Bn_ulong l; Bignum *t1 = null, *T2 = NULL; *ret = 0; CTX = Bn_ctx_new (); A Bn_ctx Instance CTX is created with bn_ctx_new () if (CTX = = NULL) goto err; Bn_ctx_start (CTX); Bn_ctx_start () to get a new stack frame first/per calling Bn_ctx_get (CTX), OpenSSL looks for an unused bignum t 1 = bn_ctx_get (CTX); if (t1 = = NULL) goto err; T2 = Bn_ctx_get (CTX); if (t2 = = NULL) goto err; if (dh->q) {if (bn_cmp (Dh->g, Bn_vaLue_one ()) <= 0)//dh->g less than Bn_value_one () *ret |= dh_not_suitable_generator; else if (bn_cmp (Dh->g, dh->p) >= 0)//dh->g is greater than dh->p *ret |= dh_not_suitable_generator; else {/* Check g^q = = 1 mod p */if (!bn_mod_exp (T1, Dh->g, Dh->q, Dh->p, CTX)) Goto err; if (!bn_is_one (T1))//Judge T1 is not 1 *ret |= dh_not_suitable_generator; if (!BN_IS_PRIME_EX (Dh->q, Bn_prime_checks, CTX, NULL))//q is a prime number *ret |= dh_check_q_not_prime; /* Check p = = 1 mod q i.e. Q divides p-1 */if (!bn_div (T1, T2, Dh->p, Dh->q, CTX)) Goto E Rr if (!bn_is_one (T2)) *ret |= Dh_check_invalid_q_value; if (dh->j && bn_cmp (dh->j, T1)) *ret |= Dh_check_invalid_j_value; } else if (Bn_is_word (Dh->g, dh_generator_2)) {//Determine dh->g is not a value dh_generator_2 L = Bn_mod_word (Dh->p, 24); Dh->p MoD 24, returns the remainder if (l! = 11)///Below is a small prime test based on Miller-rabin test *ret |= dh_not_suitable_generator; } #if 0 Else if (Bn_is_word (Dh->g, dh_generator_3)) {L = Bn_mod_word (dh->p, 12); if (l! = 5) *ret |= dh_not_suitable_generator; } #endif else if (Bn_is_word (Dh->g, dh_generator_5)) {L = Bn_mod_word (dh->p, 10); if ((l! = 3) && (l! = 7)) *ret |= dh_not_suitable_generator; } else *ret |= dh_unable_to_check_generator; if (!BN_IS_PRIME_EX (Dh->p, Bn_prime_checks, CTX, NULL)) *ret |= dh_check_p_not_prime; else if (!dh->q) {if (!BN_RSHIFT1 (t1, dh->p)) goto err; if (!BN_IS_PRIME_EX (T1, Bn_prime_checks, CTX, NULL)) *ret |= dh_check_p_not_safe_prime; } OK = 1; Err:if (CTX! = NULL) {bn_ctx_end (CTX); Bn_ctx_free (CTX); } return (OK);} Check if the public key size is appropriate int dh_check_pub_key (const DH *DH, const bignum *pub_Key, int *ret) {int ok = 0; Bignum *q = NULL; *ret = 0; Q = bn_new (); if (q = = NULL) goto err; Bn_set_word (q, 1); if (bn_cmp (Pub_key, Q) <= 0) *ret |= dh_check_pubkey_too_small; Bn_copy (q, dh->p); Bn_sub_word (q, 1); Q=q-1 if (bn_cmp (Pub_key, Q) >= 0)//bn_new () <pub_key <dh->p *ret |= dh_check_pubkey_to O_large; OK = 1; Err:if (q! = NULL) bn_free (q); return (OK);}
OpenSSL open source program DH algorithm parsing dh_check.c