LWN: Linus Torvalds下手修复了getrandom()

linux内核随机数初探 根据测试在系统时钟是200M的机器上samples_per_bit的值是1,也就是每次都会调用credit_init_bits.在系统时钟频率是25M的机器上samples_per_bit是2,也即每两次entropy_timer调用,调用一次credit_init_bits.系统时钟频率越高此值越大。根据测试,采样的用数量大约在250次左右,不同机器差异不大,如此,影响随机数初始化时间的因素包括硬件:系统时钟的频率;本机上大部分的调用都是entropy_timer, 即大部分的熵的来源是时钟中断。 阅读详情

Really fixing getrandom()

By Jonathan Corbet
October 17, 2019

From: https://lwn.net/Articles/802360/


5.3 kernel开发周期最后几天的时候有一场很热烈的讨论,关于getrandom() API以及需要revert一个ext4优化patch避免其导致系统启动过程中随机事件太少。长久来说,我们肯定不可能因为文件系统优化得太好了而阻止其合入kernel,所以大家都达成共识后面需要找到一个更好的解决方案。大家都想不到什么更好的方案,因此我们其实很惊奇的看到后来5.4里面提出的处理方案很少有人反对。


5.3中问题的核心:getrandom() API是一个阻塞调用,它会等到系统搜集到足够多的随机事件初始化好随机数生成器之后,才能让调用此API的函数返回。这样的行为受到很多批评,辩护的人反而不多。不过修改getrandom()不是件容易的事情。改得不小心的话,都会导致它返回的“随机数”被预测到,从而在安全场景下产生风险。所以,尽管有多种方案提出来,大家看起来这些方案估计要几年才能扯清楚。


还有一种方案来确保getrandom()在boostrap过程中不要阻塞:尽快搜集足够多的随机事件从而确保随机数生成器在有人要用的时候早已经初始化好了。具体来说有好几种做法,如果CPU本身有一个硬件随机数生成器的话,直接用硬件方案,有人可能觉得这个方案不可信,不过大多数人都认为把硬件事件和其他事件混在一起是一个安全可靠的做法,哪怕硬件随机数生成器本身不太随机。不过,不是所有的CPU都拥有硬件随机数生成器的,因此这个方法不够通用。还有一个其他方案就是让bootloader或者user space最早期执行的代码来初始化random pool(随机数池),这个方法有些情况下是可行的,不过也不是通用方案。


另一个可能方案是利用jitter entropy:从天生具有随机特性的硬件上搜集随机事件。哪怕一系列很简单的指令的执行时序(timing)也会每次都不相同,这主要是因为有多级缓存(cache)、预测执行、系统上执行的其他任务等共同干扰导致的。针对jitter entropy在过去多年的研究表明它是一个可行方案,虽然无法证明这是一个truly nondeterministic(真正不确定特性),不过肯定是无法预测的(unpredictable),采用jitter entropy生成的数据可以经过各种随机数测试的考验。


在5.3版本发布不久,Thomas Gleixner建议利用一种简单的jitter-entropy机制来初始化随机熵池。Linus Torvalds认为这个方案“不是非常可靠”,不过他觉得这个方向还是很有可取之处的。他自己稍微改变了一下这个方案,经过简短讨论之后,在5.4 merge window末期合入了。


Torvalds的patch增加了一个新函数try_to_generate_entropy()。如果有人在随机数池还没完全准备好的时候就要求获取随机数的话,就会导致调用这个函数。这个函数非常简单,开头是这样的:

    static void try_to_generate_entropy(void)
   {
struct {
   unsigned long now;
   struct timer_list timer;
} stack;


首先在stack(栈)里声明了一个timer,在kernel里面很少有这种用法,不过这里是故意放在stack上的。如果timer函数在另一个CPU上运行的话,在访问此函数的stack空间时就会产生cache contention(cache竞争),从而引起耗时(timing)变化。

	stack.now = random_get_entropy();

/* Slow counter - or none. Don't even bother */
if (stack.now == random_get_entropy())
   return;
timer_setup_on_stack(&stack.timer, entropy_timer, 0);


在大多数架构上,random_get_entropy()仅仅会直接读出timestamp counter(TSC)。TSC在每个clock cycle会增加一次,这样两次连续调用一定会产生两个不同的数值。不过具体来说这两个数字的差值是不固定的,没法预测出来。上面的代码只是想验证一下kernel正在运行的这个系统确实是有一个高频TSC的。否则的话这个算法没法生效了。型号大多数现代硬件都有TSC。在TSC检查通过之后,timer就可以拿来用了:

	while (!crng_ready()) {
   if (!timer_pending(&stack.timer))
mod_timer(&stack.timer, jiffies+1);
   mix_pool_bytes(&input_pool, &stack.now, sizeof(stack.now));
   schedule();
   stack.now = random_get_entropy();
}


这里的循环就是jitter-entropy算法的核心了。上面声明的timer,被配置成在很短的时间之后就会到期(下一个jiffy值,一般是0ms到10ms之间的值),到期触发之后的中断可能会在任何一个CPU上。这样timer到期实际上就是让执行的指令流更加复杂化(希望能增加随机性)。


每走一遍这个循环,都会查询一下TSC,把它的值混如随机数池中。timer到期之后就会重新配置进行下一轮。这样会导致scheduler也参与进来,引入其他各种各样的复杂代码,增加返回前代码执行的不可预知性。这个循环会在随机数池初始化好之后才停下。因为一个jiffy的时长内会发生很多事情,因此这个循环预计会执行很多次,能把多个TSC读数混进随机数池内去。

	del_timer_sync(&stack.timer);
destroy_timer_on_stack(&stack.timer);
mix_pool_bytes(&input_pool, &stack.now, sizeof(stack.now));
   }


循环之后就是清理代码,会删掉timer,并且再塞一点进随机数池。

timer函数本身是这样实现的:

    static void entropy_timer(struct timer_list *t)
   {
credit_entropy_bits(&input_pool, 1);
   }


换句话说,每次timer到期的时候,都会让随机数池里面增加一个bit的随机熵。随机数池只要有128 bit的随机熵就算是准备好了。这样可能jitter循环会执行最多128 jiffies,大致等同于100HZ tick frequency的系统上运行一秒钟的时间,这还是在假设系统其他部分一点都没有贡献随机熵的情况。这样可能还是会在启动过程中产生用户可以观察到的暂停一下的现象,不过比起完全阻塞住要好得太多了。


当Torvalds决定合入这些代码的时候,他认为这并不一定算是此问题的最终解决方案:“我不是说要让我的patch作为这个问题的结论。我个人觉得这个patch还行,不算太离谱。如果它让非常严格的人感到有点不爽,然后能发一个改进版的给我,那就算是值得了。”


因此他其实是沿用了以前的方式,尽早提交一个patch,寄希望于引起其他人的抱怨从而给出更好的方案。目前来说,还没有多少关于这个改动的评论。这其实有点奇怪,因为此前在讨论中可是有着非常多种观点的。除非有人能提供一个更好的主意,或者证明这个算法给出的随机熵其实是可以用某种方法预测出来的,否则这个方案就会一直沿用下去了。希望这个patch能达成目的,一方面避免getrandom()一直阻塞住,另一方面也能让kernel的随机数值保持真正不可以预测的特性。


Linux随机数发生器 Linux随机数发生器 日期:2017-11-29 01:42:10 星期三 Linux随机数发生器 一、源代码的基本情况 Linux内核版本 涉及文件 功能概述 二、外部访问接口 内核层输出接口 用户层输出接口 环境噪音输入接口 三、核心源码分析 随机数发生器理论 熵池结构 熵的加入 随机数的生成 启动脚本 四、回答主要问题 核心代码抽取 初始化漏洞攻击 五、参考... 阅读详情

相关推荐

无人机通信电台--XBee-PRO 900HP (S3B)

XBee PRO S3B也称为XBee-900HP无线模块,它是一款工作在频段900~928MHz之间,基于FHSS跳频技术的远距离无线数传电台核心模块。常用型号如下: 类别 型号 开发套件 XKB9-DMT-UHP XBee-PRO 900HP (S3B) DigiMesh模块,200Kbps,软天线 XBP9B-DMWT-002 XBee-PRO 900HP (S3B)...

low米的博客 4505

Linux内核 -- 随机数模块之`random_get_entropy` 函数

文件位置:通常位于与随机数生成器(Random Number Generator, RNG)相关的模块中,例如。功能用于从硬件或低级别资源中获取熵(entropy),以增强内核随机数生成器的熵池。使用场景:用于初始化随机数生成器的熵池,或在需要增强熵池时调用。是 Linux 内核中获取硬件熵的重要接口,其返回值虽然不是直接安全的随机数,但通过内核熵池机制,可以为用户空间提供高质量的随机数。

sz66cm 学习随笔 710

pcle接口详解&用途说明

它原来的名称为“3GIO”,由英特尔在2001年提出。pcel x16插槽 用途用于显卡、RAID阵列卡,向下兼容PCIE x1/x4/x8/x16。(PCIE x16插槽长89mm,有164根针脚,靠主板外侧端有一卡口,将16x分为前后两组,短插槽有22根针脚,主要用于供电,长插槽142根,主要用于数据传输,具有16通道所带来的高带宽)PCI-E x8插槽插槽用途:全长56mm,有98根针脚,与PCI-E x16比较,主要是数据针脚减少至76根,短的供电针脚仍然是22针脚。

qq_43289307的博客 1万+

Linux随机数不够用的问题解决

摘要 SpringBoot项目部署后接口卡顿问题排查发现是Linux系统熵值不足导致SecureRandom阻塞。通过安装haveged服务增加系统熵池,解决了/dev/random阻塞线程的问题。具体步骤包括下载编译安装haveged,安装后系统熵值从不足100提升至2000以上,接口响应恢复正常。该方案有效解决了Linux环境下随机数生成因熵不足引发的性能瓶颈。

Glubin的博客 518

Windows系统监控实战:Grafana+Prometheus+node_exporter配置全攻略

本文提供了一套完整的Windows系统监控解决方案,详细介绍了如何使用Grafana、Prometheus和node_exporter(Windows版为windows_exporter)构建可视化监控平台。从环境准备、组件安装配置,到数据可视化与常见问题排查,手把手指导您实现从数据采集到仪表盘展示的全过程,帮助您从被动救火转向主动预警,有效保障Windows服务器稳定运行。

assembly8low的博客 247

4D毫米波雷达点云可视化实战:从CANFD原始数据到Matplotlib三维动态图

本文详细介绍了4D毫米波雷达点云可视化实战,从CANFD原始数据解析到Matplotlib三维动态图实现的全流程。通过解析CANFD数据帧结构、点云数据编码原理,并结合Python实现CANFD通信接口,帮助开发者掌握4D雷达数据处理与优化技巧,最终实现高性能的3D点云动态可视化。

u9v0w的博客 568

python3random linux熵_linux随机数使用熵不足导致程序运行缓慢

熵池不足导致的运行缓慢问题有些程序运行加密时,系统会从虚拟设备(/dev/random)中取用随机数以供使用。然而,/dev/random会使用熵池中的数据来生成随机数.在熵不足时,生成随机数非常缓慢,导致阻塞.nginx,apache,tomcat,PHP等很多程序都会用到随机数,可以说很重要.什么熵Entropy(熵,[shāng])在信息论中表示数据的混乱程度或者不确定性,可理解为随机数据。...

weixin_39644146的博客 992

手把手教你接入京东购物小程序:从领券到下单的全流程解析

本文详细解析了如何从API申请到领券下单,手把手教你接入京东购物小程序的全流程。涵盖京东联盟账号注册、商品信息获取、优惠券链接转换等关键技术实践,帮助开发者高效实现电商功能集成,提升用户购物体验。

g5h6i的博客 907

linux系统https通信阻塞问题排查与修复

设备为快启设备,由于项目需要,设备启动后要尽快进行https通信,但是第一次进行https通信时,https会出现阻塞现象,而系统运行一段时间后再进行https通信则无此现象。而阻塞原因为内核生成随机值的机制。......

蘑菇人生的博客 2032

Ubuntu 22.04+/WSL2 中解决 `error: externally-managed-environment` 并成功安装 PyTorch + vLLM 的完整指南

Ubuntu 22.04+/WSL2 因遵循 PEP 668 规范,系统 Python 被标记为“外部管理”,导致直接使用 pip install 安装包时报错 externally-managed-environment。解决方案是创建虚拟环境: 通过 python3 -m venv ~/vllm-env 创建隔离环境 激活环境后安装 PyTorch(CUDA 12.1)和 vLLM 避免使用 sudo pip 或 --break-system-packages,防止破坏系统依赖 关键点: 虚拟环

刘一说的IT专栏 296

27、视网膜血管识别与分类的数据集和验证过程

本文介绍了视网膜血管自动识别与分类方法所使用的数据集及其验证过程。通过30张高分辨率的近红外反射视网膜图像,结合专业医生的手动标注结果,构建了包含597个血管段的基准数据集。研究采用准确率、召回率、F1分数和混淆矩阵等评估指标对模型进行验证,并提出了特征增强和分类器优化策略以提升性能。实验结果显示,该方法在复杂区域具有较强的鲁棒性和较高的准确性,为临床应用提供了可靠的依据。

i7j8k9l的博客 148

Linux编程之ioctl

在和设备驱动程序通信时,ioctl是很常用的一个调用,常用来配置、查询或者修改设备的配置。反过来说,编写驱动程序时,ioctl也是经常要实现的一个接口,以便应用程序可以方便地控制设备驱动。 应用程序中的ioctl ioctl函数的原型如下: #include <sys/ioctl.h> int ioctl(int fd, unsigned long request, ...); 可以看出该函数是一个可变参数的函数。第一个参数是一个文件描述符,通常用open

3054

2025电赛嵌入式:K210教程-如何刷固件 如何烧录代码 全网唯一

本文介绍了K210开发板的固件刷写和开发环境搭建方法。主要内容包括:1)从Sipeed官网下载合适的MaixPy固件,根据需求选择完整版或精简版;2)使用k-flash等工具烧录固件,注意区分亚博和Sipeed开发板的固件版本;3)介绍了擦除闪存的两种模式(部分擦除和完全擦除)及其应用场景;4)搭建CanMV开发环境,通过MaixPy IDE连接开发板并进行程序调试。文章还提供了常见问题的解决方法,如串口驱动安装、固件兼容性检查等,为K210开发提供了完整的入门指南。

FJN110的博客 546

linux 内核中的开发人员 名单 CREDITS文件

内核初始文件创建者

aa_jj的博客 13万+

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Linux下的随机数生成器

这两个设备的任务,是提供永不为空的随机字节数据流。很多解密程序与安全应用程序(如SSH Keys,SSL Keys等)需要它们提供的随机数据流。它同样使用熵池来收集随机事件,但在熵池中的随机性不足时,它会通过算法生成伪随机数来填补空缺。它使用熵池(entropy pool)来收集系统中的各种随机事件,如键盘输入、鼠标移动、当这些随机事件发生时,它们会被加入熵池,并由一个算法将其转化为随机数。如果熵池中的随机性不足,读取。一种是/dev/random或/dev/urandom:是Linux系统中提供的。

weixin_46115467的博客 1225

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

信息熵与随机数

在程序开发中,我们经常会用到随机数,确保某个事件发生是具有随机性,不可预测性的。而事实是随机性却不是那么随机,我们大多用的都是伪随机数。那什么才是真随机数呢? 信息熵 什么是熵?在物理学中,熵(entropy)是一个描述系统混乱程度的物理量,熵越大说明系统越无序、越混乱,不确定性越大。例如:一杯水,所有的水分子都是聚集在一起叫低熵,把这杯水静置一段时间,水分子扩散出处,弥漫到整个房间,这...

weixin_30470857的博客 561

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

熵不起的随机数

在维基百科上看了一些关于Entropy(熵)和PRNG(伪随机生成器)和RNG(随机数生成器)的文章。 Superhei曾经在Discuz的代码里也提出过:http://www.80vul.com/dzvul/sodb/14/sodb-2008-14.txt,也是:http://www.suspekt.org/2008/08/17/mt_srand-and-not-so-random-numbe

明潮的BLOG 3514

内核熵池entropy pool

随机数在许多领域都有重要应用,如Monte Carlo模拟、密码学和网络安全。随机数的质量直接关系到网络安全系统的可靠性和安全性,关系到 Monte Carlo模拟结果的可信度。自从计算机诞生起,寻求用计算机产生高质量的随机数序列的研究就一直是个长期受到关注的课题。Linux内核从 1.3.30版本开始实现了一个高强度的随机数发生器,本文根据Linux 2.6.10内核的源代码,详细分析该随机数产

li4850729的专栏 3873

性能提升8450%,Linux内核函数获大幅改进

Jason Donenfeld 是 WireGuard 的主要开发者,同时他也是 Linux 内核随机数相关代码的维护者,近日在他的领导下,Linux 内核的随机数生成器代码有了巨大幅度的改进。getrandom()背景2014年的时候,getrandom()被加入kernel,当时一个理由是因为LibreSSL project在Linux上抱怨在文件描述符被黑客恶意用光...

极客重生 438

linux_随机数

#include "stdio.h" #include "errno.h" #include int GetRandom(void *buf, int bytes) { int fd; int ret; fd = open("/dev/urandom", O_RDONLY| O_NONBLOCK); if(-1 == fd) { printf("open urandom err

BigBird 822

linux 在区间随机函数,我如何使用Linux getrandom系统调用在一个范围内生成一个随机数字?(How can I use Linux getrandom system call to g...

我如何使用Linux getrandom系统调用在一个范围内生成一个随机数字?(How can I use Linux getrandom system call to generate a random number within a range?)我有以下一段代码#include #include #include unsigned long int s;syscall(SYS_getrand...

weixin_34204530的博客 1465

Linux内核基础

1.get_random_bytes函数 随机数生成函数 /* * This function is the exported kernel interface. It returns some * number of good random numbers, suitable for key generation, seeding * TCP sequence numbers, e...

hhhhhyyyyy8的博客 2697

Linux 内核获取一定范围内的随机数

linux 内核获取一定范围内的随机数

qq_42931917的博客 2209

为什么getrandom()调用无法返回

linux,getrandom(),Qt

JiMoKuangXiangQu的专栏 1452
上一篇: LWN: 确保kmalloc()分配是对齐的
下一篇: LWN: GNU项目谁在管理?
LinuxNews搬运工
博客等级 码龄7年 438粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值