📄 random.c
字号:
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 * * QUESTION: Replace this with SHA, which as generally received better * reviews from the cryptographic community? *//* 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 */#if POOLWORDS % 16 != 0#error extract_entropy() assumes that POOLWORDS is a multiple of 16 words.#endif/* * 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. */static ssize_t extract_entropy(struct random_bucket *r, char * buf, size_t nbytes, int to_user){ ssize_t ret, i; __u32 tmp[HASH_BUFFER_SIZE + HASH_EXTRA_SIZE]; __u32 x; add_timer_randomness(r, &extract_timer_state, nbytes); /* Redundant, but just in case... */ if (r->entropy_count > POOLBITS) r->entropy_count = POOLBITS; ret = nbytes; if (r->entropy_count / 8 >= nbytes) r->entropy_count -= nbytes*8; else r->entropy_count = 0; if (r->entropy_count < WAIT_OUTPUT_BITS) wake_up_interruptible(&random_write_wait); while (nbytes) { /* Hash the pool to get the output */ tmp[0] = 0x67452301; tmp[1] = 0xefcdab89; tmp[2] = 0x98badcfe; tmp[3] = 0x10325476;#ifdef USE_SHA tmp[4] = 0xc3d2e1f0;#endif for (i = 0; i < POOLWORDS; i += 16) HASH_TRANSFORM(tmp, r->pool+i); /* * The following code does two separate things that happen * to both work two words at a time, so are convenient * to do together. * * First, this feeds the output back into the pool so * that the next call will return different results. * Any perturbation of the pool's state would do, even * changing one bit, but this mixes the pool nicely. * * Second, this folds the output in half to hide the data * fed back into the pool from the user and further mask * any patterns in the hash output. (The exact folding * pattern is not important; the one used here is quick.) */ for (i = 0; i < HASH_BUFFER_SIZE/2; i++) { x = tmp[i + (HASH_BUFFER_SIZE+1)/2]; add_entropy_words(r, tmp[i], x); tmp[i] ^= x; }#if HASH_BUFFER_SIZE & 1 /* There's a middle word to deal with */ x = tmp[HASH_BUFFER_SIZE/2]; add_entropy_words(r, x, (__u32)((unsigned long)buf)); x ^= (x >> 16); /* Fold it in half */ ((__u16 *)tmp)[HASH_BUFFER_SIZE-1] = (__u16)x;#endif /* Copy data to destination buffer */ i = MIN(nbytes, HASH_BUFFER_SIZE*sizeof(__u32)/2); if (to_user) { i -= copy_to_user(buf, (__u8 const *)tmp, i); if (!i) { ret = -EFAULT; break; } } else memcpy(buf, (__u8 const *)tmp, i); nbytes -= i; buf += i; add_timer_randomness(r, &extract_timer_state, nbytes); if (to_user && current->need_resched) { if (signal_pending(current)) { ret = -EINTR; break; } schedule(); } } /* Wipe data just returned from memory */ memset(tmp, 0, sizeof(tmp)); return ret;}/* * This function is the exported kernel interface. It returns some * number of good random numbers, suitable for seeding TCP sequence * numbers, etc. */void get_random_bytes(void *buf, int nbytes){ extract_entropy(&random_state, (char *) buf, nbytes, 0);}static ssize_trandom_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos){ struct wait_queue wait = { current, NULL }; ssize_t n, retval = 0, count = 0; if (nbytes == 0) return 0; add_wait_queue(&random_read_wait, &wait); while (nbytes > 0) { current->state = TASK_INTERRUPTIBLE; n = nbytes; if (n > random_state.entropy_count / 8) n = random_state.entropy_count / 8; if (n == 0) { if (file->f_flags & O_NONBLOCK) { retval = -EAGAIN; break; } if (signal_pending(current)) { retval = -ERESTARTSYS; break; } schedule(); continue; } n = extract_entropy(&random_state, buf, n, 1); if (n < 0) { retval = n; break; } count += n; buf += n; nbytes -= n; break; /* This break makes the device work */ /* like a named pipe */ } current->state = TASK_RUNNING; remove_wait_queue(&random_read_wait, &wait); /* * If we gave the user some bytes, update the access time. */ if (count != 0) { UPDATE_ATIME(file->f_dentry->d_inode); } return (count ? count : retval);}static ssize_trandom_read_unlimited(struct file * file, char * buf, size_t nbytes, loff_t *ppos){ return extract_entropy(&random_state, buf, nbytes, 1);}static unsigned intrandom_poll(struct file *file, poll_table * wait){ unsigned int mask; poll_wait(file, &random_read_wait, wait); poll_wait(file, &random_write_wait, wait); mask = 0; if (random_state.entropy_count >= WAIT_INPUT_BITS) mask |= POLLIN | POLLRDNORM; if (random_state.entropy_count < WAIT_OUTPUT_BITS) mask |= POLLOUT | POLLWRNORM; return mask;}static ssize_trandom_write(struct file * file, const char * buffer, size_t count, loff_t *ppos){ int ret = 0; size_t bytes; unsigned i; __u32 buf[16]; const char *p = buffer; size_t c = count; while (c > 0) { bytes = MIN(c, sizeof(buf)); bytes -= copy_from_user(&buf, p, bytes); if (!bytes) { ret = -EFAULT; break; } c -= bytes; p += bytes; i = (unsigned)((bytes-1) / (2 * sizeof(__u32))); do { add_entropy_words(&random_state, buf[2*i], buf[2*i+1]); } while (i--); } if (p == buffer) { return (ssize_t)ret; } else { file->f_dentry->d_inode->i_mtime = CURRENT_TIME; mark_inode_dirty(file->f_dentry->d_inode); return (ssize_t)(p - buffer); }}static intrandom_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg){ int *p, size, ent_count; int retval; switch (cmd) { case RNDGETENTCNT: ent_count = random_state.entropy_count; if (put_user(ent_count, (int *) arg)) return -EFAULT; return 0; case RNDADDTOENTCNT: if (!capable(CAP_SYS_ADMIN)) return -EPERM;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -