dh.c revision cd7d5faf5bbb52336a6f85578a90b31a648ac3fa
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
#include "xmalloc.h"
#include "buffer.h"
#include "cipher.h"
#include "kex.h"
#include "dh.h"
#include "pathnames.h"
#include "log.h"
#include "misc.h"
static int
{
/* Ignore leading whitespace */
if (*arg == '\0')
return 0;
/* time */
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
/* The whole group is one bit larger */
goto fail;
goto fail;
fatal("parse_prime: BN_new failed");
fatal("parse_prime: BN_new failed");
goto failclean;
goto failclean;
goto failclean;
return (1);
BN_clear_free(dhg->g);
BN_clear_free(dhg->p);
fail:
return (0);
}
DH *
{
FILE *f;
char line[2048];
int linenum;
return (dh_new_group1());
}
linenum = 0;
linenum++;
continue;
BN_clear_free(dhg.g);
BN_clear_free(dhg.p);
continue;
bestcount = 0;
}
bestcount++;
}
rewind(f);
if (bestcount == 0) {
fclose(f);
return (NULL);
}
linenum = 0;
continue;
BN_clear_free(dhg.g);
BN_clear_free(dhg.p);
continue;
}
break;
}
fclose(f);
fatal("WARNING: line %d disappeared in %s, giving up",
}
/* diffie-hellman-group1-sha1 */
int
{
int i;
int n = BN_num_bits(dh_pub);
int bits_set = 0;
log("invalid public DH value: negativ");
return 0;
}
for (i = 0; i <= n; i++)
if (BN_is_bit_set(dh_pub, i))
bits_set++;
/* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */
return 1;
return 0;
}
void
{
fatal("dh_gen_key: dh->p == NULL");
fatal("dh_gen_key: group too small: %d (2*need %d)",
do {
fatal("dh_gen_key: BN_new failed");
/* generate a 2*need bits random private exponent */
fatal("dh_gen_key: BN_rand failed");
if (DH_generate_key(dh) == 0)
fatal("dh_gen_key: DH_generate_key() failed");
bits_set++;
debug("dh_gen_key: priv key bits set: %d/%d",
if (tries++ > 10)
fatal("dh_gen_key: too many bad keys: giving up");
}
DH *
{
fatal("dh_new_group_asc: DH_new");
fatal("BN_hex2bn p");
fatal("BN_hex2bn g");
return (dh);
}
/*
* This just returns the group, we still need to generate the exchange
* value.
*/
DH *
{
fatal("dh_new_group: DH_new");
return (dh);
}
DH *
dh_new_group1(void)
{
"FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
"29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
"EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
"E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
"EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
"FFFFFFFF" "FFFFFFFF";
}
/*
* Estimates the group order for a Diffie-Hellman group that has an
* attack complexity approximately the same as O(2**bits). Estimate
* with: O(exp(1.9223 * (ln q)^(1/3) (ln ln q)^(2/3)))
*/
int
dh_estimate(int bits)
{
if (bits < 64)
return (512); /* O(2**63) */
if (bits < 128)
return (1024); /* O(2**86) */
if (bits < 192)
return (2048); /* O(2**116) */
return (4096); /* O(2**156) */
}