static int frandom_open(struct inode *inode, struct file *filp) { struct frandom_state *state; int num = iminor(inode); /* This should never happen, now when the minors are regsitered * explicitly */ if ((num != frandom_minor) && (num != erandom_minor)) return -ENODEV; state = kmalloc(sizeof(struct frandom_state), GFP_KERNEL); if (!state) return -ENOMEM; state->buf = kmalloc(frandom_bufsize, GFP_KERNEL); if (!state->buf) { kfree(state); return -ENOMEM; } sema_init(&state->sem, 1); /* Init semaphore as a mutex */ if (num == frandom_minor) init_rand_state(state, EXTERNAL_SEED); else init_rand_state(state, INTERNAL_SEED); filp->private_data = state; return 0; /* Success */ }
static int frandom_open(struct inode *inode, struct file *filp) { struct frandom_state *state; int num = iminor(inode); if ((num != frandom_minor) && (num != erandom_minor)) return -ENODEV; state = kmalloc(sizeof(struct frandom_state), GFP_KERNEL); if (!state) return -ENOMEM; state->buf = kmalloc(frandom_bufsize, GFP_KERNEL); if (!state->buf) { kfree(state); return -ENOMEM; } sema_init(&state->sem, 1); if (num == frandom_minor) init_rand_state(state, EXTERNAL_SEED); else init_rand_state(state, INTERNAL_SEED); filp->private_data = state; return 0; }
void erandom_get_random_bytes(char *buf, size_t count) { struct frandom_state *state = erandom_state; int k; unsigned int i; unsigned int j; u8 *S; if (down_interruptible(&state->sem)) { get_random_bytes(buf, count); return; } if (!erandom_seeded) { erandom_seeded = 1; init_rand_state(state, EXTERNAL_SEED); printk(KERN_INFO "frandom: Seeded global generator now (used by erandom)\n"); } i = state->i; j = state->j; S = state->S; for (k=0; k<count; k++) { i = (i + 1) & 0xff; j = (j + S[i]) & 0xff; swap_byte(&S[i], &S[j]); *buf++ = S[(S[i] + S[j]) & 0xff]; } state->i = i; state->j = j; up(&state->sem); }
void erandom_get_random_bytes(char *buf, size_t count) { struct frandom_state *state = erandom_state; int k; unsigned int i; unsigned int j; u8 *S; /* If we fail to get the semaphore, we revert to external random data. Since semaphore blocking is expected to be very rare, and interrupts during these rare and very short periods of time even less frequent, we take the better-safe-than-sorry approach, and fill the buffer some expensive random data, in case the caller wasn't aware of this possibility, and expects random data anyhow. */ if (down_interruptible(&state->sem)) { get_random_bytes(buf, count); return; } /* We seed erandom as late as possible, hoping that the kernel's main RNG is already restored in the boot sequence (not critical, but better. */ if (!erandom_seeded) { erandom_seeded = 1; init_rand_state(state, EXTERNAL_SEED); #ifdef CONFIG_DEBUG_PRINTK printk(KERN_INFO "frandom: Seeded global generator now (used by erandom)\n"); #else ; #endif } i = state->i; j = state->j; S = state->S; for (k=0; k<count; k++) { i = (i + 1) & 0xff; j = (j + S[i]) & 0xff; swap_byte(&S[i], &S[j]); *buf++ = S[(S[i] + S[j]) & 0xff]; } state->i = i; state->j = j; up(&state->sem); }