FreeBSD/contrib/ntp/ntpd/ntp_crypto.c
/*
 * crypto_bob3 - construct Bob's response to Alice's challenge
 *
 * Returns
 * XEVNT_OK	success
 * XEVNT_ERR	protocol error
 */
construct Bob's response to Alice's challenge
Returns
XEVNT_OK     success
XEVNT_ERR    protocol error
construct Bob ' s response to Alice ' s challenge Returns XEVNT_OK success XEVNT_ERR protocol error
static int
crypto_bob3(
	struct exten *ep,	
	struct value *vp	
	)
{
	DSA	*dsa;		
	DSA	*sdsa;		
	BN_CTX	*bctx;		
	EVP_MD_CTX *ctx;	
	tstamp_t tstamp;	
	BIGNUM	*r, *k, *u;
	u_char	*ptr;
	u_int	len;
	const BIGNUM *p, *q, *g;
	const BIGNUM *pub_key, *priv_key;
	BIGNUM *sp, *sq, *sg;
	if (mvkey_info == NULL) {
		msyslog(LOG_NOTICE, "crypto_bob3: scheme unavailable");
		return (XEVNT_ID);
	}
	dsa = EVP_PKEY_get0_DSA(mvkey_info->pkey);
	DSA_get0_pqg(dsa, &p, &q, &g);
	DSA_get0_key(dsa, &pub_key, &priv_key);
	len = exten_payload_size(ep);
	if (len == 0 || len > MAX_VALLEN)
		return (XEVNT_LEN);
	if ((r = BN_bin2bn((u_char *)ep->pkt, len, NULL)) == NULL) {
		msyslog(LOG_ERR, "crypto_bob3: %s",
		    ERR_error_string(ERR_get_error(), NULL));
		return (XEVNT_ERR);
	}
	bctx = BN_CTX_new(); k = BN_new(); u = BN_new();
	sdsa = DSA_new();
	sp = BN_new(); sq = BN_new(); sg = BN_new();
	while (1) {
		BN_rand(k, BN_num_bits(q), 0, 0);
		BN_mod(k, k, q, bctx);
		BN_gcd(u, k, q, bctx);
		if (BN_is_one(u))
			break;
	}
	BN_mod_exp(u, g, k, p, bctx); 
	BN_mod_mul(sp, u, r, p, bctx);
	BN_mod_exp(sq, priv_key, k, p, bctx); 
	BN_mod_exp(sg, pub_key, k, p, bctx); 
	DSA_set0_key(sdsa, BN_dup(pub_key), NULL);
	DSA_set0_pqg(sdsa, sp, sq, sg);
	BN_CTX_free(bctx); BN_free(k); BN_free(r); BN_free(u);
#ifdef DEBUG
	if (debug > 1)
		DSA_print_fp(stdout, sdsa, 0);
#endif
	memset(vp, 0, sizeof(struct value));
	tstamp = crypto_time();
	vp->tstamp = htonl(tstamp);
	vp->fstamp = htonl(mvkey_info->fstamp);
	len = i2d_DSAparams(sdsa, NULL);
	if (len == 0) {
		msyslog(LOG_ERR, "crypto_bob3: %s",
		    ERR_error_string(ERR_get_error(), NULL));
		DSA_free(sdsa);
		return (XEVNT_ERR);
	}
	vp->vallen = htonl(len);
	ptr = emalloc(len);
	vp->ptr = ptr;
	i2d_DSAparams(sdsa, &ptr);
	DSA_free(sdsa);
	if (tstamp == 0)
		return (XEVNT_OK);
	vp->sig = emalloc(sign_siglen);
	ctx = EVP_MD_CTX_new();
	EVP_SignInit(ctx, sign_digest);
	EVP_SignUpdate(ctx, (u_char *)&vp->tstamp, 12);
	EVP_SignUpdate(ctx, vp->ptr, len);
	if (EVP_SignFinal(ctx, vp->sig, &len, sign_pkey)) {
		INSIST(len <= sign_siglen);
		vp->siglen = htonl(len);
	}
	EVP_MD_CTX_free(ctx);
	return (XEVNT_OK);
}
static int crypto_bob3 ( struct exten * ep , struct value * vp ) { DSA * dsa ; DSA * sdsa ; BN_CTX * bctx ; EVP_MD_CTX * ctx ; tstamp_t tstamp ; BIGNUM * r , * k , * u ; u_char * ptr ; u_int len ; const BIGNUM * p , * q , * g ; const BIGNUM * pub_key , * priv_key ; BIGNUM * sp , * sq , * sg ; if ( mvkey_info == NULL ) { msyslog ( LOG_NOTICE , " " ) ; return ( XEVNT_ID ) ; } dsa = EVP_PKEY_get0_DSA ( mvkey_info -> pkey ) ; DSA_get0_pqg ( dsa , & p , & q , & g ) ; DSA_get0_key ( dsa , & pub_key , & priv_key ) ; len = exten_payload_size ( ep ) ; if ( len == 0 || len > MAX_VALLEN ) return ( XEVNT_LEN ) ; if ( ( r = BN_bin2bn ( ( u_char * ) ep -> pkt , len , NULL ) ) == NULL ) { msyslog ( LOG_ERR , " " , ERR_error_string ( ERR_get_error ( ) , NULL ) ) ; return ( XEVNT_ERR ) ; } bctx = BN_CTX_new ( ) ; k = BN_new ( ) ; u = BN_new ( ) ; sdsa = DSA_new ( ) ; sp = BN_new ( ) ; sq = BN_new ( ) ; sg = BN_new ( ) ; while ( 1 ) { BN_rand ( k , BN_num_bits ( q ) , 0 , 0 ) ; BN_mod ( k , k , q , bctx ) ; BN_gcd ( u , k , q , bctx ) ; if ( BN_is_one ( u ) ) break ; } BN_mod_exp ( u , g , k , p , bctx ) ; BN_mod_mul ( sp , u , r , p , bctx ) ; BN_mod_exp ( sq , priv_key , k , p , bctx ) ; BN_mod_exp ( sg , pub_key , k , p , bctx ) ; DSA_set0_key ( sdsa , BN_dup ( pub_key ) , NULL ) ; DSA_set0_pqg ( sdsa , sp , sq , sg ) ; BN_CTX_free ( bctx ) ; BN_free ( k ) ; BN_free ( r ) ; BN_free ( u ) ; #ifdef DEBUG if ( debug > 1 ) DSA_print_fp ( stdout , sdsa , 0 ) ; #endif memset ( vp , 0 , sizeof ( struct value ) ) ; tstamp = crypto_time ( ) ; vp -> tstamp = htonl ( tstamp ) ; vp -> fstamp = htonl ( mvkey_info -> fstamp ) ; len = i2d_DSAparams ( sdsa , NULL ) ; if ( len == 0 ) { msyslog ( LOG_ERR , " " , ERR_error_string ( ERR_get_error ( ) , NULL ) ) ; DSA_free ( sdsa ) ; return ( XEVNT_ERR ) ; } vp -> vallen = htonl ( len ) ; ptr = emalloc ( len ) ; vp -> ptr = ptr ; i2d_DSAparams ( sdsa , & ptr ) ; DSA_free ( sdsa ) ; if ( tstamp == 0 ) return ( XEVNT_OK ) ; vp -> sig = emalloc ( sign_siglen ) ; ctx = EVP_MD_CTX_new ( ) ; EVP_SignInit ( ctx , sign_digest ) ; EVP_SignUpdate ( ctx , ( u_char * ) & vp -> tstamp , 12 ) ; EVP_SignUpdate ( ctx , vp -> ptr , len ) ; if ( EVP_SignFinal ( ctx , vp -> sig , & len , sign_pkey ) ) { INSIST ( len <= sign_siglen ) ; vp -> siglen = htonl ( len ) ; } EVP_MD_CTX_free ( ctx ) ; return ( XEVNT_OK ) ; }
crypto_bob3 - construct Bob's response to Alice's challenge
 Returns
 XEVNT_OK     success
 XEVNT_ERR    protocol error
crypto_bob3 - construct Bob ' s response to Alice ' s challenge Returns XEVNT_OK success XEVNT_ERR protocol error
/* extension pointer */ /* value pointer */ /* MV parameters */ /* DSA signature context fake */ /* BIGNUM context */ /* signature context */ /* NTP timestamp */ /*
	 * If the MV parameters are not valid, something awful
	 * happened or we are being tormented.
	 */ /*
	 * Extract r from the challenge.
	 */ /*
	 * Bob rolls random k (0 < k < q), making sure it is not a
	 * factor of q. He then computes y = r A^k and sends (y, gbar^k,
	 * and ghat^k) to Alice.
	 */ /* A^k r */ /* gbar */ /* ghat */ /*
	 * Encode the values in ASN.1 and sign. The filestamp is from
	 * the local file.
	 */