FreeBSD/contrib/ntp/ntpd/ntp_crypto.c
/*
 * crypto_iff - verify Bob's response to Alice's challenge
 *
 * Returns
 * XEVNT_OK	success
 * XEVNT_FSP	bad filestamp
 * XEVNT_ID	bad or missing group key
 * XEVNT_PUB	bad or missing public key
 */
verify Bob's response to Alice's challenge
Returns
XEVNT_OK     success
XEVNT_FSP    bad filestamp
XEVNT_ID     bad or missing group key
XEVNT_PUB    bad or missing public key
verify Bob ' s response to Alice ' s challenge Returns XEVNT_OK success XEVNT_FSP bad filestamp XEVNT_ID bad or missing group key XEVNT_PUB bad or missing public key
int
crypto_iff(
	struct exten *ep,	
	struct peer *peer	
	)
{
	DSA	*dsa;		
	BN_CTX	*bctx;		
	DSA_SIG	*sdsa;		
	BIGNUM	*bn, *bk;
	u_int	len;
	const u_char *ptr;
	int	temp;
	const BIGNUM *p, *g;
	const BIGNUM *r, *s;
	const BIGNUM *pub_key;
	if (peer->ident_pkey == NULL) {
		msyslog(LOG_NOTICE, "crypto_iff: scheme unavailable");
		return (XEVNT_ID);
	}
	if (ntohl(ep->fstamp) != peer->ident_pkey->fstamp) {
		msyslog(LOG_NOTICE, "crypto_iff: invalid filestamp %u",
		    ntohl(ep->fstamp));
		return (XEVNT_FSP);
	}
	if ((dsa = EVP_PKEY_get0_DSA(peer->ident_pkey->pkey)) == NULL) {
		msyslog(LOG_NOTICE, "crypto_iff: defective key");
		return (XEVNT_PUB);
	}
	if (peer->iffval == NULL) {
		msyslog(LOG_NOTICE, "crypto_iff: missing challenge");
		return (XEVNT_ID);
	}
	bctx = BN_CTX_new(); bk = BN_new(); bn = BN_new();
	len = ntohl(ep->vallen);
	ptr = (u_char *)ep->pkt;
	if ((sdsa = d2i_DSA_SIG(NULL, &ptr, len)) == NULL) {
		BN_free(bn); BN_free(bk); BN_CTX_free(bctx);
		msyslog(LOG_ERR, "crypto_iff: %s",
		    ERR_error_string(ERR_get_error(), NULL));
		return (XEVNT_ERR);
	}
	DSA_get0_key(dsa, &pub_key, NULL);
	DSA_get0_pqg(dsa, &p, NULL, &g);
	DSA_SIG_get0(sdsa, &r, &s);
	BN_mod_exp(bn, pub_key, peer->iffval, p, bctx);
	BN_mod_exp(bk, g, r, p, bctx);
	BN_mod_mul(bn, bn, bk, p, bctx);
	bighash(bn, bn);
	temp = BN_cmp(bn, s);
	BN_free(bn); BN_free(bk); BN_CTX_free(bctx);
	BN_free(peer->iffval);
	peer->iffval = NULL;
	DSA_SIG_free(sdsa);
	if (temp == 0)
		return (XEVNT_OK);
	msyslog(LOG_NOTICE, "crypto_iff: identity not verified");
	return (XEVNT_ID);
}
int crypto_iff ( struct exten * ep , struct peer * peer ) { DSA * dsa ; BN_CTX * bctx ; DSA_SIG * sdsa ; BIGNUM * bn , * bk ; u_int len ; const u_char * ptr ; int temp ; const BIGNUM * p , * g ; const BIGNUM * r , * s ; const BIGNUM * pub_key ; if ( peer -> ident_pkey == NULL ) { msyslog ( LOG_NOTICE , " " ) ; return ( XEVNT_ID ) ; } if ( ntohl ( ep -> fstamp ) != peer -> ident_pkey -> fstamp ) { msyslog ( LOG_NOTICE , " " , ntohl ( ep -> fstamp ) ) ; return ( XEVNT_FSP ) ; } if ( ( dsa = EVP_PKEY_get0_DSA ( peer -> ident_pkey -> pkey ) ) == NULL ) { msyslog ( LOG_NOTICE , " " ) ; return ( XEVNT_PUB ) ; } if ( peer -> iffval == NULL ) { msyslog ( LOG_NOTICE , " " ) ; return ( XEVNT_ID ) ; } bctx = BN_CTX_new ( ) ; bk = BN_new ( ) ; bn = BN_new ( ) ; len = ntohl ( ep -> vallen ) ; ptr = ( u_char * ) ep -> pkt ; if ( ( sdsa = d2i_DSA_SIG ( NULL , & ptr , len ) ) == NULL ) { BN_free ( bn ) ; BN_free ( bk ) ; BN_CTX_free ( bctx ) ; msyslog ( LOG_ERR , " " , ERR_error_string ( ERR_get_error ( ) , NULL ) ) ; return ( XEVNT_ERR ) ; } DSA_get0_key ( dsa , & pub_key , NULL ) ; DSA_get0_pqg ( dsa , & p , NULL , & g ) ; DSA_SIG_get0 ( sdsa , & r , & s ) ; BN_mod_exp ( bn , pub_key , peer -> iffval , p , bctx ) ; BN_mod_exp ( bk , g , r , p , bctx ) ; BN_mod_mul ( bn , bn , bk , p , bctx ) ; bighash ( bn , bn ) ; temp = BN_cmp ( bn , s ) ; BN_free ( bn ) ; BN_free ( bk ) ; BN_CTX_free ( bctx ) ; BN_free ( peer -> iffval ) ; peer -> iffval = NULL ; DSA_SIG_free ( sdsa ) ; if ( temp == 0 ) return ( XEVNT_OK ) ; msyslog ( LOG_NOTICE , " " ) ; return ( XEVNT_ID ) ; }
crypto_iff - verify Bob's response to Alice's challenge
 Returns
 XEVNT_OK     success
 XEVNT_FSP    bad filestamp
 XEVNT_ID     bad or missing group key
 XEVNT_PUB    bad or missing public key
crypto_iff - verify Bob ' s response to Alice ' s challenge Returns XEVNT_OK success XEVNT_FSP bad filestamp XEVNT_ID bad or missing group key XEVNT_PUB bad or missing public key
/* extension pointer */ /* peer structure pointer */ /* IFF parameters */ /* BIGNUM context */ /* DSA parameters */ /*
	 * If the IFF parameters are not valid or no challenge was sent,
	 * something awful happened or we are being tormented.
	 */ /*
	 * Extract the k + b r and g^k values from the response.
	 */ /*
	 * Compute g^(k + b r) g^(q - b)r mod p.
	 */ /*
	 * Verify the hash of the result matches hash(x).
	 */