Exemplo n.º 1
0
int32_t ZrtpDH::getPubKeyBytes(uint8_t *buf) const
{
    dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);

    if (pkType == DH2K || pkType == DH3K) {
        // get len of pub_key, prepend with zeros to DH size
        int size = getPubKeySize();
        int32_t prepend = getDhSize() - size;
        if (prepend > 0) {
            memset(buf, 0, prepend);
        }
        bnExtractBigBytes(&tmpCtx->pubKey, buf + prepend, 0, size);
        return size;
    }

    if (pkType == EC25 || pkType == EC38 || pkType == E414) {
        int32_t len = getPubKeySize() / 2;

        bnExtractBigBytes(tmpCtx->pubPoint.x, buf, 0, len);
        bnExtractBigBytes(tmpCtx->pubPoint.y, buf+len, 0, len);
        return len * 2;
    }
    if (pkType == E255) {
        int32_t len = getPubKeySize();
        bnExtractLittleBytes(tmpCtx->pubPoint.x, buf, 0, len);
        return len;
    }
    return 0;
}
Exemplo n.º 2
0
/* Initialize BSafe pubkey structure from a RSApub. */
static int
rpubk_init(B_KEY_OBJ rpubk, RSApub const *pub,
	PGPMemoryMgrRef	mgr)
{
	A_RSA_KEY kdata;
	PGPByte *buf;
	PGPSize bufsize;
	int err;

	bufsize = bnBytes(&pub->n) + bnBytes(&pub->e);
	buf = PGPNewSecureData( mgr, bufsize, 0 );
	kdata.modulus.data = buf;
	kdata.modulus.len = bnBytes(&pub->n);
	kdata.exponent.data = buf + kdata.modulus.len;
	kdata.exponent.len = bnBytes(&pub->e);
	bnExtractBigBytes (&pub->n, kdata.modulus.data, 0,
						kdata.modulus.len);
	bnExtractBigBytes (&pub->e, kdata.exponent.data, 0,
						kdata.exponent.len);
	err = B_SetKeyInfo (rpubk, KI_RSAPublic, (POINTER)&kdata);
	pgpAssert (err == 0);
	pgpClearMemory (buf, bufsize);
	PGPFreeData (buf);
	return err;
}
Exemplo n.º 3
0
int
bnPrint(FILE *f, char const *prefix, BigNum const *bn,
	char const *suffix)
{
	unsigned char temp[32];	/* How much to print on one line */
	unsigned len;
	size_t i;

	if (prefix && fputs(prefix, f) < 0)
		return EOF;

	len = (bnBits(bn) + 7)/ 8;

	if (!len) {
		if (putc('0', f) < 0)
			return EOF;
	} else {
		while (len > sizeof(temp)) {
			len -= sizeof(temp);
			bnExtractBigBytes(bn, temp, len, sizeof(temp));
			for (i = 0; i < sizeof(temp); i++)
				if (fprintf(f, "%02X", temp[i]) < 0)
					return EOF;
			if (putc('\\', f) < 0 || putc('\n', f) < 0)
				return EOF;
			if (prefix) {
				i = strlen(prefix);
				while (i--)
					if (putc(' ', f) < 0)
						return EOF;
			}
		}
		bnExtractBigBytes(bn, temp, 0, len);
		for (i = 0; i < len; i++)
			if (fprintf(f, "%02X", temp[i]) < 0)
				return EOF;
	}
	return suffix ?	fputs(suffix, f) : 0;
}
Exemplo n.º 4
0
int rsa_EXTRACTKEYS(RSA_CTX *ctx,unsigned char **N,unsigned char **d,
unsigned char **e){
/* we extract as big - endian */
/*
unsigned int a=bnBits(&ctx->e);
unsigned int b=a/8;
b+=1;
*/
*N=(unsigned char*)Lmalloc((ctx->bits/8)+1);
*d=(unsigned char*)Lmalloc((ctx->bits/8)+1);
*e=(unsigned char*)Lmalloc((ctx->bits/8)+1);
memset(*N,0,(ctx->bits/8)+1);
memset(*d,0,(ctx->bits/8)+1);
memset(*e,0,(ctx->bits/8)+1);

bnExtractBigBytes(&ctx->n,(void*)*N,0,ctx->bits/8);
bnExtractBigBytes(&ctx->d,(void*)*d,0,ctx->bits/8);
bnExtractBigBytes(&ctx->e,(void*)*e,0,ctx->bits/8);

N[(ctx->bits/8)+1]='\0';
d[(ctx->bits/8)+1]='\0';
e[(ctx->bits/8)+1]='\0';
return OK;
}
Exemplo n.º 5
0
/*
 * Move bytes between the given buffer and the given BigNum encoded in
 * base 256.  I.e. after either of these, the buffer will be equal to
 * (bn / 256^lsbyte) % 256^len.  The difference is which is altered to
 * match the other!
 */
	PGPError
PGPBigNumExtractBigEndianBytes(
	PGPBigNumRef	bn,
	PGPByte *			dest,
	PGPUInt32			lsbyte,
	PGPUInt32			len )
{
	PGPError	err	= kPGPError_NoErr;
	
	pgpValidateBigNum( bn );
	
	bnExtractBigBytes( &bn->bn, dest, lsbyte, len );
	
	return( err );
}
Exemplo n.º 6
0
static zrtp_status_t _prepare_dhpart1(zrtp_stream_t *stream)
{	
    zrtp_proto_crypto_t* cc = stream->protocol->cc;
	zrtp_packet_DHPart_t *dh1 = &stream->messages.dhpart;
	uint16_t dh_length = (uint16_t)stream->pubkeyscheme->pv_length;
	
	zrtp_memcpy(dh1->rs1ID, cc->rs1.id.buffer, ZRTP_RSID_SIZE);	
	zrtp_memcpy(dh1->rs2ID, cc->rs2.id.buffer, ZRTP_RSID_SIZE);		
	zrtp_memcpy(dh1->auxsID, cc->auxs.id.buffer, ZRTP_RSID_SIZE);
	zrtp_memcpy(dh1->pbxsID, cc->pbxs.id.buffer, ZRTP_RSID_SIZE);	
		
	bnExtractBigBytes(&stream->dh_cc.pv, dh1->pv, 0, dh_length);
	
	_zrtp_packet_fill_msg_hdr( stream,
							   ZRTP_DHPART1,
							   dh_length + ZRTP_DH_STATIC_SIZE + ZRTP_HMAC_SIZE,
							   &dh1->hdr);

	return zrtp_status_ok;
}
Exemplo n.º 7
0
/*---------------------------------------------------------------------------*/
static zrtp_status_t _derive_s0(zrtp_stream_t* stream, int is_initiator)
{
	static const zrtp_string32_t zrtp_kdf_label	= ZSTR_INIT_WITH_CONST_CSTRING(ZRTP_KDF_STR);
	static const zrtp_string32_t zrtp_sess_label = ZSTR_INIT_WITH_CONST_CSTRING(ZRTP_SESS_STR);
	static const zrtp_string32_t zrtp_multi_label = ZSTR_INIT_WITH_CONST_CSTRING(ZRTP_MULTI_STR);
	static const zrtp_string32_t zrtp_presh_label = ZSTR_INIT_WITH_CONST_CSTRING(ZRTP_PRESH_STR);
	
	zrtp_session_t *session = stream->session;
	zrtp_secrets_t* secrets  = &session->secrets;
	zrtp_proto_crypto_t* cc  = stream->protocol->cc;
	void* hash_ctx = NULL;
	char print_buff[256];

	switch (stream->mode)
	{
	/*
	 * S0 computing for FULL DH exchange	 
	 * S0 computing.  s0 is the master shared secret used for all
	 * cryptographic operations.  In particular, note the inclusion
	 * of "total_hash", a hash of all packets exchanged up to this
	 * point.  This belatedly detects any tampering with earlier
	 * packets, e.g. bid-down attacks.
	 *
	 * s0 = hash( 1 | DHResult | "ZRTP-HMAC-KDF" | ZIDi | ZIDr |
	 *                        total_hash | len(s1) | s1 | len(s2) | s2 | len(s3) | s3 )
	 * The constant 1 and all lengths are 32 bits big-endian values.
	 * The fields without length prefixes are fixed-witdh:
	 * - DHresult is fixed to the width of the DH prime.
	 * - The hash type string and ZIDs are fixed width.
	 * - total_hash is fixed by the hash negotiation.
	 * The constant 1 is per NIST SP 800-56A section 5.8.1, and is
	 * a counter which can be incremented to generate more than 256
	 * bits of key material.
	 * ========================================================================
	 */
	case ZRTP_STREAM_MODE_DH:
	{
		zrtp_proto_secret_t *C[3] = { 0, 0, 0};
		int i = 0;
		uint32_t comp_length = 0;
		zrtp_stringn_t *zidi = NULL, *zidr = NULL;
		struct BigNum dhresult;
#if (defined(ZRTP_USE_STACK_MINIM) && (ZRTP_USE_STACK_MINIM == 1))
		zrtp_uchar1024_t* buffer = zrtp_sys_alloc( sizeof(zrtp_uchar1024_t) );
		if (!buffer) {
			return zrtp_status_alloc_fail;
		}
#else
		zrtp_uchar1024_t holder;
		zrtp_uchar1024_t* buffer = &holder;
#endif

		ZRTP_LOG(3,(_ZTU_,"\tDERIVE S0 from DH exchange and RS secrets...\n"));
		ZRTP_LOG(3,(_ZTU_,"\t       my rs1ID:%s\n", hex2str(cc->rs1.id.buffer, cc->rs1.id.length, print_buff, sizeof(print_buff))));
		ZRTP_LOG(3,(_ZTU_,"\t      his rs1ID:%s\n", hex2str((const char*)stream->messages.peer_dhpart.rs1ID, ZRTP_RSID_SIZE, print_buff, sizeof(print_buff))));
		ZRTP_LOG(3,(_ZTU_,"\t his rs1ID comp:%s\n", hex2str(cc->rs1.peer_id.buffer, cc->rs1.peer_id.length, print_buff, sizeof(print_buff))));

		ZRTP_LOG(3,(_ZTU_,"\t       my rs2ID:%s\n", hex2str(cc->rs2.id.buffer, cc->rs2.id.length, print_buff, sizeof(print_buff))));
		ZRTP_LOG(3,(_ZTU_,"\t      his rs2ID:%s\n", hex2str((const char*)stream->messages.peer_dhpart.rs2ID, ZRTP_RSID_SIZE, print_buff, sizeof(print_buff))));
		ZRTP_LOG(3,(_ZTU_,"\t his rs2ID comp:%s\n", hex2str(cc->rs2.peer_id.buffer, cc->rs2.peer_id.length, print_buff, sizeof(print_buff))));

		ZRTP_LOG(3,(_ZTU_,"\t      my pbxsID:%s\n", hex2str(cc->pbxs.id.buffer, cc->pbxs.id.length, print_buff, sizeof(print_buff))));
		ZRTP_LOG(3,(_ZTU_,"\t     his pbxsID:%s\n", hex2str((const char*)stream->messages.peer_dhpart.pbxsID, ZRTP_RSID_SIZE, print_buff, sizeof(print_buff))));
		ZRTP_LOG(3,(_ZTU_,"\this pbxsID comp:%s\n", hex2str(cc->pbxs.peer_id.buffer, cc->pbxs.peer_id.length, print_buff, sizeof(print_buff))));

		hash_ctx = session->hash->hash_begin(session->hash);
		if (0 == hash_ctx) {
			ZRTP_LOG(1,(_ZTU_, "\tERROR! can't start hash calculation for S0 computing. ID=%u.\n", stream->id));
			return zrtp_status_fail;
		}

		/*
		 * NIST requires a 32-bit big-endian integer counter to be included
		 * in the hash each time the hash is computed, which we have set to
		 * the fixed value of 1, because we only compute the hash once.
		 */
		comp_length = zrtp_hton32(1L);
		session->hash->hash_update(session->hash, hash_ctx, (const int8_t*)&comp_length, 4);

		
		switch (stream->pubkeyscheme->base.id) {
			case ZRTP_PKTYPE_DH2048:
			case ZRTP_PKTYPE_DH3072:
			case ZRTP_PKTYPE_DH4096:
				comp_length = stream->pubkeyscheme->pv_length;
				ZRTP_LOG(3,(_ZTU_,"DH comp_length=%u\n", comp_length));
				break;
			case ZRTP_PKTYPE_EC256P:
			case ZRTP_PKTYPE_EC384P:
			case ZRTP_PKTYPE_EC521P:
				comp_length = stream->pubkeyscheme->pv_length/2;
				ZRTP_LOG(3,(_ZTU_,"ECDH comp_length=%u\n", comp_length));
				break;
			default:
				break;
		}
		
		bnBegin(&dhresult);
		stream->pubkeyscheme->compute(stream->pubkeyscheme,
									  &stream->dh_cc,
									  &dhresult,
									  &stream->dh_cc.peer_pv);
				
		bnExtractBigBytes(&dhresult, (uint8_t *)buffer, 0, comp_length);
		session->hash->hash_update(session->hash, hash_ctx, (const int8_t*)buffer, comp_length);
		bnEnd(&dhresult);

#if (defined(ZRTP_USE_STACK_MINIM) && (ZRTP_USE_STACK_MINIM == 1))
		zrtp_sys_free(buffer);
#endif
		
		/* Add "ZRTP-HMAC-KDF" to the S0 hash */		
		session->hash->hash_update( session->hash, hash_ctx,
									(const int8_t*)&zrtp_kdf_label.buffer,
									zrtp_kdf_label.length);

		/* Then Initiator's and Responder's ZIDs */
		if (stream->protocol->type == ZRTP_STATEMACHINE_INITIATOR) {
			zidi = ZSTR_GV(stream->session->zrtp->zid);
			zidr = ZSTR_GV(stream->session->peer_zid);
		} else {
			zidr = ZSTR_GV(stream->session->zrtp->zid);
			zidi = ZSTR_GV(stream->session->peer_zid);
		}
		
		session->hash->hash_update(session->hash, hash_ctx, (const int8_t*)&zidi->buffer, zidi->length);
		session->hash->hash_update(session->hash, hash_ctx, (const int8_t*)&zidr->buffer, zidr->length);
		session->hash->hash_update(session->hash, hash_ctx, (const int8_t*)&cc->mes_hash.buffer, cc->mes_hash.length);

		/* If everything is OK - RS1 should much */
		if (!zrtp_memcmp(cc->rs1.peer_id.buffer, stream->messages.peer_dhpart.rs1ID, ZRTP_RSID_SIZE))
		{
			C[0] = &cc->rs1;
			secrets->matches |= ZRTP_BIT_RS1;
		}
		/* If we have lost our RS1 - remote party should use backup (RS2) instead */
		else if (!zrtp_memcmp(cc->rs1.peer_id.buffer, stream->messages.peer_dhpart.rs2ID, ZRTP_RSID_SIZE))
		{
			C[0] = &cc->rs1;
			secrets->matches |= ZRTP_BIT_RS1;
			ZRTP_LOG(2,(_ZTU_,"\tINFO! We have lost our RS1 from previous broken exchange"
						" - remote party will use RS2 backup. ID=%u\n", stream->id));
		}
		/* If remote party lost it's secret - we will use backup */
		else if (!zrtp_memcmp(cc->rs2.peer_id.buffer, stream->messages.peer_dhpart.rs1ID, ZRTP_RSID_SIZE))
		{
			C[0] = &cc->rs2;
			cc->rs1 = cc->rs2;
			secrets->matches |= ZRTP_BIT_RS1;
			secrets->cached  |= ZRTP_BIT_RS1;
			ZRTP_LOG(2,(_ZTU_,"\tINFO! Remote party has lost it's RS1 - use RS2 backup. ID=%u\n", stream->id));
		}
		else
		{			
			secrets->matches &= ~ZRTP_BIT_RS1;

			zrtp_cache_set_verified(session->zrtp->cache, ZSTR_GV(session->peer_zid), 0);
			zrtp_cache_reset_secure_since(session->zrtp->cache, ZSTR_GV(session->peer_zid));

			ZRTP_LOG(2,(_ZTU_,"\tINFO! Our RS1 doesn't equal to other-side's one %s. ID=%u\n",
						cc->rs1.secret->_cachedflag ? " - drop verified!" : "", stream->id));
		}

		if (!zrtp_memcmp(cc->rs2.peer_id.buffer, stream->messages.peer_dhpart.rs2ID, ZRTP_RSID_SIZE)) {
			secrets->matches |= ZRTP_BIT_RS2;
			if (0 == C[0]) {
				C[0] = &cc->rs2;
			}
		}
		

		if (secrets->auxs &&
			(!zrtp_memcmp(stream->messages.peer_dhpart.auxsID, cc->auxs.peer_id.buffer, ZRTP_RSID_SIZE)) ) {
			C[1] =&cc->auxs;
	    	secrets->matches |= ZRTP_BIT_AUX;
		}

		if ( secrets->pbxs &&
			(!zrtp_memcmp(stream->messages.peer_dhpart.pbxsID, cc->pbxs.peer_id.buffer, ZRTP_RSID_SIZE)) ) {	
			C[2] = &cc->pbxs;
			secrets->matches |= ZRTP_BIT_PBX;
		}

		/* Finally hashing matched shared secrets */
		for (i=0; i<3; i++) {
			/*
			 * Some of the shared secrets s1 through s5 may have lengths of zero
			 * if they are null (not shared), and are each preceded by a 4-octet
			 * length field. For example, if s4 is null, len(s4) is 00 00 00 00,
			 * and s4 itself would be absent from the hash calculation, which
			 * means len(s5) would immediately follow len(s4).
			 */
			comp_length = C[i] ? zrtp_hton32(ZRTP_RS_SIZE) : 0;
			session->hash->hash_update(session->hash, hash_ctx, (const int8_t*)&comp_length, 4);
			if (C[i]) {
				session->hash->hash_update( session->hash,
											 hash_ctx,
											 (const int8_t*)C[i]->secret->value.buffer,
											 C[i]->secret->value.length );
				ZRTP_LOG(3,(_ZTU_,"\tUse S%d in calculations.\n", i+1));
			}
		}

		session->hash->hash_end(session->hash, hash_ctx, ZSTR_GV(cc->s0));
	} break; /* S0 for for DH and Preshared streams */

	/*
	 * Compute all possible combinations of preshared_key:
	 * hash(len(rs1) | rs1 | len(auxsecret) | auxsecret | len(pbxsecret) | pbxsecret)	 
	 * Find matched preshared_key and derive S0 from it:
	 * s0 = KDF(preshared_key, "ZRTP Stream Key", KDF_Context, negotiated hash length) 
	 *
	 * INFO: Take into account that RS1 and RS2 may be swapped.
	 * If no matched were found - generate DH commit.
	 * ========================================================================
	 */
	case ZRTP_STREAM_MODE_PRESHARED:
	{
		zrtp_status_t s				= zrtp_status_ok;
		zrtp_string32_t presh_key	= ZSTR_INIT_EMPTY(presh_key);		

		ZRTP_LOG(3,(_ZTU_,"\tDERIVE S0 for PRESHARED from cached secret. ID=%u\n", stream->id));

		/* Use the same hash as we used for Commitment */
		if (is_initiator)
		{
			s = _zrtp_compute_preshared_key( session,											 
											 ZSTR_GV(session->secrets.rs1->value),
											 (session->secrets.auxs->_cachedflag) ? ZSTR_GV(session->secrets.auxs->value) : NULL,
											 (session->secrets.pbxs->_cachedflag) ? ZSTR_GV(session->secrets.pbxs->value) : NULL,
											 ZSTR_GV(presh_key),
											 NULL);
			if (zrtp_status_ok != s) {
				return s;
			}
			
			secrets->matches |= ZRTP_BIT_RS1;
			if (session->secrets.auxs->_cachedflag) {				
				secrets->matches |= ZRTP_BIT_AUX;
			}
			if (session->secrets.pbxs->_cachedflag) {			
				secrets->matches |= ZRTP_BIT_PBX;
			}
		}
		/*
		 * Let's find appropriate hv key for Responder:
		 * <RS1, 0, 0>, <RS1, AUX, 0>, <RS1, 0, PBX>, <RS1, AUX, PBX>.
		 */
		else
		{
			int res=-1;
			char* peer_key_id		= (char*)stream->messages.peer_commit.hv+ZRTP_HV_NONCE_SIZE;
			zrtp_string8_t key_id	= ZSTR_INIT_EMPTY(key_id);
			
			do {
				/* RS1 MUST be available at this stage.*/
				s = _zrtp_compute_preshared_key( session,							 
												 ZSTR_GV(secrets->rs1->value),
												 NULL,
												 NULL,
												 ZSTR_GV(presh_key),
												 ZSTR_GV(key_id));
				if (zrtp_status_ok == s) {
					res = zrtp_memcmp(peer_key_id, key_id.buffer, ZRTP_HV_KEY_SIZE);
					if (0 == res) {
						secrets->matches |= ZRTP_BIT_RS1;
						break;
					}
				}				
				
				if (session->secrets.pbxs->_cachedflag)
				{
					s = _zrtp_compute_preshared_key( session,											 
													 ZSTR_GV(secrets->rs1->value),
													 NULL,
													 ZSTR_GV(secrets->pbxs->value),
													 ZSTR_GV(presh_key),
													 ZSTR_GV(key_id));
					if (zrtp_status_ok == s) {
						res = zrtp_memcmp(peer_key_id, key_id.buffer, ZRTP_HV_KEY_SIZE);
						if (0 == res) {
							secrets->matches |= ZRTP_BIT_PBX;
							break;
						}
					}
				}
				
				if (session->secrets.auxs->_cachedflag)
				{
					s = _zrtp_compute_preshared_key( session,													 
													 ZSTR_GV(secrets->rs1->value),
													 ZSTR_GV(secrets->auxs->value),
													 NULL,
													 ZSTR_GV(presh_key),
													 ZSTR_GV(key_id));
					if (zrtp_status_ok == s) {
						res = zrtp_memcmp(peer_key_id, key_id.buffer, ZRTP_HV_KEY_SIZE);
						if (0 == res) {
							secrets->matches |= ZRTP_BIT_AUX;
							break;
						}
					}
				}
				
				if ((session->secrets.pbxs->_cachedflag) && (session->secrets.auxs->_cachedflag))
				{
					s = _zrtp_compute_preshared_key( session,													 
													 ZSTR_GV(secrets->rs1->value),
													 ZSTR_GV(secrets->auxs->value),
													 ZSTR_GV(secrets->pbxs->value),
													 ZSTR_GV(presh_key),
													 ZSTR_GV(key_id));
					if (zrtp_status_ok == s) {
						res = zrtp_memcmp(peer_key_id, key_id.buffer, ZRTP_HV_KEY_SIZE);
						if (0 == res) {
							secrets->matches |= ZRTP_BIT_AUX;
							secrets->matches |= ZRTP_BIT_PBX;
							break;
						}
					}
				}
				
			} while (0);
			
			if (0 != res) {
				ZRTP_LOG(3,(_ZTU_,"\tINFO! Matched Key wasn't found - initate DH exchange.\n"));
				secrets->cached = 0;
				secrets->rs1->_cachedflag = 0;
				
				_zrtp_machine_start_initiating_secure(stream);
				return zrtp_status_ok;				
			}
		}
		
		ZRTP_LOG(3,(_ZTU_,"\tUse RS1, %s, %s in calculations.\n", 
					   (session->secrets.matches & ZRTP_BIT_AUX) ? "AUX" : "NULL",
					   (session->secrets.matches & ZRTP_BIT_PBX) ? "PBX" : "NULL"));		
		
		_zrtp_kdf( stream,
				   ZSTR_GV(presh_key),
				   ZSTR_GV(zrtp_presh_label),
				   ZSTR_GV(stream->protocol->cc->kdf_context),
				   session->hash->digest_length,
				   ZSTR_GV(cc->s0));
	} break;

		
	/*
	 * For FAST Multistream:
	 * s0n = KDF(ZRTPSess, "ZRTP Multistream Key", KDF_Context, negotiated hash length) 
	 * ========================================================================
	 */
	case ZRTP_STREAM_MODE_MULT:
	{
		ZRTP_LOG(3,(_ZTU_,"\tDERIVE S0 for MULTISTREAM from ZRTP Session key... ID=%u\n", stream->id));
		_zrtp_kdf( stream,
				   ZSTR_GV(session->zrtpsess),
				   ZSTR_GV(zrtp_multi_label),
				   ZSTR_GV(stream->protocol->cc->kdf_context),
				   session->hash->digest_length,
				   ZSTR_GV(cc->s0));
	} break;
		
	default: break;
	}
	
	
	/*
	 * Compute ZRTP session key for FULL streams only:
	 * ZRTPSess = KDF(s0, "ZRTP Session Key", KDF_Context, negotiated hash length)
	 */
	if (!ZRTP_IS_STREAM_MULT(stream)) {
		if (session->zrtpsess.length == 0) {
			_zrtp_kdf( stream,
					   ZSTR_GV(cc->s0),
					   ZSTR_GV(zrtp_sess_label),
					   ZSTR_GV(stream->protocol->cc->kdf_context),
					   session->hash->digest_length,
					   ZSTR_GV(session->zrtpsess));
		}
	}
	
	return zrtp_status_ok;
}
Exemplo n.º 8
0
int32_t ZrtpDH::computeSecretKey(uint8_t *pubKeyBytes, uint8_t *secret) {

    dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);

    int32_t length = getDhSize();

    BigNum sec;
    if (pkType == DH2K || pkType == DH3K) {
        BigNum pubKeyOther;
        bnBegin(&pubKeyOther);
        bnBegin(&sec);

        bnInsertBigBytes(&pubKeyOther, pubKeyBytes, 0, length);

        if (pkType == DH2K) {
            bnExpMod(&sec, &pubKeyOther, &tmpCtx->privKey, &bnP2048);
        }
        else if (pkType == DH3K) {
            bnExpMod(&sec, &pubKeyOther, &tmpCtx->privKey, &bnP3072);
        }
        else {
            return 0;
        }
        bnEnd(&pubKeyOther);
        bnExtractBigBytes(&sec, secret, 0, length);
        bnEnd(&sec);

        return length;
    }

    if (pkType == EC25 || pkType == EC38 || pkType == E414) {
        int32_t len = getPubKeySize() / 2;
        EcPoint pub;

        bnBegin(&sec);
        INIT_EC_POINT(&pub);
        bnSetQ(pub.z, 1);               // initialze Z to one, these are affine coords

        bnInsertBigBytes(pub.x, pubKeyBytes, 0, len);
        bnInsertBigBytes(pub.y, pubKeyBytes+len, 0, len);

        /* Generate agreement for responder: sec = pub * privKey */
        ecdhComputeAgreement(&tmpCtx->curve, &sec, &pub, &tmpCtx->privKey);
        bnExtractBigBytes(&sec, secret, 0, length);
        bnEnd(&sec);
        FREE_EC_POINT(&pub);

        return length;
    }
    if (pkType == E255) {
        int32_t len = getPubKeySize();
        EcPoint pub;

        bnBegin(&sec);
        INIT_EC_POINT(&pub);

        bnInsertLittleBytes(pub.x, pubKeyBytes, 0, len);

        /* Generate agreement for responder: sec = pub * privKey */
        ecdhComputeAgreement(&tmpCtx->curve, &sec, &pub, &tmpCtx->privKey);
        bnExtractLittleBytes(&sec, secret, 0, length);
        bnEnd(&sec);
        FREE_EC_POINT(&pub);

        return length;
    }
    return -1;
}
Exemplo n.º 9
0
/*
 * Performs an RSA decryption.  Returns a prefix of the unwrapped
 * data in the given buf.  Returns the length of the untruncated
 * data, which may exceed "len". Returns <0 on error.
 */
int
rsaPrivateDecrypt(PGPByte *outbuf, unsigned len, BigNum *bn,
	RSAsec const *sec)
{
	unsigned bytes = bnBytes(&sec->n);
	PGPByte *buf = NULL;
	B_ALGORITHM_OBJ bobj = NULL;
	B_KEY_OBJ rprivk = NULL;
	unsigned int bufoutlen;
	PGPMemoryMgrRef	mgr	= bn->mgr;
	int err;

	buf = PGPNewSecureData (mgr, bytes, 0);
	if (buf == NULL) {
		err = kPGPError_OutOfMemory;
		goto error;
	}
	bnExtractBigBytes (bn, buf, 0, bytes);

	/* Initialize BSafe private key structure */
	err = B_CreateAlgorithmObject (&bobj);
	CHKERR(err);
	err = B_SetAlgorithmInfo (bobj, AI_RSAPrivate, NULL);
	CHKERR(err);
	err = B_CreateKeyObject (&rprivk);
	CHKERR(err);
	err = rprivk_init(rprivk, sec, mgr);
	CHKERR(err);
	err = B_DecryptInit (bobj, rprivk, RSA_CHOOSER, (A_SURRENDER_CTX *)0);
	CHKERR(err);

	/* Do an RSA decryption to recover PKCS-1 padded key */
	err = B_DecryptUpdate (bobj, buf, &bufoutlen, bytes, buf, bytes,
						(B_ALGORITHM_OBJ)NULL, (A_SURRENDER_CTX *)NULL);
	CHKERR(err);
	err = B_DecryptFinal (bobj, buf+bufoutlen, &bufoutlen, bytes-bufoutlen,
						(B_ALGORITHM_OBJ)NULL, (A_SURRENDER_CTX *)NULL);
	CHKERR(err);

	B_DestroyKeyObject (&rprivk);
	rprivk = NULL;
	B_DestroyAlgorithmObject (&bobj);
	bobj = NULL;

	/* Return to bn format */
	bnSetQ (bn, 0);
	bnInsertBigBytes (bn, buf, 0, bytes);
	pgpClearMemory (buf, bytes);
	PGPFreeData (buf);
	buf = NULL;
	
	err = pgpPKCSUnpack(outbuf, len, bn, PKCS_PAD_ENCRYPTED, bytes);

error:
	if (buf) {
		pgpClearMemory (buf, bytes);
		PGPFreeData (buf);
	}
	if (rprivk)
		B_DestroyKeyObject (&rprivk);
	if (bobj)
		B_DestroyAlgorithmObject (&bobj);
	
	return err;
}
Exemplo n.º 10
0
/*
 * Encrypt a buffer holding a session key with an RSA public key
 */
int
rsaPublicEncrypt(BigNum *bn, PGPByte const *in, unsigned len,
	RSApub const *pub, PGPRandomContext const *rc)
{
	unsigned bytes = bnBytes(&pub->n);
	PGPByte *buf = NULL;
	B_ALGORITHM_OBJ bobj = NULL;
	B_KEY_OBJ rpubk = NULL;
	unsigned int bufoutlen;
	PGPMemoryMgrRef	mgr	= bn->mgr;
	int err = 0;

	pgpPKCSPack(bn, in, len, PKCS_PAD_ENCRYPTED, bytes, rc);
	buf = PGPNewSecureData (mgr, bytes, 0);
	if (buf == NULL) {
		err = kPGPError_OutOfMemory;
		goto error;
	}
	bnExtractBigBytes (bn, buf, 0, bytes);
	bnSetQ (bn, 0);

	/* Initialize BSafe public key structure */
	err = B_CreateAlgorithmObject (&bobj);
	CHKERR(err);
	err = B_SetAlgorithmInfo (bobj, AI_RSAPublic, NULL);
	CHKERR(err);
	err = B_CreateKeyObject (&rpubk);
	CHKERR(err);
	err = rpubk_init(rpubk, pub, mgr);
	CHKERR(err);
	err = B_EncryptInit (bobj, rpubk, RSA_CHOOSER, (A_SURRENDER_CTX *)0);
	CHKERR(err);

	/* Encrypt data */
	err = B_EncryptUpdate (bobj, buf, &bufoutlen, bytes, buf, bytes,
						(B_ALGORITHM_OBJ)NULL, (A_SURRENDER_CTX *)NULL);
	CHKERR(err);
	err = B_EncryptFinal (bobj, buf+bufoutlen, &bufoutlen, bytes-bufoutlen,
						(B_ALGORITHM_OBJ)NULL, (A_SURRENDER_CTX *)NULL);
	CHKERR(err);

	B_DestroyKeyObject (&rpubk);
	rpubk = NULL;
	B_DestroyAlgorithmObject (&bobj);
	bobj = NULL;

	/* Return to bn format */
	bnInsertBigBytes (bn, buf, 0, bytes);
	pgpClearMemory (buf, bytes);
	PGPFreeData (buf);
	buf = NULL;

error:
	if (buf) {
		pgpClearMemory (buf, bytes);
		PGPFreeData (buf);
	}
	if (rpubk)
		B_DestroyKeyObject (&rpubk);
	if (bobj)
		B_DestroyAlgorithmObject (&bobj);
	
	return err;
}
Exemplo n.º 11
0
/* Initialize BSafe privkey structure from a RSAsec. */
static int
rprivk_init(B_KEY_OBJ rprivk, RSAsec const *sec,
	PGPMemoryMgrRef	mgr)
{
	BigNum dmodp, dmodq, tmp;
	A_RSA_CRT_KEY kdata;
	PGPByte *buf;
	PGPSize bufsize;
	int err;

	/* Calculate d mod p-1 and d mod q-1 */
	bnBegin(&dmodp, mgr, TRUE);
	bnBegin(&dmodq, mgr, TRUE);
	bnBegin(&tmp, mgr, TRUE);
	bnCopy(&tmp, &sec->p);
	bnSubQ(&tmp, 1);
	bnMod(&dmodp, &sec->d, &tmp);
	bnCopy(&tmp, &sec->q);
	bnSubQ(&tmp, 1);
	bnMod(&dmodq, &sec->d, &tmp);

	bufsize = bnBytes(&sec->n) + bnBytes(&sec->q) + bnBytes(&sec->p)
			+ bnBytes(&dmodq) + bnBytes(&dmodp) + bnBytes(&sec->u);
	buf = PGPNewSecureData( mgr, bufsize, 0 );
	kdata.modulus.data = buf;
	kdata.modulus.len = bnBytes(&sec->n);
	kdata.prime[0].data = kdata.modulus.data + kdata.modulus.len;
	kdata.prime[0].len = bnBytes(&sec->q);
	kdata.prime[1].data = kdata.prime[0].data + kdata.prime[0].len;
	kdata.prime[1].len = bnBytes(&sec->p);
	kdata.primeExponent[0].data = kdata.prime[1].data
				+ kdata.prime[1].len;
	kdata.primeExponent[0].len = bnBytes(&dmodq);
	kdata.primeExponent[1].data = kdata.primeExponent[0].data
				+ kdata.primeExponent[0].len;
	kdata.primeExponent[1].len = bnBytes(&dmodp);
	kdata.coefficient.data = kdata.primeExponent[1].data
				+ kdata.primeExponent[1].len;
	kdata.coefficient.len = bnBytes(&sec->u);
	bnExtractBigBytes (&sec->n, kdata.modulus.data, 0,
						kdata.modulus.len);
	bnExtractBigBytes (&sec->q, kdata.prime[0].data, 0,
						kdata.prime[0].len);
	bnExtractBigBytes (&sec->p, kdata.prime[1].data, 0,
						kdata.prime[1].len);
	bnExtractBigBytes (&dmodq, kdata.primeExponent[0].data, 0,
						kdata.primeExponent[0].len);
	bnExtractBigBytes (&dmodp, kdata.primeExponent[1].data, 0,
						kdata.primeExponent[1].len);
	bnExtractBigBytes (&sec->u, kdata.coefficient.data, 0,
						kdata.coefficient.len);
	err = B_SetKeyInfo (rprivk, KI_RSA_CRT, (POINTER)&kdata);
	pgpAssert (err == 0);
	pgpClearMemory (buf, bufsize);
	PGPFreeData (buf);

	bnEnd(&dmodp);
	bnEnd(&dmodq);
	bnEnd(&tmp);
	return err;
}