feat: openkal.random — entropy is not derivable from the other eight - #8
Merged
Conversation
⭐ **加一个接口的判据是「不加就实现不了」,而这一条满足它。**
`std::random_device` 在这套体系上不可用,查到底是三层:
std::random_device → libc++ 五条后端 → getentropy → musl getrandom()
→ syscall_cp(SYS_getrandom) → openkal-musl 无替代 → **规范无随机源接口**
⚠️ 而现有九个接口一个都给不出熵:
· `time` —— 时钟读数「对读源码的人不可预测,对攻击者可预测」。
这句话不是我写的,是 `openkal-musl/port/src/okm_start.c` 给 musl 的
`AT_RANDOM` 凑 16 字节时**自己写下的**,并注明「在这个 port 上
两者都不是安全属性」。给 allocator cookie 够用,给 random_device 不够。
· `fs` —— `kal_fs_open` 只能相对 preopen 目录打开,开不了
`/dev/urandom`。⭐ **那是能力模型在工作,不是缺口。**
· 其余六个与熵无关。
⚠️ 而绕过接口层直接发系统调用违反本规范存在的理由。**两条都不行,
于是层多一个接口。**
── ⭐ 它「宿主普遍有、裸机不一定有」,正是 6.1 条的形状 ────
linux/macos/windows getrandom / getentropy / ProcessPrng 有
uefi EFI_RNG_PROTOCOL —— **可选协议** 不一定
opensbi SBI 基础规范无 RNG 扩展 无
按 6.1 条,不提供的实现让这些名字作为链接期定义缺席 —— 与 `openkal.fs`
在 opensbi 上缺席完全同理,**不需要任何新机制**。
── ⚠️ 没有 `AVAILABLE` 能力字,而这是设计 ──────────────
「有没有」由接口的**在场与否**回答(6.1),不由能力字回答。
一个不提供任何操作却定义 `kal_random_props = 0` 的后端,会让程序
越过链接器存在的意义 —— 这正是 `openkal-opensbi@0.1.3` 撤回的那件事。
两个位各有理由:`BLOCKING`(熵不足时可能等待,影响早期启动路径的程序)、
`HARDWARE`(直接来自硬件 RNG,影响信任模型而非接口行为)。
── 无部分成功 ────────────────────────────────────
要么每个字节都填,要么一个都不填。一个必须循环的调用者要区分
「短读」与「没有更多熵」,而后者不是本接口的状态:一个环境要么有源、
要么不提供本接口。`kal_err_again` 是「源暂时为空」(刚启动、池未播种),
不是「本环境没有源」。
一致性套件加一节四条观察,含「两次填充不得相同」——
⚠️ 该条以 2^-256 概率误报,把概率写出来比省掉好。
声明检查 58/58 通过。
…id why
我把 `random` 放进 `hosted`,于是一致性套件对每一个尚未实现它的后端
**链接失败**:
lld-link: error: undefined symbol: kal_random_fill
⚠️ 而 `optional` 那段注释早就写着这件事:「a feature set that required every
optional interface would make optional mean nothing, **and the report would be
a link failure rather than an observation that did not hold**」。
⭐ `random` 与 `exec` 同形:宿主平台普遍提供,裸机只在板子有源时提供,
两者都不是偏离(6.1 条)。一个要求它的集合把「被允许的选择」变成了构建错误。
SPEC.md 的接口表同步改为 optional。
第 156 行那张表列出每个接口的模块名与头文件名,我加接口时漏了它。⚠️ 一张只列了八个而接口有九个的表,读者会当成「这个接口没有模块」。
新增 `openkal.random` 是加法而非破坏:既有八个接口的名字、签名与语义 一字未动,而 6.1 条已经规定「实现不提供的接口作为链接期定义缺席」, 所以一个尚未实现它的后端**仍然是 0.7 的合规实现**。⚠️ 次版本号而非补丁号:一致性套件的 `optional` 集合多了一项, 一个自称提供全部可选接口的实现因此要多提供一个。
标题与第 48 行的 "Version 0.6" 改为 0.7。⚠️ 第 340 行**不改** —— 那句 "Every declaration of version 0.6 already satisfies it" 是**历史陈述**,讲某条款当时为何没有让版本前进。 把它一起替换会把一句关于过去的记录改成一句关于现在的假话。
Sunrisepeak
added a commit
to mcpplibs/openkal-macos
that referenced
this pull request
Aug 24, 2026
* deps: follow openkal 0.7.0 规范新增 `openkal.random`(mcpplibs/openkal#8),版本升到 0.7.0。⚠️ CI 有一道版本同步门,而它的诊断说明了为什么必须一起改: this is openkal 0.7.0 and this implementation is written against openkal 0.6.0. Nothing is wrong with either; they are not in step. ⭐ 本包**不提供** `openkal.random`,而那不是偏离 —— 6.1 条规定实现提供一个 接口是全有或全无,不提供的接口作为链接期定义缺席。这里跟随的只是规范版本, 不是接口集合。 * feat: openkal.random on getentropy(2) ⭐ **号来自机器,不来自记忆。** `.github/workflows/numbers.yml` 从 SDK 自己的 `sys/syscall.h` 读出本实现用到的每一个号,在本仓库针对的两个 runner 上都读, 而两者都答 `SYS_getentropy 500`。那个 workflow 存在的理由正是: 一个凭记忆写下的号,在它出错的那天之前一直是对的。⚠️ **不用 `arc4random_buf`**,虽然 libc++ 在这个系统上默认会去找它。 那个名字在 libSystem 里,而伸手进 libSystem 正是本后端要避免的 —— 它直接发这个内核的调用,`sys.h` 的注释记着这一点。`getentropy` 是底下那一层。⚠️ **这个内核单次上限 256 字节。** 那是这个系统的限制而不是本接口的, 所以循环把它变成 `kal_random_fill` 承诺的「全有或全无」。 失败时缓冲区不恢复 —— 契约如此:失败的填充留下未指定内容而非原内容。 * release: 0.3.4 The branch carried 0.3.3, which is the version on `main` and the version already in the index. Following openkal 0.7.0 changes what this package declares, and on two of these repositories it also adds an interface, so the content behind that number is no longer the content published under it. openkal takes a minor bump for a new interface and an implementation following it takes a patch bump --- the shape of 0.5.2 → 0.6.0 with 0.5.2 → 0.5.3 beneath it.
Sunrisepeak
added a commit
to mcpplibs/openkal-opensbi
that referenced
this pull request
Aug 24, 2026
* deps: follow openkal 0.7.0 规范新增 `openkal.random`(mcpplibs/openkal#8),版本升到 0.7.0。⚠️ CI 有一道版本同步门,而它的诊断说明了为什么必须一起改: this is openkal 0.7.0 and this implementation is written against openkal 0.6.0. Nothing is wrong with either; they are not in step. ⭐ 本包**不提供** `openkal.random`,而那不是偏离 —— 6.1 条规定实现提供一个 接口是全有或全无,不提供的接口作为链接期定义缺席。这里跟随的只是规范版本, 不是接口集合。 * release: 0.1.5 The branch carried 0.1.4, which is the version on `main` and the version already in the index. Following openkal 0.7.0 changes what this package declares, and on two of these repositories it also adds an interface, so the content behind that number is no longer the content published under it. openkal takes a minor bump for a new interface and an implementation following it takes a patch bump --- the shape of 0.5.2 → 0.6.0 with 0.5.2 → 0.5.3 beneath it. * fix(ci): one specification in the graph, and follow the branch under test Two failures, both quiet until this change made them loud. The example asked for openkal 0.6.0 while the package it links asks for 0.7.0, so both were resolved and the engine fell back to mangling one copy's module names to let them coexist: Downloading mcpplibs.openkal v0.6.0 Downloading mcpplibs.openkal v0.7.0 Mangled openkal.abort v0.6.0 ↔ v0.7.0 → …__v0_7_0__mcpp (cross-major fallback) Mangling stages the sources under `target/.mangled/` and, by design, leaves headers where they are. This package's sources reach `sbi.h` as a quoted include beside them, which the staged copy has no path to: src/time.cpp:44:10: fatal error: 'sbi.h' file not found Naming one specification removes the fallback and the example builds against what the package is written for. The engine gap it exposed is real and is being fixed separately; nothing here depends on that. `OPENKAL_BRANCH` was `feat/openkal-closure`, a branch merged long before, so every run since had been cloning a stale specification and reporting on it. It now follows the branch under test where one of that name exists, and says which it used.
Sunrisepeak
added a commit
to mcpplibs/openkal-uefi
that referenced
this pull request
Aug 24, 2026
* deps: follow openkal 0.7.0 规范新增 `openkal.random`(mcpplibs/openkal#8),版本升到 0.7.0。⚠️ CI 有一道版本同步门,而它的诊断说明了为什么必须一起改: this is openkal 0.7.0 and this implementation is written against openkal 0.6.0. Nothing is wrong with either; they are not in step. ⭐ 本包**不提供** `openkal.random`,而那不是偏离 —— 6.1 条规定实现提供一个 接口是全有或全无,不提供的接口作为链接期定义缺席。这里跟随的只是规范版本, 不是接口集合。 * release: 0.1.3 The branch carried 0.1.2, which is the version on `main` and the version already in the index. Following openkal 0.7.0 changes what this package declares, and on two of these repositories it also adds an interface, so the content behind that number is no longer the content published under it. openkal takes a minor bump for a new interface and an implementation following it takes a patch bump --- the shape of 0.5.2 → 0.6.0 with 0.5.2 → 0.5.3 beneath it. * fix(ci): one specification in the graph The example asked for openkal 0.6.0 while the package it links asks for 0.7.0. Both were resolved, the engine fell back to mangling one copy's module names so they could coexist, and mangling stages sources without the headers beside them: src/kal.cpp:32:10: fatal error: uefi.h: No such file or directory Naming one specification removes the fallback.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
⭐ 加一个接口的判据是「不加就实现不了」,而这一条满足它。
std::random_device在这套体系上不可用,链条三层查到底,根在规范没有随机源接口。而现有九个接口一个都给不出熵:time—— 时钟读数「对读源码的人不可预测,对攻击者可预测」。这句话是openkal-musl/port/src/okm_start.c给AT_RANDOM凑数时自己写下的,并注明两者都不是安全属性。fs——kal_fs_open只能相对 preopen 目录,开不了/dev/urandom。⭐ 那是能力模型在工作,不是缺口。⭐ 「宿主普遍有、裸机不一定有」正是 6.1 条的形状
EFI_RNG_PROTOCOL—— 可选协议按 6.1 条不提供的实现让名字链接期缺席——与
openkal.fs在 opensbi 上缺席同理,不需要任何新机制。「有没有」由接口在场与否回答,不由能力字回答。定义
kal_random_props = 0却不提供操作,会让程序越过链接器存在的意义——正是openkal-opensbi@0.1.3撤回的那件事。声明检查 58/58;一致性套件加一节四条观察,含「两次填充不得相同」(⚠️ 2^-256 误报概率已写明)。