Ejemplo n.º 1
0
/*----------------------------------------------------------------------------*/
int zrtp_randstr(zrtp_global_t* zrtp, unsigned char *buffer, uint32_t length)
{
	//TODO: replace bg_aes_xxx() with our own block cipher component.
	//TODO: Do the same with the hash functions.

    aes_encrypt_ctx	aes_ctx;
    MD_CTX			rand_ctx2;
    unsigned char	md[MD_DIGEST_LENGTH];
    unsigned char	ctr[AES_BLOCK_SIZE];
    unsigned char	rdata[AES_BLOCK_SIZE];
    uint32_t		generated = length;
	
	/*
	 * In few cases we need to gerate random value before initializing libzrtp engine.
	 * Following trick makes it possible.
	 */	
	if (!zrtp->rand_initialized) {
		if (zrtp_status_ok != zrtp_init_rng(zrtp)) {
			return -1;
		}
	}	

	zrtp_mutex_lock(zrtp->rng_protector);

    /*
     * Add entropy from system state
     * We will include whatever happens to be in the buffer, it can't hurt
     */
    if ( 0 > zrtp_entropy_add(zrtp, buffer, length) ) {		
		zrtp_mutex_unlock(zrtp->rng_protector);
        return -1;
    }

    /* Copy the zrtp->rand_ctx and finalize it into the md buffer */
    rand_ctx2 = zrtp->rand_ctx;
    MD_Final(&rand_ctx2, md);
    
    zrtp_mutex_unlock(zrtp->rng_protector);

    /* Key an AES context from this buffer */
    zrtp_bg_aes_encrypt_key256(md, &aes_ctx);

    /* Initialize counter, using excess from md if available */
    zrtp_memset (ctr, 0, sizeof(ctr));
    if (MD_DIGEST_LENGTH > (256/8)) {
		uint32_t ctrbytes = MD_DIGEST_LENGTH - (256/8);
		if (ctrbytes > AES_BLOCK_SIZE)
			ctrbytes = AES_BLOCK_SIZE;
		zrtp_memcpy(ctr + sizeof(ctr) - ctrbytes, md + (256/8), ctrbytes);
    }
	
    /* Encrypt counter, copy to destination buffer, increment counter */
    while (length)
    {
		unsigned char *ctrptr;
		uint32_t copied;
		zrtp_bg_aes_encrypt(ctr, rdata, &aes_ctx);
		copied = (sizeof(rdata) < length) ? sizeof(rdata) : length;
		zrtp_memcpy (buffer, rdata, copied);
		buffer += copied;
		length -= copied;
		
		/* Increment counter */
		ctrptr = ctr + sizeof(ctr) - 1;
		while (ctrptr >= ctr) {
			if ((*ctrptr-- += 1) != 0) {
				break;
			}
		}
    }

    /* Done!  Cleanup and exit */
    MD_Cleanup (&rand_ctx2);
    MD_Cleanup (md);
    MD_Cleanup (&aes_ctx);
    MD_Cleanup (ctr);
    MD_Cleanup (rdata);
	
    return generated;
}
Ejemplo n.º 2
0
zrtp_status_t zrtp_init(zrtp_config_t* config, zrtp_global_t** zrtp)
{
    zrtp_global_t* new_zrtp;
    zrtp_status_t s = zrtp_status_ok;
	
	ZRTP_LOG(3, (_ZTU_,"INITIALIZING LIBZRTP...\n"));
	
	/* Print out configuration setting */
	zrtp_print_env_settings(config);
	
	new_zrtp = zrtp_sys_alloc(sizeof(zrtp_global_t));
	if (!new_zrtp) {
		return zrtp_status_alloc_fail;
    }	
	zrtp_memset(new_zrtp, 0, sizeof(zrtp_global_t));
		
	/*
	 * Apply configuration according to the config
	 */		
	new_zrtp->lic_mode = config->lic_mode;	
	new_zrtp->is_mitm = config->is_mitm;
	ZSTR_SET_EMPTY(new_zrtp->def_cache_path);
	zrtp_zstrcpy(ZSTR_GV(new_zrtp->def_cache_path), ZSTR_GV(config->def_cache_path));
	zrtp_memcpy(&new_zrtp->cb, &config->cb, sizeof(zrtp_callback_t));
	new_zrtp->cache_auto_store = config->cache_auto_store;
        
	ZSTR_SET_EMPTY(new_zrtp->client_id);
	zrtp_memset(new_zrtp->client_id.buffer, ' ', sizeof(zrtp_client_id_t));
	zrtp_zstrncpyc( ZSTR_GV(new_zrtp->client_id),
					(const char*)config->client_id,
					sizeof(zrtp_client_id_t));
	
    /*
	 * General Initialization
	 */
	init_mlist(&new_zrtp->sessions_head);
	
    zrtp_mutex_init(&new_zrtp->sessions_protector);   
	
    init_mlist(&new_zrtp->hash_head);
    init_mlist(&new_zrtp->cipher_head);
    init_mlist(&new_zrtp->atl_head);
    init_mlist(&new_zrtp->pktype_head);
    init_mlist(&new_zrtp->sas_head);

    /* Init RNG context */	
	s = zrtp_init_rng(new_zrtp);
    if (zrtp_status_ok != s) {
		ZRTP_LOG(1, (_ZTU_,"ERROR! zrtp_init_rng() failed:%s.\n", zrtp_log_status2str(s)));
		return zrtp_status_rng_fail;
	}
   	
	/* Initialize SRTP engine */
	s =  zrtp_srtp_init(new_zrtp);
	if (zrtp_status_ok != s) {
		ZRTP_LOG(1, (_ZTU_,"ERROR! zrtp_srtp_init() failed:<%s>\n", zrtp_log_status2str(s)));
		return zrtp_status_fail;
    }    

	if (new_zrtp->cb.cache_cb.on_init)  {
		s = new_zrtp->cb.cache_cb.on_init(new_zrtp);
		if (zrtp_status_ok != s) {
			ZRTP_LOG(1, (_ZTU_,"ERROR! cache on_init() callback failed <%s>\n", zrtp_log_status2str(s)));
			zrtp_srtp_down(new_zrtp);
			return zrtp_status_fail;
		}
	}
	
	if (new_zrtp->cb.sched_cb.on_init)  {
		s = new_zrtp->cb.sched_cb.on_init(new_zrtp);
		if (zrtp_status_ok != s) {
			ZRTP_LOG(1, (_ZTU_,"ERROR! scheduler on_init() callback failed <%s>\n", zrtp_log_status2str(s)));
			zrtp_srtp_down(new_zrtp);
			return zrtp_status_fail;
		}
	}
	
	/* Load default crypto-components */
    zrtp_prepare_pkt(new_zrtp);
    zrtp_defaults_sas(new_zrtp);
    zrtp_defaults_pkt(new_zrtp);
    zrtp_defaults_atl(new_zrtp);
    zrtp_defaults_aes_cipher(new_zrtp);
    zrtp_defaults_hash(new_zrtp);

	*zrtp = new_zrtp;
	
	ZRTP_LOG(3, (_ZTU_,"INITIALIZING LIBZRTP - DONE\n"));
    return  s;
}