首页 > 系统相关 >Linux hwrng以及ARM TRNG记录

Linux hwrng以及ARM TRNG记录

时间:2023-06-13 19:45:01浏览次数:47  
标签:struct -- random rng dev TRNG Linux hwrng

关键词:hwrng,/dev/random,/dev/urandom,rngd,rngtest等。

 

 Linux hwrng驱动比较简单,hwrng core注册设备提供应用层设备。hwrnd driver提供具体硬件接口,然后注册到hwrng core中,以及往内核熵池提供随机数。

1. Linux hwrng框架

1.1 hwrng框架对外接口

 hwrng对外提供的API接口包括:注册接口、去注册接口、将硬件产生随机数加入到/dev/random接口。

其中注册和去注册接口分是否创建device_add接口两种。

/** Register a new Hardware Random Number Generator driver. */
extern int hwrng_register(struct hwrng *rng);
extern int devm_hwrng_register(struct device *dev, struct hwrng *rng);
/** Unregister a Hardware Random Number Generator driver. */
extern void hwrng_unregister(struct hwrng *rng);
extern void devm_hwrng_unregister(struct device *dve, struct hwrng *rng);
/** Feed random bits into the pool. */
extern void add_hwgenerator_randomness(const char *buffer, size_t count, size_t entropy);

 struct hwrng编写hwrnd硬件驱动的结构体,包含了操作函数集、熵质量、列表头、引用计数等。

一个驱动根据需要填写了结构体之后,即可通过hwrng_register()/devm_hwrng_register()注册到hwrng核心中,对/dev/hwrng设备的操作即可映射到注册的硬件。

struct hwrng {
    const char *name;
    int (*init)(struct hwrng *rng);--初始化回调函数。可为NULL。
    void (*cleanup)(struct hwrng *rng);--当rng的ref为0时被调用。可为NULL。
    int (*data_present)(struct hwrng *rng, int wait);--淘汰的接口。检查rng数据是否有效。
    int (*data_read)(struct hwrng *rng, u32 *data);--淘汰的接口。读取rng数据。
    int (*read)(struct hwrng *rng, void *data, size_t max, bool wait);--读取数据接口,替代data_present()和data_read()。
    unsigned long priv;
    unsigned short quality;--熵质量,0表示未知;1~1024越大表示越随机。

    /* internal. */
    struct list_head list;--插入rng_list中。
    struct kref ref;
    struct completion cleanup_done;
};

 1.2 rng core模块

rng core初始化时已经创建了/dev/hwrng设备,以及misc设备的一系列属性。

hwrng_modinit
  ->rng_buffer/rng_fillbuf--创建缓存。 ->register_miscdev ->misc_register(&rng_miscdev)
      ->device_create_with_groups--创建字符设备,操作函数集为rng_chrdev_ops,groups为rng_dev_groups。

device_create_with_groups()创建设备位于/sys/devices/virtual/misc下,目录名对应miscdevice->name;并将groups下面的attr创建对应的节点。

对于hw_random而言创建:

  • rng_selected--是否由用户空间选择rng设备,1表示是,0表示没有设置过。
  • rng_current--当前rng设备名称,可以写入名称来选择指定rng设备。
  • rng_available--可用rng设备名称。
static struct miscdevice rng_miscdev = {
    .minor        = HWRNG_MINOR,
    .name        = RNG_MODULE_NAME,
    .nodename    = "hwrng",
    .fops        = &rng_chrdev_ops,
    .groups        = rng_dev_groups,
};

static const struct file_operations rng_chrdev_ops = {
    .owner        = THIS_MODULE,
    .open        = rng_dev_open,
    .read        = rng_dev_read,
    .llseek        = noop_llseek,
};

static const struct attribute_group *rng_dev_groups[];

rng_dev_read()是hwrng设备read()调用底层函数:

rng_dev_read
    ->get_current_rng
    ->rng_get_data
        ->hwrng->read--调用驱动实现的read()函数。
        ->hwrng->data_present--为NULL则表示数据一直可读。否则函数返回1表示数据可读,使用data_read()读取数据,0表示不可读。
        ->hwrng->data_read--在data_present为NULL,或返回1时被调用。
    ->copy_to_user--拷贝数据到用户空间缓存。

hwrng注册接口主要将当前hwrng加入到rng_list列表中,并选择熵质量最高的硬件作为当前随机数硬件设备。后续对/dev/hwrng的操作,会转换为对hwrng->read()等的调用。

devm_hwrng_register
    ->hwrng_register
        ->list_add_tail--将当前hwrng设备加入到rng_list中。
        ->set_current_rng--根据hwrng->quality选择合适的hwrng设备作为当前设备。
      ->hwrng_init
        ->rng->init--hwrng设备初始化。
        ->start_khwrngd
          ->hwrng_fillfn ->add_early_randomness ->rng_get_data--从硬件读取随机数。 ->add_device_randomness--将硬件产生的随机数添加到inpu_pool熵池中。 ->device_add--创建

2. hwrng驱动

编写hwrng驱动,最主要的工作就是填充struct hwrng结构体,其他诸如dts解析,中断注册和处理,调试接口等。

其中init()完成hwrng设备初始化,cleanup()完成设备关闭扫尾工作,核心是read()读取随机数。data_read()和data_present()是被淘汰的接口。

2.1 硬件资料

ARM TRNG规格书《Arm True Random Number Generator (TRNG) Technical Reference Manual Revision r0p0》,对应的裸驱程序《TZ-TRNG: TrustZone True Number Generator》。

3. /dev/random和/dev/urandom

/dev/random和/devurandom都提供了随机数读取接口,更多参考《初探 Linux kernel 亂數產生器 – random generator》,《What are /dev/random and /dev/urandom in Linux?》,《Linux随机数发生器 (betheme.net)》。

static const struct memdev {
    const char *name;
    umode_t mode;
    const struct file_operations *fops;
    fmode_t fmode;
} devlist[] = {
     [8] = { "random", 0666, &random_fops, 0 },
     [9] = { "urandom", 0666, &urandom_fops, 0 },
};

const struct file_operations random_fops = {
    .read  = random_read,
    .write = random_write,
    .poll  = random_poll,
    .unlocked_ioctl = random_ioctl,
    .fasync = random_fasync,
    .llseek = noop_llseek,
};

const struct file_operations urandom_fops = {
    .read  = urandom_read,
    .write = random_write,
    .unlocked_ioctl = random_ioctl,
    .fasync = random_fasync,
    .llseek = noop_llseek,
};

另外还提供了getrandom系统调用。

4. hwrng测试程序

通过dd读取/dev/hwrng数据到指定文件:

dd if=/dev/hrrng of=rng.dat bs=1024 count=1

 

安装rng-tools,里面包含rngd和rngtest两个程序。

rngd作为守护进程,从/dev/hwrng中读取随机数,喂到内核熵池中。

rngd --rng-device=/dev/hwrng 

rngtest使用FIPS 140-2协议对从/dev/hwrng获取的数据进行检查。

cat /dev/hwrng | rngtest -c 1000

 

参考资料:《3.4. Using the Random Number Generator Red Hat Enterprise Linux 6》《》

标签:struct,--,random,rng,dev,TRNG,Linux,hwrng
From: https://www.cnblogs.com/arnoldlu/p/17469748.html

相关文章

  • 学无止境--linux 代码中获取pid的方法
    #include<linux/resource.h>#include<unistd.h>#include<signal.h>pid_twd_pid;charline[8];FILE*cmd;intpri;/*创建管道并创建shell子进程,执行pidofbspInit0命令:‘bspInit0’是进程名*/cmd=popen("pidofbspInit0","r");/*从文件流......
  • 10分钟让你掌握Linux常用命令(+3万+++收藏)
    1、常用Linux命令2、Linux下脚本编写3、windows下CMD常用命令文章目录一、目录操作1、批量操作二、文件操作三、文件内容操作(查看日志,更改配置文件)1、grep(检索文件内容)2、awk(数据统计)3、sed(替换文件内容)4、管道操作符`|`5、cut(数据裁剪)四、系统日志位置五、创建与删除软连......
  • Linux系统下如果在编译时指定程序运行时动态链接库相对目录,及为程序收集默认不安装动
    1、在编译中指定编译的程序去查找的动态链接库目录qmake是这样指定运行时动态库目录的:  QMAKE_LFLAGS+=-Wl,-rpath=/usr/local/ultrasec/policyfilter/lib/ 2、用lddPROG  查看程序的动态链接库,如果没有的动态链接库,就从其它计算机或者网络上找这个库,然后拷贝到指......
  • 宝塔Linux安装
    首先找到宝塔的安装地址:https://www.bt.cn/new/index.html第一步:安装宝塔SSH终端安装成功之后的界面是这样的:  第二步:Liunx宝塔面板的安装地址:https://www.bt.cn/btcode.html 这里我安装的是第一个 ......
  • Linux内核期末复习
    1、P22-252、P36、P165ret指令的作用:进程切换时用什么函数 _switch_to_函数如何理解怎么实现  3、gcc、gdb命令 gdb 堆栈汇编典型示例: 反汇编指令:  4、内嵌汇编(10号系统调用)#include<stdio.h>intmain(){longresult;longsys......
  • Linux(centos 7.5)安装Jenkins
    文章目录一、Jenkins软件安装1、Jenkins需要依赖JDK,所以先安装JDK1.82、Linux安装Gitlab3、下载Jenkins安装包4、安装Jenkins5、修改Jenkins配置6、启动Jenkins二、Jenkins简单配置1、打开浏览器访问2、获取并输入admin账户密码3、跳过插件安装4、添加一个管理员账户,并进入Jenkin......
  • Linux开机过程
    1.Linux开机时,会首先创建0号进程,0号进程会创建出1号和2号进程,然后0号进程本身会终止。2.1号进程(sbin/init)是所有用户进程的祖先,需要开机自启的进程可以挂在一号进程下,1号进程会再产生tty/pts终端,之后会再由该终端产生login,shell等3.2号进程是所有系统进程的祖先。4.另外,开机......
  • Linux 文件检索 | locate、grep、find
    Linux中查找文件或关键词检索文件内容是很常用的功能合理使用命令,高效检索需要的结果本文系统AmazonLinux2locate通常locate命令系统会自带,如果没有则需要安装mlocatelocate搜索文件速度很快,因为它不去实际目录中找文件,而是在文件数据库对应的文件中直接查找。数据......
  • oracle linux 7.9 静默安装oracle 11g
    搭建虚拟机步骤配置ip,步骤省略。 下载linux版本11gOracle安装包,通过sftp上传到虚拟机。oracle11.2.4安装包及补丁包链接如下:链接:https://pan.baidu.com/s/1TaVNOqXCoSjsJJZ-ADLkmw提取码:ycxi前两个zip包为oracle,第三个为grid安装包,只安装数据,则下载1和2即可,如需搭建......
  • c++ linux基础学习第一课
    课程目标:1.shell命令解析器shell就是命令解析器,将用户命令翻译成内核能够识别的指令。shell常用的快捷键:tab:补齐命令,补齐文件(包括目录和文件)ctrl+a光标移动到头部,ctrl+e光标移动到尾部2.linux下主要目录:/bin保存着二进制文件、可执行程序和shell命令/sbins是superu......