在内核模块中获取/ dev / random

时间:2016-06-24 01:34:27

标签: random linux-kernel linux-device-driver kernel-module

我需要在内核模块中同时获得/dev/random/dev/urandom

提供了{p> get_random_bytes API以获取/dev/urandom

/dev/random没有API,所以我尝试在内核空间中进行ioctl和读取文件。
这就是我所做的。

  1. 使用RNDGETPOOL ioctl
  2. <{1>}中的

    声明include/linux/random.h

    RNDGETPOOL

    但是,它不起作用所以我检查了/* Get the contents of the entropy pool. (Superuser only.) */ #define RNDGETPOOL _IOR( 'R', 0x02, int [2] ) 注意到driver/char/random.h已经消失!!

    RNDGETPOOL

    我搜索google并找出ioctl static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg) { int size, ent_count; int __user *p = (int __user *)arg; int retval; switch (cmd) { case RNDGETENTCNT: /* inherently racy, no point locking */ if (put_user(input_pool.entropy_count, p)) return -EFAULT; return 0; case RNDADDTOENTCNT: if (!capable(CAP_SYS_ADMIN)) return -EPERM; if (get_user(ent_count, p)) return -EFAULT; credit_entropy_bits(&input_pool, ent_count); return 0; case RNDADDENTROPY: if (!capable(CAP_SYS_ADMIN)) return -EPERM; if (get_user(ent_count, p++)) return -EFAULT; if (ent_count < 0) return -EINVAL; if (get_user(size, p++)) return -EFAULT; retval = write_pool(&input_pool, (const char __user *)p, size); if (retval < 0) return retval; credit_entropy_bits(&input_pool, ent_count); return 0; case RNDZAPENTCNT: case RNDCLEARPOOL: /* Clear the entropy pool counters. */ if (!capable(CAP_SYS_ADMIN)) return -EPERM; rand_initialize(); return 0; default: return -EINVAL; } } 已删除。完成了!

    1. 使用RNDGETPOOL

      中的random_read函数
      driver/char/random.c:997
    2. 这是我的内核模块对static ssize_t random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) 的函数访问。

      /dev/random

      输出似乎是随机的

      首先尝试

      static void read_file()
      {
        struct file *file;
        loff_t pos = 0;
        //ssize_t wc;
        unsigned char buf_ent[21]={0,};
        int ent_c;
        int i;
        ssize_t length = 0;
      
        mm_segment_t old_fs = get_fs();
        set_fs(KERNEL_DS);
      
        file = filp_open("/dev/random", O_WRONLY, 0);
        file->f_op->unlocked_ioctl(file, RNDGETENTCNT, &ent_c);
        if(ent_c < sizeof(char))
        {
          printk("not enough entropy\n");
        }
        printk("ent counter : %d\n", ent_c);
      
        //file->f_op->unlocked_ioctl(file, RNDGETPOOL, &ent_st.buf);
        length = file->f_op->read(file, buf_ent, ent_c/ 8, &pos);
        if(length <0)
        {
          printk("failed to random_read\n");
        }
        printk("length : %d\n", length);
        printk("ent: ");
        for(i=0;i<length; i++)
        {
            printk("%02x", buf_ent[i]);
        }
        printk("\n");
        filp_close(file,0);
        set_fs(old_fs);
      }
      

      第二次尝试

      [1290902.992048] ent_c : 165  
      [1290902.992060] length : 20  
      [1290902.992060] ent: d89290f4a5eea8e087a63943ed0129041e80b568
      

      顺便[1290911.493990] ent_c : 33 [1290911.493994] length : 4 [1290911.493994] ent: 7832640a 函数参数有random_read个关键字。代码中的Buf __user位于内核空间中。

      在内核空间中使用buf函数是否合适?

1 个答案:

答案 0 :(得分:2)

获取随机字节的内核中接口是get_random_bytes()

static void read_file(void)
{
    unsigned char buf_ent[21];

    get_random_bytes(buf_ent, 21);
    print_hex_dump_bytes("ent: ", DUMP_PREFIX_NONE, buf_ent, 21);
}