📄 random.c
字号:
#define SHA_CODE_SIZE 0/* * SHA transform algorithm, taken from code written by Peter Gutmann, * and placed in the public domain. *//* The SHA f()-functions. */#define f1(x,y,z) ( z ^ (x & (y^z)) ) /* Rounds 0-19: x ? y : z */#define f2(x,y,z) (x ^ y ^ z) /* Rounds 20-39: XOR */#define f3(x,y,z) ( (x & y) + (z & (x ^ y)) ) /* Rounds 40-59: majority */#define f4(x,y,z) (x ^ y ^ z) /* Rounds 60-79: XOR *//* The SHA Mysterious Constants */#define K1 0x5A827999L /* Rounds 0-19: sqrt(2) * 2^30 */#define K2 0x6ED9EBA1L /* Rounds 20-39: sqrt(3) * 2^30 */#define K3 0x8F1BBCDCL /* Rounds 40-59: sqrt(5) * 2^30 */#define K4 0xCA62C1D6L /* Rounds 60-79: sqrt(10) * 2^30 */#define ROTL(n,X) ( ( ( X ) << n ) | ( ( X ) >> ( 32 - n ) ) )#define subRound(a, b, c, d, e, f, k, data) \ ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )static void SHATransform(__u32 digest[85], __u32 const data[16]){ __u32 A, B, C, D, E; /* Local vars */ __u32 TEMP; int i;#define W (digest + HASH_BUFFER_SIZE) /* Expanded data array */ /* * Do the preliminary expansion of 16 to 80 words. Doing it * out-of-line line this is faster than doing it in-line on * register-starved machines like the x86, and not really any * slower on real processors. */ memcpy(W, data, 16*sizeof(__u32)); for (i = 0; i < 64; i++) { TEMP = W[i] ^ W[i+2] ^ W[i+8] ^ W[i+13]; W[i+16] = ROTL(1, TEMP); } /* Set up first buffer and local data buffer */ A = digest[ 0 ]; B = digest[ 1 ]; C = digest[ 2 ]; D = digest[ 3 ]; E = digest[ 4 ]; /* Heavy mangling, in 4 sub-rounds of 20 iterations each. */#if SHA_CODE_SIZE == 0 /* * Approximately 50% of the speed of the largest version, but * takes up 1/16 the space. Saves about 6k on an i386 kernel. */ for (i = 0; i < 80; i++) { if (i < 40) { if (i < 20) TEMP = f1(B, C, D) + K1; else TEMP = f2(B, C, D) + K2; } else { if (i < 60) TEMP = f3(B, C, D) + K3; else TEMP = f4(B, C, D) + K4; } TEMP += ROTL(5, A) + E + W[i]; E = D; D = C; C = ROTL(30, B); B = A; A = TEMP; }#elif SHA_CODE_SIZE == 1 for (i = 0; i < 20; i++) { TEMP = f1(B, C, D) + K1 + ROTL(5, A) + E + W[i]; E = D; D = C; C = ROTL(30, B); B = A; A = TEMP; } for (; i < 40; i++) { TEMP = f2(B, C, D) + K2 + ROTL(5, A) + E + W[i]; E = D; D = C; C = ROTL(30, B); B = A; A = TEMP; } for (; i < 60; i++) { TEMP = f3(B, C, D) + K3 + ROTL(5, A) + E + W[i]; E = D; D = C; C = ROTL(30, B); B = A; A = TEMP; } for (; i < 80; i++) { TEMP = f4(B, C, D) + K4 + ROTL(5, A) + E + W[i]; E = D; D = C; C = ROTL(30, B); B = A; A = TEMP; }#elif SHA_CODE_SIZE == 2 for (i = 0; i < 20; i += 5) { subRound( A, B, C, D, E, f1, K1, W[ i ] ); subRound( E, A, B, C, D, f1, K1, W[ i+1 ] ); subRound( D, E, A, B, C, f1, K1, W[ i+2 ] ); subRound( C, D, E, A, B, f1, K1, W[ i+3 ] ); subRound( B, C, D, E, A, f1, K1, W[ i+4 ] ); } for (; i < 40; i += 5) { subRound( A, B, C, D, E, f2, K2, W[ i ] ); subRound( E, A, B, C, D, f2, K2, W[ i+1 ] ); subRound( D, E, A, B, C, f2, K2, W[ i+2 ] ); subRound( C, D, E, A, B, f2, K2, W[ i+3 ] ); subRound( B, C, D, E, A, f2, K2, W[ i+4 ] ); } for (; i < 60; i += 5) { subRound( A, B, C, D, E, f3, K3, W[ i ] ); subRound( E, A, B, C, D, f3, K3, W[ i+1 ] ); subRound( D, E, A, B, C, f3, K3, W[ i+2 ] ); subRound( C, D, E, A, B, f3, K3, W[ i+3 ] ); subRound( B, C, D, E, A, f3, K3, W[ i+4 ] ); } for (; i < 80; i += 5) { subRound( A, B, C, D, E, f4, K4, W[ i ] ); subRound( E, A, B, C, D, f4, K4, W[ i+1 ] ); subRound( D, E, A, B, C, f4, K4, W[ i+2 ] ); subRound( C, D, E, A, B, f4, K4, W[ i+3 ] ); subRound( B, C, D, E, A, f4, K4, W[ i+4 ] ); }#elif SHA_CODE_SIZE == 3 /* Really large version */ subRound( A, B, C, D, E, f1, K1, W[ 0 ] ); subRound( E, A, B, C, D, f1, K1, W[ 1 ] ); subRound( D, E, A, B, C, f1, K1, W[ 2 ] ); subRound( C, D, E, A, B, f1, K1, W[ 3 ] ); subRound( B, C, D, E, A, f1, K1, W[ 4 ] ); subRound( A, B, C, D, E, f1, K1, W[ 5 ] ); subRound( E, A, B, C, D, f1, K1, W[ 6 ] ); subRound( D, E, A, B, C, f1, K1, W[ 7 ] ); subRound( C, D, E, A, B, f1, K1, W[ 8 ] ); subRound( B, C, D, E, A, f1, K1, W[ 9 ] ); subRound( A, B, C, D, E, f1, K1, W[ 10 ] ); subRound( E, A, B, C, D, f1, K1, W[ 11 ] ); subRound( D, E, A, B, C, f1, K1, W[ 12 ] ); subRound( C, D, E, A, B, f1, K1, W[ 13 ] ); subRound( B, C, D, E, A, f1, K1, W[ 14 ] ); subRound( A, B, C, D, E, f1, K1, W[ 15 ] ); subRound( E, A, B, C, D, f1, K1, W[ 16 ] ); subRound( D, E, A, B, C, f1, K1, W[ 17 ] ); subRound( C, D, E, A, B, f1, K1, W[ 18 ] ); subRound( B, C, D, E, A, f1, K1, W[ 19 ] ); subRound( A, B, C, D, E, f2, K2, W[ 20 ] ); subRound( E, A, B, C, D, f2, K2, W[ 21 ] ); subRound( D, E, A, B, C, f2, K2, W[ 22 ] ); subRound( C, D, E, A, B, f2, K2, W[ 23 ] ); subRound( B, C, D, E, A, f2, K2, W[ 24 ] ); subRound( A, B, C, D, E, f2, K2, W[ 25 ] ); subRound( E, A, B, C, D, f2, K2, W[ 26 ] ); subRound( D, E, A, B, C, f2, K2, W[ 27 ] ); subRound( C, D, E, A, B, f2, K2, W[ 28 ] ); subRound( B, C, D, E, A, f2, K2, W[ 29 ] ); subRound( A, B, C, D, E, f2, K2, W[ 30 ] ); subRound( E, A, B, C, D, f2, K2, W[ 31 ] ); subRound( D, E, A, B, C, f2, K2, W[ 32 ] ); subRound( C, D, E, A, B, f2, K2, W[ 33 ] ); subRound( B, C, D, E, A, f2, K2, W[ 34 ] ); subRound( A, B, C, D, E, f2, K2, W[ 35 ] ); subRound( E, A, B, C, D, f2, K2, W[ 36 ] ); subRound( D, E, A, B, C, f2, K2, W[ 37 ] ); subRound( C, D, E, A, B, f2, K2, W[ 38 ] ); subRound( B, C, D, E, A, f2, K2, W[ 39 ] ); subRound( A, B, C, D, E, f3, K3, W[ 40 ] ); subRound( E, A, B, C, D, f3, K3, W[ 41 ] ); subRound( D, E, A, B, C, f3, K3, W[ 42 ] ); subRound( C, D, E, A, B, f3, K3, W[ 43 ] ); subRound( B, C, D, E, A, f3, K3, W[ 44 ] ); subRound( A, B, C, D, E, f3, K3, W[ 45 ] ); subRound( E, A, B, C, D, f3, K3, W[ 46 ] ); subRound( D, E, A, B, C, f3, K3, W[ 47 ] ); subRound( C, D, E, A, B, f3, K3, W[ 48 ] ); subRound( B, C, D, E, A, f3, K3, W[ 49 ] ); subRound( A, B, C, D, E, f3, K3, W[ 50 ] ); subRound( E, A, B, C, D, f3, K3, W[ 51 ] ); subRound( D, E, A, B, C, f3, K3, W[ 52 ] ); subRound( C, D, E, A, B, f3, K3, W[ 53 ] ); subRound( B, C, D, E, A, f3, K3, W[ 54 ] ); subRound( A, B, C, D, E, f3, K3, W[ 55 ] ); subRound( E, A, B, C, D, f3, K3, W[ 56 ] ); subRound( D, E, A, B, C, f3, K3, W[ 57 ] ); subRound( C, D, E, A, B, f3, K3, W[ 58 ] ); subRound( B, C, D, E, A, f3, K3, W[ 59 ] ); subRound( A, B, C, D, E, f4, K4, W[ 60 ] ); subRound( E, A, B, C, D, f4, K4, W[ 61 ] ); subRound( D, E, A, B, C, f4, K4, W[ 62 ] ); subRound( C, D, E, A, B, f4, K4, W[ 63 ] ); subRound( B, C, D, E, A, f4, K4, W[ 64 ] ); subRound( A, B, C, D, E, f4, K4, W[ 65 ] ); subRound( E, A, B, C, D, f4, K4, W[ 66 ] ); subRound( D, E, A, B, C, f4, K4, W[ 67 ] ); subRound( C, D, E, A, B, f4, K4, W[ 68 ] ); subRound( B, C, D, E, A, f4, K4, W[ 69 ] ); subRound( A, B, C, D, E, f4, K4, W[ 70 ] ); subRound( E, A, B, C, D, f4, K4, W[ 71 ] ); subRound( D, E, A, B, C, f4, K4, W[ 72 ] ); subRound( C, D, E, A, B, f4, K4, W[ 73 ] ); subRound( B, C, D, E, A, f4, K4, W[ 74 ] ); subRound( A, B, C, D, E, f4, K4, W[ 75 ] ); subRound( E, A, B, C, D, f4, K4, W[ 76 ] ); subRound( D, E, A, B, C, f4, K4, W[ 77 ] ); subRound( C, D, E, A, B, f4, K4, W[ 78 ] ); subRound( B, C, D, E, A, f4, K4, W[ 79 ] );#else#error Illegal SHA_CODE_SIZE#endif /* Build message digest */ digest[ 0 ] += A; digest[ 1 ] += B; digest[ 2 ] += C; digest[ 3 ] += D; digest[ 4 ] += E; /* W is wiped by the caller */#undef W}#undef ROTL#undef f1#undef f2#undef f3#undef f4#undef K1 #undef K2#undef K3 #undef K4 #undef subRound #else /* !USE_SHA - Use MD5 */#define HASH_BUFFER_SIZE 4#define HASH_EXTRA_SIZE 0#define HASH_TRANSFORM MD5Transform /* * MD5 transform algorithm, taken from code written by Colin Plumb, * and put into the public domain *//* The four core functions - F1 is optimized somewhat *//* #define F1(x, y, z) (x & y | ~x & z) */#define F1(x, y, z) (z ^ (x & (y ^ z)))#define F2(x, y, z) F1(z, x, y)#define F3(x, y, z) (x ^ y ^ z)#define F4(x, y, z) (y ^ (x | ~z))/* This is the central step in the MD5 algorithm. */#define MD5STEP(f, w, x, y, z, data, s) \ ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )/* * The core of the MD5 algorithm, this alters an existing MD5 hash to * reflect the addition of 16 longwords of new data. MD5Update blocks * the data and converts bytes into longwords for this routine. */static void MD5Transform(__u32 buf[HASH_BUFFER_SIZE], __u32 const in[16]){ __u32 a, b, c, d; a = buf[0]; b = buf[1]; c = buf[2]; d = buf[3]; MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7); MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12); MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17); MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22); MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7); MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12); MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17); MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22); MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7); MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12); MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17); MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22); MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7); MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12); MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17); MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22); MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5); MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9); MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14); MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20); MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5); MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9); MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14); MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20); MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5); MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9); MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14); MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20); MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5); MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9); MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14); MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20); MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4); MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11); MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16); MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23); MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4); MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11); MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16); MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23); MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4); MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11); MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16); MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23); MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4); MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11); MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16); MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23); MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6); MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10); MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15); MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21); MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6); MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10); MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15); MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21); MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6); MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10); MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15); MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21); MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6); MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10); MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15); MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21); buf[0] += a; buf[1] += b; buf[2] += c; buf[3] += d;}#undef F1#undef F2#undef F3#undef F4#undef MD5STEP#endif /* !USE_SHA *//********************************************************************* * * Entropy extraction routines * *********************************************************************/#define EXTRACT_ENTROPY_USER 1#define EXTRACT_ENTROPY_SECONDARY 2#define TMP_BUF_SIZE (HASH_BUFFER_SIZE + HASH_EXTRA_SIZE)#define SEC_XFER_SIZE (TMP_BUF_SIZE*4)static ssize_t extract_entropy(struct entropy_store *r, void * buf, size_t nbytes, int flags);/* * This utility inline function is responsible for transfering entropy * from the primary pool to the secondary extraction pool. We pull * randomness under two conditions; one is if there isn't enough entropy * in the secondary pool. The other is after we have extract 1024 bytes, * at which point we do a "catastrophic reseeding". */static inline void xfer_secondary_pool(struct entropy_store *r, size_t nbytes){ __u32 tmp[TMP_BUF_SIZE]; if (r->entropy_count < nbytes*8) { extract_entropy(random_state, tmp, sizeof(tmp), 0); add_entropy_words(r, tmp, TMP_BUF_SIZE); credit_entropy_store(r, TMP_BUF_SIZE*8); } if (r->extract_count > 1024) { extract_entropy(random_state, tmp, sizeof(tmp), 0); add_entropy_words(r, tmp, TMP_BUF_SIZE); r->extract_count = 0; }}/* * This function extracts randomness from the "entropy pool", and * returns it in a buffer. This function computes how many remaining * bits of entropy are left in the pool, but it does not restrict the * number of bytes that are actually obtained. If the EXTRACT_ENTROPY_USER * flag is given, then the buf pointer is assumed to be in user space. * If the EXTRACT_ENTROPY_SECONDARY flag is given, then this function will * * Note: extract_entropy() assumes that POOLWORDS is a multiple of 16 words. */static ssize_t extract_entropy(struct entropy_store *r, void * buf, size_t nbytes, int flags){ ssize_t ret, i; __u32 tmp[TMP_BUF_SIZE]; __u32 x; add_timer_randomness(&extract_timer_state, nbytes); /* Redundant, but just in case... */ if (r->entropy_count > r->poolinfo.poolwords) r->entropy_count = r->poolinfo.poolwords; if (flags & EXTRACT_ENTROPY_SECONDARY) xfer_secondary_pool(r, nbytes); if (r->entropy_count / 8 >= nbytes) r->entropy_count -= nbytes*8; else r->entropy_count = 0; if (r->entropy_count < random_write_wakeup_thresh)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -