⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 yarrow.c

📁 Vovida 社区开源的 SIP 协议源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (y->seeded)    {	if (num_sources) { *num_sources = 0; }	if (entropy_bits) { *entropy_bits = emax; }	THROW( YARROW_OK );    }    for (i = 0; i < y->num_sources; i++)    {	if (y->source[i].entropy[YARROW_SLOW_POOL] >= y->slow_thresh)	{	    num--;	}	else if (y->source[i].entropy[YARROW_SLOW_POOL] > entropy)	{	    source = i;	    entropy = y->source[i].entropy[YARROW_SLOW_POOL];	}    }    if (num_sources) { *num_sources = num; }    if (source_id) { *source_id = source; }    if (entropy_bits) { *entropy_bits = entropy; }    THROW( YARROW_NOT_SEEDED ); CATCH:    EXCEP_RET;}YARROW_DLLint Yarrow_Output( Yarrow_CTX* y, void* out, size_t size ){    EXCEP_DECL;    int locked = 0;    size_t left;    char* outp;    size_t use;    if (!y || !out) { THROW( YARROW_BAD_ARG ); }    TRY( Yarrow_detect_fork( y ) );    if (!y->seeded) { THROW( YARROW_NOT_SEEDED ); }    left = size;    outp = out;    TRY( LOCK() );    if (y->out_left > 0)    {	use = min(left, y->out_left);	mem_copy(outp, y->out + CIPHER_BLOCK_SIZE - y->out_left, use);	left -= use;	y->out_left -= use;	outp += use;    }    for ( ; 	  left >= CIPHER_BLOCK_SIZE;	  left -= CIPHER_BLOCK_SIZE, outp += CIPHER_BLOCK_SIZE)    {	TRY( Yarrow_Output_Block(y, outp) );    }    if (left > 0)    {	TRY( Yarrow_Output_Block(y, y->out) );	mem_copy(outp, y->out, left);	y->out_left = CIPHER_BLOCK_SIZE - left;    } CATCH:    if ( locked ) { TRY( UNLOCK() ); }      EXCEP_RET;}int Yarrow_Gate(Yarrow_CTX* y){    EXCEP_DECL;    byte new_K[CIPHER_KEY_SIZE];    if (!y) { THROW( YARROW_BAD_ARG ); }      TRACE( printf( "GATE[" ); );    /* K <- Next k bits of PRNG output */    TRY( Yarrow_Output(y, new_K, CIPHER_KEY_SIZE) );    mem_copy(y->K, new_K, CIPHER_KEY_SIZE);    /* need to resetup the key schedule as the key has changed */    CIPHER_Init(&y->cipher, y->K); CATCH:    TRACE( printf( "]," ); );    mem_zero(new_K, sizeof(new_K));    EXCEP_RET;}#if defined( YARROW_SAVE_STATE )static int Yarrow_Load_State( Yarrow_CTX *y ){    EXCEP_DECL;    Yarrow_STATE state;        if ( !y ) { THROW( YARROW_BAD_ARG ); }    if ( y->entropyfile )    {	TRY( STATE_Load(y->entropyfile, &state) );	TRACE( printf( "LOAD STATE," ); );#if defined( YARROW_DEBUG )	hex_print( stderr, "state.load", state.seed, sizeof(state.seed));#endif    	/* what to do here is not defined by the Yarrow paper */	/* this is a place holder until we get some clarification */    	HASH_Update( &y->pool[YARROW_FAST_POOL], 		     state.seed, sizeof(state.seed) );	Yarrow_Make_Seeded( y );	TRY( Yarrow_Reseed(y, YARROW_FAST_POOL) );    } CATCH:    mem_zero(state.seed, sizeof(state.seed));    EXCEP_RET;}static int Yarrow_Save_State( Yarrow_CTX *y ){    EXCEP_DECL;    Yarrow_STATE state;        if ( !y ) { THROW( YARROW_BAD_ARG ); }    if ( y->entropyfile && y->seeded )     {	TRACE( printf( "SAVE STATE[" ); );	TRY( Yarrow_Output( y, state.seed, sizeof(state.seed) ) );	TRY( STATE_Save(y->entropyfile, &state) );    }    y->saved = 1;# if defined(YARROW_DEBUG)    hex_print(stdout, "state.save", state.seed, sizeof(state.seed));# endif CATCH:    TRACE( printf( "]," ); );    mem_zero(state.seed, sizeof(state.seed));    EXCEP_RET;}#endifint Yarrow_Reseed(Yarrow_CTX* y, int pool){    EXCEP_DECL;    HASH_CTX* fast_pool = &y->pool[YARROW_FAST_POOL];    HASH_CTX* slow_pool = &y->pool[YARROW_SLOW_POOL];    byte digest[HASH_DIGEST_SIZE];    HASH_CTX hash;    byte v_0[HASH_DIGEST_SIZE];    byte v_i[HASH_DIGEST_SIZE];    uint32 big_endian_int32;    COUNTER i;    if (!y) { THROW( YARROW_BAD_ARG ); }    if( pool != YARROW_FAST_POOL && pool != YARROW_SLOW_POOL )    {	THROW( YARROW_BAD_ARG );    }      TRACE( printf( "%s RESEED,", 		   pool == YARROW_SLOW_POOL ? "SLOW" : "FAST" ); );    if (pool == YARROW_SLOW_POOL)    {	/* SLOW RESEED */	/* feed hash of slow pool into the fast pool */	HASH_Final(slow_pool, digest);	/*  Each pool contains the running hash of all inputs fed into it	 *  since it was last used to carry out a reseed -- this implies	 *  that the pool must be reinitialized after a reseed	 */	HASH_Init(slow_pool);    /* reinitialize slow pool */	HASH_Update(fast_pool, digest, sizeof(digest));	if (y->seeded == 0)	{	    Yarrow_Make_Seeded( y );	}    }    /* step 1. v_0 <- hash of all inputs into fast pool */    HASH_Final(fast_pool, v_0);    HASH_Init(fast_pool);    /* reinitialize fast pool */     /* v_i <- v_0 */    mem_copy( v_i, v_0, sizeof(v_0) );    /* step 2. v_i = h(v_{i-1}|v_0|i) for i = 1,..,Pt */    /* note: this code has to work for Pt = 0 also */    for ( i = 0; i < y->Pt[pool]; i++ )    {	HASH_Init(&hash);	HASH_Update(&hash, v_i, sizeof(v_i));	HASH_Update(&hash, v_0, sizeof(v_0));	big_endian_int32 = make_big_endian32(i >> 32); /* MS word */	HASH_Update(&hash, &big_endian_int32, sizeof(uint32));	big_endian_int32 = make_big_endian32(i & 0xFFFFFFFF); /* LS word */	HASH_Update(&hash, &big_endian_int32, sizeof(uint32));	HASH_Final(&hash, v_i);    }    /* step3. K = h'(h(v_Pt|K)) */    /* t = h(v_Pt|K) */    HASH_Init(&hash);    HASH_Update(&hash, v_i, sizeof(v_i));    HASH_Update(&hash, y->K, sizeof(y->K));    HASH_Final(&hash, v_i);#if defined(YARROW_DEBUG)    hex_print(stdout, "old K", y->K, sizeof(y->K));#endif    /* K <- h'(t) */    TRY( Yarrow_Stretch(v_i, HASH_DIGEST_SIZE, y->K, CIPHER_KEY_SIZE) );    /* need to resetup the key schedule as the key has changed */    CIPHER_Init(&y->cipher, y->K);#if defined(YARROW_DEBUG)    hex_print(stdout, "new K", y->K, sizeof(y->K));#endif    /* step 4. C <- E_k(0) */#if defined(YARROW_DEBUG)    hex_print(stdout, "old C", y->C, sizeof(y->C));#endif    CIPHER_Encrypt_Block(&y->cipher, zero_block, y->C);#if defined(YARROW_DEBUG)    hex_print(stdout, "new C", y->C, sizeof(y->C));#endif    /* discard part output from previous key */      y->out_left = 0;    /*   step 5. Reset all entropy estimate accumulators of the entropy     *   accumulator to zero     */    for (i = 0; i < y->num_sources; i++)    {	y->source[i].entropy[pool] = 0;	if (pool == YARROW_SLOW_POOL)	{    /*   if this is a slow reseed, reset the fast pool entropy     *   accumulator also     */	    y->source[i].entropy[YARROW_FAST_POOL] = 0;	    y->source[i].reached_slow_thresh = 0;	}    }    /*  step 7. If a seed file is in use, the next 2k bits of output     *  are written to the seed file     */#if defined( YARROW_SAVE_STATE )    if ( y->seeded && y->entropyfile )    {	TRY( Yarrow_Save_State( y ) );    }#endif CATCH:    /*   step 6. Wipe the memory of all intermediate values     *     */    mem_zero( digest, sizeof(digest) );    mem_zero( &hash, sizeof(hash) );    mem_zero( v_0, sizeof(v_0) );    mem_zero( v_i, sizeof(v_i) );    EXCEP_RET;}int Yarrow_Stretch(const byte* m, size_t size, byte* out, size_t out_size){    EXCEP_DECL;    const byte* s_i;    byte* outp;    int left, use;    HASH_CTX hash, save;    byte digest[HASH_DIGEST_SIZE];      if (m == NULL || size == 0 || out == NULL || out_size == 0)    {	THROW( YARROW_BAD_ARG );    }      /*      *   s_0 = m     *   s_1 = h(s_0 | ... | s_{i-1})     *     *   h'(m, k) = first k bits of (s_0 | s_1 | ...)     *     */    outp = out;    left = out_size;      use = min(out_size, size);    mem_copy(outp, m, use);    /* get k bits or as many as available */    s_i = (const byte*)m;            /* pointer to s0 = m */    outp += use;    left -= use;    HASH_Init(&hash);    for ( ;	  left > 0;	  left -= HASH_DIGEST_SIZE)    {	HASH_Update(&hash, s_i, use);    	/* have to save hash state to one side as HASH_final changes state */	mem_copy(&save, &hash, sizeof(hash));	HASH_Final(&hash, digest);	use = min(HASH_DIGEST_SIZE, left);	mem_copy(outp, digest, use);	/* put state back for next time */	mem_copy(&hash, &save, sizeof(hash));	s_i = outp;            /* retain pointer to s_i */	outp += use;    }   CATCH:    mem_zero(&hash, sizeof(hash));    mem_zero(digest, sizeof(digest));    EXCEP_RET;}static void block_increment(void* block, const int sz){    byte* b = block;    int i;      for (i = sz-1; (++b[i]) == 0 && i > 0; i--)    {	; /* nothing */    }}YARROW_DLLint Yarrow_Final(Yarrow_CTX* y){    EXCEP_DECL;    int locked = 0;    if (!y) { THROW( YARROW_BAD_ARG ); }    TRY( Yarrow_detect_fork(y) );    TRY( LOCK() );    locked = 1;#if defined( YARROW_SAVE_STATE )    if ( y->seeded && y->entropyfile )    {	TRY( Yarrow_Save_State( y ) );    }#endif CATCH:    if ( locked ) { TRY( UNLOCK() ); }    mem_zero( y, sizeof(Yarrow_CTX) );    EXCEP_RET;}YARROW_DLLconst char* Yarrow_Str_Error( int err ){    err = 1-err;    if ( err < 0 || err >= sizeof( yarrow_str_error ) / sizeof( char* ) )    {	err = 1-YARROW_FAIL;    }     return yarrow_str_error[ err ];}#if defined(YARROW_DEBUG)static void hex_print(FILE* f, const char* var, void* data, size_t size){    const char* conv = "0123456789abcdef";    size_t i;    char* p = (char*) data;    char c, d;    fprintf(f, var);    fprintf(f, " = ");    for (i = 0; i < size; i++)    {	c = conv[(p[i] >> 4) & 0xf];	d = conv[p[i] & 0xf];	fprintf(f, "%c%c", c, d);    }    fprintf(f, "\n");}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -