FreeBSD/contrib/ntp/ntpd/ntp_crypto.c
/*
 * crypto_bob2 - construct Bob's response to Alice's challenge
 *
 * Returns
 * XEVNT_OK	success
 * XEVNT_ERR	protocol error
 * XEVNT_ID	bad or missing group key
 */
construct Bob's response to Alice's challenge
Returns
XEVNT_OK     success
XEVNT_ERR    protocol error
XEVNT_ID     bad or missing group key
construct Bob ' s response to Alice ' s challenge Returns XEVNT_OK success XEVNT_ERR protocol error XEVNT_ID bad or missing group key
static int
crypto_bob2(
	struct exten *ep,	
	struct value *vp	
	)
{
	RSA	*rsa;		
	DSA_SIG	*sdsa;		
	BN_CTX	*bctx;		
	EVP_MD_CTX *ctx;	
	tstamp_t tstamp;	
	BIGNUM	*r, *k, *g, *y;
	u_char	*ptr;
	u_int	len;
	int	s_len;
	const BIGNUM *n, *p, *e;
	if (gqkey_info == NULL) {
		msyslog(LOG_NOTICE, "crypto_bob2: scheme unavailable");
		return (XEVNT_ID);
	}
	rsa = EVP_PKEY_get0_RSA(gqkey_info->pkey);
	RSA_get0_key(rsa, &n, &p, &e);
	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_bob2: %s",
		    ERR_error_string(ERR_get_error(), NULL));
		return (XEVNT_ERR);
	}
	bctx = BN_CTX_new(); k = BN_new(); g = BN_new(); y = BN_new();
	sdsa = DSA_SIG_new();
	BN_rand(k, len * 8, -1, 1);		
	BN_mod(k, k, n, bctx);
	BN_mod_exp(y, p, r, n, bctx); 
	BN_mod_mul(y, k, y, n, bctx);	
	BN_mod_exp(g, k, e, n, bctx); 
	bighash(g, g);
	DSA_SIG_set0(sdsa, y, g);
	BN_CTX_free(bctx);
	BN_free(r); BN_free(k);
#ifdef DEBUG
	if (debug > 1)
		RSA_print_fp(stdout, rsa, 0);
#endif
	len = s_len = i2d_DSA_SIG(sdsa, NULL);
	if (s_len <= 0) {
		msyslog(LOG_ERR, "crypto_bob2: %s",
		    ERR_error_string(ERR_get_error(), NULL));
		DSA_SIG_free(sdsa);
		return (XEVNT_ERR);
	}
	memset(vp, 0, sizeof(struct value));
	tstamp = crypto_time();
	vp->tstamp = htonl(tstamp);
	vp->fstamp = htonl(gqkey_info->fstamp);
	vp->vallen = htonl(len);
	ptr = emalloc(len);
	vp->ptr = ptr;
	i2d_DSA_SIG(sdsa, &ptr);
	DSA_SIG_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_bob2 ( struct exten * ep , struct value * vp ) { RSA * rsa ; DSA_SIG * sdsa ; BN_CTX * bctx ; EVP_MD_CTX * ctx ; tstamp_t tstamp ; BIGNUM * r , * k , * g , * y ; u_char * ptr ; u_int len ; int s_len ; const BIGNUM * n , * p , * e ; if ( gqkey_info == NULL ) { msyslog ( LOG_NOTICE , " " ) ; return ( XEVNT_ID ) ; } rsa = EVP_PKEY_get0_RSA ( gqkey_info -> pkey ) ; RSA_get0_key ( rsa , & n , & p , & e ) ; 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 ( ) ; g = BN_new ( ) ; y = BN_new ( ) ; sdsa = DSA_SIG_new ( ) ; BN_rand ( k , len * 8 , -1 , 1 ) ; BN_mod ( k , k , n , bctx ) ; BN_mod_exp ( y , p , r , n , bctx ) ; BN_mod_mul ( y , k , y , n , bctx ) ; BN_mod_exp ( g , k , e , n , bctx ) ; bighash ( g , g ) ; DSA_SIG_set0 ( sdsa , y , g ) ; BN_CTX_free ( bctx ) ; BN_free ( r ) ; BN_free ( k ) ; #ifdef DEBUG if ( debug > 1 ) RSA_print_fp ( stdout , rsa , 0 ) ; #endif len = s_len = i2d_DSA_SIG ( sdsa , NULL ) ; if ( s_len <= 0 ) { msyslog ( LOG_ERR , " " , ERR_error_string ( ERR_get_error ( ) , NULL ) ) ; DSA_SIG_free ( sdsa ) ; return ( XEVNT_ERR ) ; } memset ( vp , 0 , sizeof ( struct value ) ) ; tstamp = crypto_time ( ) ; vp -> tstamp = htonl ( tstamp ) ; vp -> fstamp = htonl ( gqkey_info -> fstamp ) ; vp -> vallen = htonl ( len ) ; ptr = emalloc ( len ) ; vp -> ptr = ptr ; i2d_DSA_SIG ( sdsa , & ptr ) ; DSA_SIG_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_bob2 - construct Bob's response to Alice's challenge
 Returns
 XEVNT_OK     success
 XEVNT_ERR    protocol error
 XEVNT_ID     bad or missing group key
crypto_bob2 - construct Bob ' s response to Alice ' s challenge Returns XEVNT_OK success XEVNT_ERR protocol error XEVNT_ID bad or missing group key
/* extension pointer */ /* value pointer */ /* GQ parameters */ /* DSA parameters */ /* BIGNUM context */ /* signature context */ /* NTP timestamp */ /*
	 * If the GQ parameters are not valid, something awful
	 * happened or we are being tormented.
	 */ /*
	 * Extract r from the challenge.
	 */ /*
	 * Bob rolls random k (0 < k < n), computes y = k u^r mod n and
	 * x = k^b mod n, then sends (y, hash(x)) to Alice. 
	 */ /* k */ /* u^r mod n */ /* k u^r mod n */ /* k^b mod n */ /*
	 * Encode the values in ASN.1 and sign. The filestamp is from
	 * the local file.
	 */