From 3deb51d83834b33691faa50fdbbd49a3379c596c Mon Sep 17 00:00:00 2001 From: chenjintao Date: Wed, 16 Sep 2026 17:27:21 +0800 Subject: [PATCH] Adapt WSS to new boards and use MQTT domain for eSIM connectivity Preserve main GNSS and volume behavior while porting verified TLS, receive fixes and full-handshake optimizations. Add MQTT connection diagnostics and route MQTT through banban.api.talkingq.com:1883. Include migration documentation and regression tools. Firmware builds and package checks passed; user confirmed new-board connectivity after switching the MQTT host to the domain. --- .gitignore | 3 + artifacts/wss/.gitignore | 3 + artifacts/wss/README.md | 13 + docs/WSS适配与性能优化完整总结.md | 1156 +++++ docs/new_board_wss.md | 125 + docs/talkingq_wss.md | 128 + .../threadx/common/include/mbedtls/config.h | 4254 +---------------- .../threadx/interface/custom_app/Makefile | 4 + .../threadx/interface/custom_app/hal_key.c | 7 +- .../custom_app/inc/mqtt_connect_diag.h | 9 + .../interface/custom_app/inc/talkingq_wss.h | 20 + .../interface/custom_app/lib/hal/hal.c | 11 +- .../custom_app/lib/librws/inc/librws.h | 1 + .../custom_app/lib/librws/inc/rws_common.h | 2 + .../custom_app/lib/librws/inc/rws_handshake.h | 8 + .../custom_app/lib/librws/inc/rws_socket.h | 2 + .../lib/librws/inc/rws_tls_config.h | 5 + .../custom_app/lib/librws/src/rws_handshake.c | 79 + .../lib/librws/src/rws_socketpriv.c | 638 ++- .../custom_app/lib/librws/src/rws_socketpub.c | 6 +- .../threadx/interface/custom_app/mqtt.c | 17 +- .../interface/custom_app/mqtt_connect_diag.c | 107 + .../interface/custom_app/talkingq_root_ca.c | 18 + .../interface/custom_app/talkingq_wss.c | 53 + .../interface/custom_app/ws_talkingq.c | 64 +- ql-config/config/talkingq_mbedtls_config.h | 79 + ql-kernel/threadx/common/include/config.h | 81 +- .../threadx/common/include/mbedtls/config.h | 81 +- .../threadx/common/include/mbedtls/ecdsa.h | 612 +++ ql-kernel/threadx/quec_mbedtls/x509.c | 6 +- tools/check_mbedtls_abi.py | 61 + tools/probe_talkingq_wss.ps1 | 59 + tools/probe_wss_groups.py | 40 + tools/probe_wss_root.py | 36 + tools/test_mbedtls_cert.c | 169 + tools/test_mbedtls_cert.py | 37 + tools/test_mqtt_diag.py | 107 + tools/test_wss.c | 58 + tools/test_wss.cmd | 17 + tools/test_wss_handshake.py | 75 + tools/test_wss_io.py | 80 + tools/test_wss_receive.py | 126 + tools/verify_wss_package.py | 67 + tools/wss_host_stubs/UART.h | 1 + tools/wss_tls_host_config.h | 14 + 45 files changed, 3724 insertions(+), 4815 deletions(-) create mode 100644 artifacts/wss/.gitignore create mode 100644 artifacts/wss/README.md create mode 100644 docs/WSS适配与性能优化完整总结.md create mode 100644 docs/new_board_wss.md create mode 100644 docs/talkingq_wss.md create mode 100644 ql-application/threadx/interface/custom_app/inc/mqtt_connect_diag.h create mode 100644 ql-application/threadx/interface/custom_app/inc/talkingq_wss.h create mode 100644 ql-application/threadx/interface/custom_app/lib/librws/inc/rws_handshake.h create mode 100644 ql-application/threadx/interface/custom_app/lib/librws/inc/rws_tls_config.h create mode 100644 ql-application/threadx/interface/custom_app/lib/librws/src/rws_handshake.c create mode 100644 ql-application/threadx/interface/custom_app/mqtt_connect_diag.c create mode 100644 ql-application/threadx/interface/custom_app/talkingq_root_ca.c create mode 100644 ql-application/threadx/interface/custom_app/talkingq_wss.c create mode 100644 ql-config/config/talkingq_mbedtls_config.h create mode 100644 ql-kernel/threadx/common/include/mbedtls/ecdsa.h create mode 100644 tools/check_mbedtls_abi.py create mode 100644 tools/probe_talkingq_wss.ps1 create mode 100644 tools/probe_wss_groups.py create mode 100644 tools/probe_wss_root.py create mode 100644 tools/test_mbedtls_cert.c create mode 100644 tools/test_mbedtls_cert.py create mode 100644 tools/test_mqtt_diag.py create mode 100644 tools/test_wss.c create mode 100644 tools/test_wss.cmd create mode 100644 tools/test_wss_handshake.py create mode 100644 tools/test_wss_io.py create mode 100644 tools/test_wss_receive.py create mode 100644 tools/verify_wss_package.py create mode 100644 tools/wss_host_stubs/UART.h create mode 100644 tools/wss_tls_host_config.h diff --git a/.gitignore b/.gitignore index 25e8ee1..36e7a39 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,9 @@ /target/ /version/ +# Local legacy-board packages retained when switching to the new-board branch. +/artifacts/legacy-no-gnss/ + # Extracted toolchain and local compiler license; keep compile_tools.zip in LFS. /ql-cross-tool/win32/owtoolchain/ diff --git a/artifacts/wss/.gitignore b/artifacts/wss/.gitignore new file mode 100644 index 0000000..7c9d611 --- /dev/null +++ b/artifacts/wss/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!README.md diff --git a/artifacts/wss/README.md b/artifacts/wss/README.md new file mode 100644 index 0000000..f43ad08 --- /dev/null +++ b/artifacts/wss/README.md @@ -0,0 +1,13 @@ +# WSS 联调包 + +最新域名试验包:new-board/mqtt-domain/EG800AKCN_11LG-new-board-wss-mqtt-domain.zip。MQTT 改为 banban.api.talkingq.com:1883,保留诊断日志;用户已确认改域名后新板连接成功,详细成功日志和其他业务验收尚未提供。 + +最新网络诊断包:new-board/mqtt-diag/EG800AKCN_11LG-new-board-wss-mqtt-diag.zip。沿用新板 WSS 内核,APP 补充 MQTT 收发、CONNACK 和语音键网络准入日志,具体根因待新板日志确认。 + +当前 main 对应新板,下载包为 [EG800AKCN_11LG-new-board-wss-x25519.zip](D:/banban/project/nfc_gnss/artifacts/wss/new-board/EG800AKCN_11LG-new-board-wss-x25519.zip)。这是包含本次内核和 APP 的完整多分区包,默认连接 `wss://banban.api.talkingq.com:443/ws`,保留新板 GNSS。音量沿用原 main 逻辑,读取不到保存值时回退至 70。 + +新板已经完成内核、APP、固件打包和主机/静态验证,尚待新板上板测试。包哈希、镜像一致性、GNSS 任务入口、TLS 算法与时间检查结果见 `new-board/verification.json`;迁移说明见 [新板 WSS 文档](D:/banban/project/nfc_gnss/docs/new_board_wss.md)。 + +旧板包 `full-handshake/EG800AKCN_11LG-legacy-wss-x25519.zip` 保持原样,属于无 GNSS、默认音量 100 的旧板配置。旧板 2026-09-16 日志确认 X25519 完整 TLS 握手 1455 ms;该数值不是新板实测结果。旧板 NIST 版本、接收修复版本及更早实验包保留用于历史追溯。完整旧板过程见 [旧板总结](D:/banban/project/nfc_gnss/docs/WSS适配与性能优化完整总结.md)。 + +构建日志、测试报告、公共证书和包体在本目录本地保存并被 Git 忽略;提交源码与文档不会把这些本地包一并上传。 diff --git a/docs/WSS适配与性能优化完整总结.md b/docs/WSS适配与性能优化完整总结.md new file mode 100644 index 0000000..a33a246 --- /dev/null +++ b/docs/WSS适配与性能优化完整总结.md @@ -0,0 +1,1156 @@ +# 旧板 WSS 适配、故障修复与性能优化完整总结 + +> 新板 main 说明:本文保留旧板历史过程、配置与实测数据。新板已迁入 WSS,保留 GNSS 与原 main 音量行为;新板构建、下载包及验收请见 [新板 WSS 迁移说明](D:/banban/project/nfc_gnss/docs/new_board_wss.md)。旧板实测耗时不代表新板实测。 + +> 整理日期:2026-09-16;设备日志时间按用户提供的串口时间记录。 +> +> 工作区:`D:\banban\project\nfc_gnss`。分支:`legacy-board-wss`。本文覆盖的最新代码提交:`551a7bb1e657c12f45ac0a1f2ca851625723a63d`。 +> +> 最新板端证据:2026-09-16 15:52 的 X25519 版本日志。本文区分代码事实、主机测试、板端日志和未来建议,不把主机基准当作设备实测。 + +## 1. 最终成果与当前状态 + +此次工作把旧板语音业务的 WebSocket 通道从明文 WS 迁移到经过服务器证书校验的 WSS,并修复了迁移过程中暴露的内核密码算法缺失、APP/内核配置不一致、证书时间来源不正确、非阻塞接收误断线等问题。 + +当前业务入口为: + +```text +wss://banban.api.talkingq.com:443/ws +``` + +截至最新日志,板端已经完成以下验证: + +| 项目 | 结果与依据 | +| --- | --- | +| 无 GNSS 旧板启动 | 正常绕过 GNSS 识别与定位流程 | +| 蜂窝网络与 MQTT | 最新日志中均已连接 | +| 根 CA 解析 | `WSS root CA parsed successfully` | +| TLS 1.2 完整握手 | 成功,`ret=0`,最终状态 `state=16` | +| 服务器证书与域名验证 | `WSS TLS handshake and certificate/hostname verification passed` | +| X25519 协商 | `WSS TLS negotiated ECDHE group: 9` | +| WebSocket 升级 | `WebSocket upgrade verified: HTTP 101` | +| APP 连接回调 | `websocket connected`、`ws connect okay` | +| 原业务鉴权 | 已调用原逻辑发送 `device_id`、`serial_number`;该日志片段未单独展示服务端鉴权成功响应 | +| 录音初始化 | 提示音结束后进入 VAD 录音 | + +最主要的性能成果: + +| 版本/阶段 | TLS 完整握手 | 说明 | +| --- | ---: | --- | +| 基础 WSS 修复后,未启用 NIST 加速 | 约 9.6 秒 | 14:20 日志,以串口 TCP 成功到 TLS 完成的时间差估算 | +| 启用 NIST 快速模约减 | 1820 ms | 14:38 日志,设备内部 tick 计时 | +| NIST 加速 + X25519 优先 | **1455 ms** | 15:52 日志,设备内部 tick 计时 | + +与最初约 9.6 秒相比,最新 TLS 完整握手时间减少约 **85%**,原耗时约为当前的 **6.6 倍**。其中第二轮曲线调整使 1820 ms 进一步下降到 1455 ms,减少 **365 ms,约 20%**。 + +这些是具体日志样本的对比,不是多次测试的平均值、P95 或性能承诺。第一轮基线与后两轮的计时方式也不完全相同,百分比应按近似结果理解。 + +最新版本仍然满足用户明确的条件:**按键后建连,每次新建 TLS 连接执行完整握手,不提前建立连接,不依赖 TLS 会话恢复来获得上述加速。** 已存活的业务连接按原逻辑使用,没有新增“每次按键强制断开再连接”的行为。 + +## 2. 项目背景、范围与约束 + +### 2.1 硬件与软件背景 + +- 目标产品:Quectel EG800AKCN_11LG,日志平台为 ASR1605/CRANELRH。 +- 操作系统与 SDK:ThreadX/OpenCPU 厂商 SDK。 +- TLS 库:SDK 中的 mbedTLS 2.28.9。 +- 内核编译器:ARM Compiler 5 / ARMCC。 +- APP 编译器:ARM GCC 9.2.1。 +- WebSocket 库:项目内的 librws,调用 SDK 导出的 mbedTLS 接口。 +- 旧板没有 GNSS,已有旧板分支负责跳过 GNSS 检测;默认音量为 100。 + +WSS 问题不能简单归结为“旧板硬件不兼容”。后续板端完整握手、HTTP 101 和录音初始化已经证明,该板具备运行当前 WSS 方案的能力。主要障碍来自软件配置、协议状态处理和运算性能。 + +### 2.2 本次修改的范围 + +本次迁移的是 TalkingQ 语音业务 WebSocket 连接,包含 TLS、WebSocket Upgrade、连接状态处理、必要的内核算法支持与测试工具。 + +沿用以下原业务约定: + +- 设备身份继续通过 `device_id`、`serial_number` 发送。 +- 不增加 TLS 客户端证书或客户端私钥,不使用双向 TLS。 +- 没有把 MQTT、HTTP 下载、升级接口等所有网络通道统一改成 HTTPS/TLS。 +- 未修改服务器配置;本文提到的服务器转发只是诊断背景和建议。 +- 性能优化没有修改按键逻辑、休眠策略、提示音或录音业务流程。 + +### 2.3 用户最终选定的性能路线 + +排查中讨论过提前建连、复用连接、TLS 会话恢复等方法。用户最终明确选择: + +> 只优化每次完整握手,不提前建连。 + +因此最终落地的性能改动是 NIST 运算加速和 X25519 优先协商。会话恢复只做过主机探测,没有加入固件。 + +## 3. WSS 到底增加了什么 + +WSS 的协议关系是: + +```text +蜂窝数据网络 → DNS → TCP → TLS → HTTP WebSocket Upgrade → WebSocket 业务消息 +``` + +`wss://` 不能只当作 `ws://` 的字符串替换。设备必须能够建立 TLS 通道,验证服务端身份,然后在 TLS 通道中发送 WebSocket 握手请求。 + +```mermaid +sequenceDiagram + participant U as 用户按键 + participant A as APP / librws + participant T as SDK TLS + participant S as 服务端 + U->>A: 触发业务连接 + A->>S: DNS 与 TCP 连接 + A->>T: 配置根 CA、SNI、域名及 TLS 参数 + T->>S: ClientHello + S-->>T: ServerHello、证书链、ECDHE 参数与签名 + T->>T: 验证证书链、时间、域名和握手签名 + T->>T: 生成临时密钥并计算共享密钥 + T->>S: ClientKeyExchange、Finished 等 + S-->>T: Finished 等 + T-->>A: TLS 握手与验证通过 + A->>S: GET /ws + Upgrade + 随机 Key + S-->>A: HTTP 101 + 匹配的 Accept + A->>S: 原 device_id / serial_number 鉴权消息 +``` + +这里有三个独立的成功条件: + +1. **TLS 成功**:安全通道建立,并验证服务器身份。 +2. **WebSocket 成功**:HTTP Upgrade 返回并通过 101/Accept 校验。 +3. **业务鉴权成功**:服务端接受设备身份,允许后续业务。 + +`MQTT Connected` 只能证明 MQTT 连接成功;`ws connect okay` 也不能单独证明后端已经确认设备鉴权或完成语音业务。 + +## 4. 域名、端口、路径与服务器排查 + +### 4.1 各字段的含义 + +| 字段 | 当前值 | 作用 | +| --- | --- | --- | +| 协议 | `wss` | WebSocket over TLS | +| 域名 | `banban.api.talkingq.com` | DNS、TLS SNI、证书域名匹配、HTTP Host | +| 端口 | `443` | 本次可用的 TLS 入口 | +| 路径 | `/ws` | HTTP/WebSocket 路由,不是磁盘路径或证书路径 | + +证书通常验证 DNS 名称。即使域名解析到某个 IP,也不能随意把 URL 换成该 IP,并期待原域名证书仍通过验证。 + +### 4.2 后台探测结论 + +2026-09-16 的多轮探测结果如下,均属于当时的服务状态: + +| 测试地址 | 初期情况 | 后续结果 | +| --- | --- | --- | +| `wss://banban.api.talkingq.com:443/ws` | TLS 可用,但 HTTP Upgrade 一度返回 404 | 11:32 复测返回有效 101,Accept 匹配;后续板端也成功 | +| `wss://banban.api.talkingq.com:8080/ws` | TLS 无法建立,出现协议格式错误 | 未验证到可用 WSS | +| `ws://banban.api.talkingq.com:8080/ws` | 明文 WebSocket 测试 | 返回有效 101 | + +准确解释是: + +- 443 上出现过 404,说明当时请求没有到达可用的 `/ws` Upgrade 路由;不能由此推断 443 没有任何 HTTPS 服务。 +- 8080 的 WSS 失败,不等于 TCP 端口完全不通。明文 WS 成功说明该端口当时提供的是明文服务。 +- 后台后续 443 `/ws` 已可用,固件最终选择 443 WSS。 +- 这些测试没有向后台发送设备鉴权身份或语音业务数据。 + +### 4.3 eSIM 白名单的关系 + +此 WebSocket 通道至少需要运营商允许 `banban.api.talkingq.com:443` 的访问,并支持所需 DNS 解析。运营商是按域名、IP、端口还是代理规则放行,取决于其平台。 + +设备仍有 MQTT、下载和升级等独立通道。本次 WSS 成功不代表整个设备只需要这一个白名单地址。应按真实启用的业务逐项梳理,不能把历史 WS IP 或一次解析得到的 IP 当作永久完整清单。 + +## 5. 第一轮实现:把业务连接真正迁移到 WSS + +对应提交:`3e463f57b69732ced0562e8e52915cc1566c4b6c`。 + +### 5.1 统一地址解析与默认地址 + +新增 `talkingq_wss.h` 与 `talkingq_wss.c`,集中定义默认入口,并把域名、端口、路径分开解析。 + +解析规则包括: + +- 必须是 `wss://`,不自动降级成明文 WS。 +- 未指定端口时使用 443,未指定路径时使用 `/ws`。 +- 拒绝空域名、非法端口、超长输出、CR/LF 等非法路径字符。 +- 当前不是通用浏览器 URL 解析器,不支持 IPv6 字面量、userinfo 等全部 URI 语法。 +- 地址存储缓冲区容量为 64 字节,业务侧主机缓冲区 64 字节、路径缓冲区 128 字节;后两者更大并不代表持久化 URL 也能存储同样长度。 + +### 5.2 保存的 talkingq_url 从哪里来 + +实际读取链路是: + +```text +talkingq_ws_connect() + → hal_os_get_talkingq_url() + → hal_kv_get("talkingq_url", ...) + → talkingq_parse_wss_url() + → rws_socket_set_url() +``` + +实际保存入口为 `hal_os_set_talkingq_url()`,通过 `hal_kv_set()` 写入 KV。仓库中可见的调用来自 `fota.c` 的共享属性处理:收到 `shared.talkingq_url`,当值非空且与当前读取结果不同时保存。该代码存在不等于每次启动必然走到该分支,执行时机还受原属性请求流程控制。 + +源码中虽然保留了 `U:/talkingq_url.txt` 的旧文件辅助函数,但当前 getter/setter 调用这些函数的语句是注释,实际使用的是 KV。 + +### 5.3 旧地址迁移 + +getter 对“没有保存值”以及下列已知历史默认地址,返回新的默认 WSS 地址: + +```text +ws://101.35.224.118:8080 +ws://101.35.224.118:8080/ws +ws://api.talkingq.com:8080 +ws://175.24.73.253:80 +``` + +这是**读取时迁移**,不会因为一次读取就重写 Flash。自定义地址不会被无条件替换;自定义明文地址会被后续 WSS 解析规则拒绝。 + +影响:既有设备不必先清空 KV 才能迁移已知默认值,但后台如继续下发自定义 `ws://` 地址,会导致明确连接失败,需要同步调整配置。 + +### 5.4 接入真正的 TLS 传输 + +- 通过统一的 `rws_tls_config.h` 启用 librws 的 mbedTLS 分支,避免公共/私有头文件宏不一致。 +- 保留已工作的蜂窝 PDP profile 1 TCP 路径,连接成功后将 socket 交给 mbedTLS 的 BIO 收发函数。 +- 没有直接套用标准示例中的 `mbedtls_net_connect()`,因为本 SDK 的接口存在 CID/端口等厂商 ABI 差异。 +- 配置可信根 CA、`MBEDTLS_SSL_VERIFY_REQUIRED`、SNI 与预期服务器域名。 +- 设置 WSS 最低 TLS 版本为 TLS 1.2;此 SDK 配置实际支持到 TLS 1.2,本次没有引入 TLS 1.3。 +- TLS 建立后,HTTP Upgrade、WebSocket 文本和二进制收发均走相应 TLS 接口。 + +### 5.5 单向 TLS 与原业务鉴权 + +不做双向 TLS,仍然需要设备验证服务器证书。二者区别如下: + +| 机制 | 谁验证谁 | 本项目做法 | +| --- | --- | --- | +| 服务器证书验证 | 设备验证服务端 | 必须执行 | +| TLS 客户端证书 | 服务端在 TLS 层验证设备证书 | 未启用 | +| 应用层设备鉴权 | 服务端验证设备提交的业务身份 | 保留原 `device_id`、`serial_number` | + +内置根 CA 是公开证书,不是需要保密的客户端私钥。 + +### 5.6 WebSocket Upgrade 的完整验证 + +新增独立响应解析器,要求: + +- HTTP 状态为 101。 +- `Upgrade` 含 `websocket`。 +- `Connection` 含 `upgrade`。 +- `Sec-WebSocket-Accept` 与本次随机 Key 对应。 +- 拒绝重复/错误 Accept,以及本客户端没有请求的扩展或子协议。 +- 支持响应头分片接收,设置 8192 字节响应头上限,保留头结束后的 WebSocket 数据。 + +协议计算公式为: + +```text +Key = Base64(16 字节随机数) +Accept = Base64(SHA-1(Key 的 ASCII 文本 + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11")) +``` + +这里的 SHA-1 是 RFC 6455 的 Upgrade 匹配算法,不是本次服务器证书签名算法,也不承担 TLS 身份认证。服务器身份由 TLS 证书验证保证。 + +### 5.7 发送、任务和资源生命周期 + +改动同时补齐: + +- TLS 短写:只发送一部分时继续发送剩余部分。 +- `WANT_READ/WANT_WRITE`:按库语义重试,不按普通 socket 的 `-1` 处理。 +- 致命错误、EOF、超时:明确退出并通知连接失败。 +- 回调身份校验:只处理属于当前 APP socket 的事件。 +- 正在启动/连接的 worker:由 worker 完成退出和对象释放,避免调用方提前释放活跃对象。 +- 连接失败唤醒等待连接的业务线程。 +- WSS worker 栈从 4 KiB 增至 16 KiB,为证书解析和密码运算提供空间。 + +增加的栈空间约为每个该 worker 12 KiB。尚无长期栈水位与高负载峰值报告,不能仅凭启动时剩余堆较大就认定所有内存情形都已覆盖。 + +## 6. 根证书解析失败 -9774:原因与修复 + +对应主要提交:`5c3e7eee6dc3bbf6d514af6bb93465bc81d6c952`。该提交还包含后续接收误断线修复,见第 9 节。 + +### 6.1 现象 + +早期板端已经联网、MQTT 已连接,WSS 输出: + +```text +WSS trust anchor loaded: 789 bytes +WSS TLS connection failed: -9774 +``` + +这不是“服务器证书过期”的直接证据,也不是硬件没有 GNSS 导致的 TLS 故障。 + +### 6.2 错误码分解 + +```text +-9774 = -0x262E + = MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG (-0x2600) + + MBEDTLS_ERR_OID_NOT_FOUND (-0x002E) +``` + +X.509 解析器通过 OID 识别签名算法。固件内置 ISRG Root X2 使用 ECDSA/SHA-384,但原内核 mini TLS profile 没有启用 ECDSA;相关映射/能力被条件编译裁剪后,解析该 CA 时无法识别所需算法。 + +`trust anchor loaded` 只表示证书数据交给了连接代码,不代表 X.509 解析或信任校验已经成功。 + +### 6.3 实际证书链 + +本次捕获和验证的链为: + +```text +banban.api.talkingq.com + └─ Let's Encrypt YE1 + └─ ISRG Root YE(由 ISRG Root X2 交叉签名) + └─ ISRG Root X2(设备信任锚) +``` + +| 证书 | 证书中的公钥 | 证书签名算法 | 当时有效期,UTC | +| --- | --- | --- | --- | +| 服务器叶证书 | P-256 | ECDSA with SHA-384 | 2026-08-28 14:10:29 至 2026-11-26 14:10:28 | +| YE1 | P-384 | ECDSA with SHA-384 | 2025-09-03 至 2028-09-02 | +| Root YE 交叉签名证书 | P-384 | ECDSA with SHA-384 | 2026-05-13 至 2032-09-02 | +| ISRG Root X2 | P-384 | ECDSA with SHA-384 | 2020-09-04 至 2040-09-17 | + +设备内置根 CA 的 DER SHA-256: + +```text +69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470 +``` + +以上是当次证书快照,不能当作后台永远不会变化的配置。服务器证书正常续期且仍能构建到受信任根时,通常不需要同步烧录新叶证书。 + +### 6.4 修复措施 + +新增共享配置 `ql-config/config/talkingq_mbedtls_config.h`,在保留原 mini profile 能力的基础上增加: + +| 宏 | 作用 | +| --- | --- | +| `MBEDTLS_ECDSA_C` | 解析与验证 ECDSA 签名 | +| `MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED` | 支持 ECDHE 密钥交换、ECDSA 服务器认证的 TLS 套件 | +| `MBEDTLS_GCM_C` | 支持 AES-GCM 记录层加密 | +| `MBEDTLS_HAVE_TIME_DATE` | 启用证书日期验证 | +| `MBEDTLS_PLATFORM_TIME_ALT` | 使用 SDK 的时间适配 | +| `TALKINGQ_TLS_USE_RTC_TIME` | 选择本产品可用的 RTC 时间路径 | + +同时把 APP 中同版本的 `mbedtls/ecdsa.h` 补入内核缺失的位置。它是 SDK 同版本头文件补齐,不是自行编写一套 ECDSA 实现。 + +### 6.5 结果与影响 + +- 实际 SDK 主机测试中,根 CA 解析从此前板端的 `-9774` 对应故障变为返回 0。 +- 后续板端明确出现 CA 解析成功和证书/域名验证通过。 +- 内核需要重编并烧录,不能仅修改 APP 的宏或地址。 +- 原先“只编译 APP + firmware 就能完成最初 WSS 适配”的判断,在发现内核缺失算法后被纠正。只重新打包旧内核不会补出 ECDSA。 + +## 7. APP/内核 mbedTLS ABI 不一致的隐患 + +### 7.1 原因 + +APP 原先使用一份较完整的 mbedTLS 配置头文件,实际内核使用厂商 mini profile。mbedTLS 的很多结构体成员由宏条件控制,配置差异会改变结构体大小及字段偏移。 + +APP 分配的上下文由内核代码读写。若双方理解不同,可能出现越界写、指针解释错误或不可预测的崩溃。此项是在审查中发现并处理的结构性风险;不能把所有此前日志异常都反推为它已经造成了内存破坏。 + +### 7.2 解决方法 + +- APP 配置头改成共享 profile 的包装层。 +- 内核两个相关配置头的 mini 分支引用同一 profile;原完整配置分支保留。 +- 用 ARMCC 编译内核头、GCC 编译 APP 头,比较实际 `sizeof` 与 `offsetof`,同时比较启用的 TLS 宏。 +- X25519 诊断增加对 `curve_list`、握手参数和 ECDH 上下文布局的检查。 + +当前校验的 12 种结构体大小如下,单位为字节: + +| 类型,均带 mbedtls_ 前缀 | 大小 | 类型 | 大小 | +| --- | ---: | --- | ---: | +| ssl_context | 232 | ssl_config | 152 | +| net_context | 8 | x509_crt | 340 | +| pk_context | 8 | entropy_context | 632 | +| ctr_drbg_context | 320 | ecp_group | 124 | +| ecp_point | 36 | mpi | 12 | +| ssl_handshake_params | 952 | ecdh_context | 224 | + +例如 `ssl_config.curve_list` 偏移为 128,`ssl_handshake_params.ecdh_ctx` 偏移为 32;这些是本 SDK、本编译器配置下的实测值,不应当作为其他 SDK 的通用常量。 + +影响:减少跨 APP/内核调用的 ABI 风险,但共享配置也意味着以后修改 TLS 功能宏时,应同时考虑 MQTT/其他调用内核 TLS 的模块,并重新执行 ABI 与相关功能检查。 + +## 8. 证书日期校验与 RTC 修复 + +只补 ECDSA 仍不完整:证书验证还需要可信且合理的当前时间。 + +内核厂商 X.509 路径原本调用 `GetCurrentCompTime()`;通过当前构建的符号和反汇编发现,该产品中的实现是空 shim,不能提供有效年月日。直接启用日期校验而保留此路径,可能把当前日期当成无效或错误值。 + +处理方式: + +1. 在 `x509.c` 中通过 `TALKINGQ_TLS_USE_RTC_TIME` 选择 `mbedtls_time()` 加 UTC 转换路径。 +2. 使用 SDK 实际 RTC 的时间实现,避免空 shim。 +3. APP 在 TLS 初始化前检查时间是否明显未初始化;早于 2024-01-01 时拒绝连接并给出日志。 +4. 内核反汇编确认 `x509_get_current_time` 调用 `mbedtls_platform_gmtime_r`,不再调用该空 shim。 + +“晚于 2024-01-01”只是启动前的粗筛,不等于时间准确。实际证书验证仍会检查 `notBefore/notAfter`。运营商 NITZ/RTC 同步、时区和异常时间处理仍是产品运行条件,串口显示本地时间也不代表底层时间转换可任意修改。 + +## 9. TLS 成功后 HTTP 0:非阻塞接收误断线 + +### 9.1 现象与定位 + +14:06 日志已出现: + +```text +WSS root CA parsed successfully +WSS TLS handshake and certificate/hostname verification passed: banban.api.talkingq.com:443 +recv data failed +WebSocket upgrade failed: HTTP 0 (0 means incomplete/invalid headers) +``` + +这次失败发生在读取 WebSocket Upgrade 响应时。`HTTP 0` 是程序内部“尚未解析出有效状态码”的值,不是服务器发送的 HTTP 状态码。 + +### 9.2 具体代码错误 + +原接收函数把 `error_number` 初始化为 `-1`。TLS 返回 `WANT_READ` 或 `WANT_WRITE` 时,代码直接 `break`,跳过后面的错误变量更新。循环结束后又检查 `error_number`,把残留的 `-1` 当成真实故障。 + +```c +/* 错误路径的简化表示 */ +int error_number = -1; +len = mbedtls_ssl_read(...); +if (len == WANT_READ || len == WANT_WRITE) + break; +/* 正常路径才有机会更新 error_number */ +/* 循环后把遗留的 -1 判成失败 */ +``` + +修复后的关键分支: + +```c +if (len == MBEDTLS_ERR_SSL_WANT_READ || + len == MBEDTLS_ERR_SSL_WANT_WRITE) { + error_number = 0; + break; +} +``` + +此时“本轮没有完整数据”允许上层继续等待;真正的 EOF、TLS 错误仍然产生错误状态。WebSocket 握手循环会继续接收、累计响应头并按期限退出。 + +### 9.3 为什么必须做回归测试 + +只测 HTTP 响应解析器不能覆盖这个问题,因为错误发生在“TLS 返回值 → 接收函数 → 握手等待循环”的衔接处。 + +新增测试提取实际接收函数与实际握手循环,配合真实 HTTP 解析器和可控 TLS 桩: + +- 修复前可重现 WANT 被错误当成失败。 +- 修复后支持 WANT_READ、WANT_WRITE、分片 101、响应头后的帧数据保留。 +- 仍正确处理 EOF、致命错误、超时、tick 回绕、空 TLS 上下文、错误 Accept。 + +后续 14:20 日志及用户反馈确认连接正常。这一修复只涉及 APP;前提是板端已经有补齐 ECDSA/RTC 的内核。 + +## 10. 识别“烧录包未生效”的经验 + +13:59 左右的一份日志仍输出旧格式 `WSS TLS connection failed: -9774`,而新 APP 已使用带失败阶段和十六进制错误码的格式,并增加了 CA 解析成功日志。 + +对实际 ZIP 内 `customer_app.bin` 的字符串检查显示:新包包含新日志格式,旧包包含旧格式。由此能够判断当时运行的 APP 不是预期新 APP,但不能仅凭该字符串进一步断言具体烧录操作错在哪里或内核是哪一版。 + +处理方式是明确新包绝对路径、核对包内镜像及 SHA-256,重新核查烧录工具实际选择的包和结果。 + +日志里的 `BUILD TIME:20260906093652` 是项目已有固定值,不能当作可靠构建身份。后续产品化可以增加真实 Git 提交号/构建标识,但本次未新增该机制。 + +## 11. 第一轮性能优化:NIST 快速模约减 + +对应提交:`3a0714c735f5eec3eaab19ec04f12ef26e8145c1`。 + +### 11.1 9.6 秒不是 socket 断线或固定延时 + +14:20 日志的关键时间为: + +```text +14:20:39.114 TCP connect success / socket break +14:20:48.752 TLS handshake and certificate/hostname verification passed +14:20:48.894 WebSocket upgrade verified: HTTP 101 +``` + +原 `socket break` 对应的是 C 代码退出 TCP 连接重试循环的 `break`,不是关闭 socket。已改成: + +```text +TCP connected; leaving connect loop +``` + +从 TCP 连接成功到 TLS 完成约 9.6 秒,而 HTTP Upgrade 只需随后约 0.1 秒。代码中没有固定“等 10 秒再继续”的逻辑,20 秒握手超时也不是要求每次等待 20 秒。 + +### 11.2 缺失的优化开关 + +当时已启用 ECDSA/ECDHE,但共享 mini profile 没有定义 `MBEDTLS_ECP_NIST_OPTIM`。SDK 的 NIST 曲线算术因此没有启用其专门的快速模约减函数。 + +加入: + +```c +#define MBEDTLS_ECP_NIST_OPTIM +``` + +这使 P-256、P-384、P-521 等曲线使用 SDK 已有的专用约减实现,例如 `ecp_mod_p256`、`ecp_mod_p384`、`ecp_mod_p521`。本次没有自行替换椭圆曲线公式或引入外部密码库。 + +### 11.3 为什么这个开关能加速 + +椭圆曲线点运算需要大量有限域乘法、平方和模约减。乘法会产生较大的中间数,必须把它约减到模数 `p` 范围内。 + +NIST 素数具有便于运算的特殊形式,例如: + +```text +P-256: p = 2^256 - 2^224 + 2^192 + 2^96 - 1 +P-384: p = 2^384 - 2^128 - 2^96 + 2^32 - 1 +P-521: p = 2^521 - 1 +``` + +以 P-521 为直观例子,在模 `2^521 - 1` 下有 `2^521 ≡ 1`。一个大数的高位部分可按这一关系折回低位,再做必要归一化。实际库实现会处理进位、边界和规范化,不能用一条简单表达式替代完整实现。 + +这种优化减少了通用大整数模运算开销,不改变曲线参数、证书身份或校验规则。当前证书链中多张 CA 证书使用 P-384,收益不仅作用于临时密钥交换,也作用于证书签名验证。 + +### 11.4 主机与板端验证 + +使用实际 SDK crypto/X.509 源码,在同一 Windows 主机验证同一证书链,各运行 20 次: + +| 配置 | 平均证书链验证时间 | +| --- | ---: | +| 关闭 NIST 优化 | 36.8 ms | +| 开启 NIST 优化 | 10.2 ms | + +主机算法测试约快 3.6 倍。之后板端完整 TLS 握手实测为 1820 ms,相比原约 9.6 秒减少约 81%。主机测的是证书校验,板端测的是整个 TLS 握手,两个倍率不要求相同。 + +开启 NIST 优化需要修改内核并重新编译。本次增加约 4 KiB 的打包内核镜像大小,具体镜像对比见第 17 节。 + +## 12. 握手计时方法与归因边界 + +原来只有“TCP 成功”和“TLS 完成”两条日志,无法区分证书校验、密钥交换与网络等待。 + +新增 `rws_tls_handshake_timed()`,通过 SDK 导出的 `mbedtls_ssl_handshake_step()` 驱动原有握手状态机,记录各阶段耗时。原 `mbedtls_ssl_handshake()` 内部也以 step 函数推进状态;此处没有重新实现 TLS 协议。 + +日志格式: + +```text +WSS TLS phase server certificate (3): elapsed=935 ms, calls=935 ms, retries=0 +WSS TLS handshake total=1455 ms, state=16, ret=0 +``` + +| 字段 | 解释 | 不能直接推断的内容 | +| --- | --- | --- | +| `elapsed` | 当前握手阶段经过的时间 | 阶段名不一定代表其中只有一种工作 | +| `calls` | 调用 SDK step 函数期间累计经过的时间 | 含任务调度,不是硬件 CPU 周期或纯运算时间 | +| `retries` | 返回 WANT_READ/WANT_WRITE 的次数 | 不是 TCP 丢包次数,也不是网络往返次数 | +| `total` | 本次 TLS 状态机开始到结束的时间 | 不包含此前 DNS/TCP,也不包含后续 HTTP Upgrade | +| `state=16` | 此 SDK 的 `MBEDTLS_SSL_HANDSHAKE_OVER` | 数值依赖当前 SDK,不能跨版本套用 | + +设备系统 tick 为 5 ms,统计按无符号 tick 差计算,再乘以 5 转成毫秒。无符号差值也用于覆盖 tick 回绕场景。 + +WANT 状态按原策略等待 10 ms,正常状态推进不增加睡眠。阶段日志与串口输出、调度会产生少量开销;总耗时不必精确等于所有打印阶段之和。 + +当前超时参数: + +| 环节 | 设定 | +| --- | --- | +| TLS 发送重试预算 | 1000 ticks,约 5 秒 | +| TLS 握手预算 | 4000 ticks,约 20 秒 | +| HTTP Upgrade 等待预算 | 2000 ticks,约 10 秒 | +| 业务线程等待连接结果 | 45000 ms | + +这些是循环或等待点上的预算,不是保证底层 DNS/TCP/密码函数可被任意时刻强制中断的实时截止期限。不能把超时值改小当作运算提速,否则可能只是让慢网络更容易失败。 + +## 13. 第二轮性能优化:完整握手优先 X25519 + +对应提交:`551a7bb1e657c12f45ac0a1f2ca851625723a63d`。 + +### 13.1 发现默认曲线顺序的影响 + +SDK 的曲线列表默认以较大的曲线排在前面,包括 P-521,然后才到 P-384、P-256,X25519 较靠后。 + +采用固件根 CA、TLS 1.2 和严格证书/域名验证,通过主机对后台做独立完整握手探测: + +| ClientHello 曲线顺序 | 后台选择 | +| --- | --- | +| 模拟 SDK 原顺序 | P-521 | +| X25519 优先 | X25519 | +| P-256 优先 | P-256 | +| 从最终固件数组读取的新顺序 | X25519 | + +这证明当前后台能够配合客户端优先级使用更适合该 MCU 的曲线。服务器未来更换 TLS 配置后是否仍按相同规则选择,需要重新验证。 + +### 13.2 最终配置及实现方式 + +新顺序优先为: + +```text +X25519 → P-256 → P-384 → P-521 → 其余原已启用曲线 +``` + +其他原已启用曲线保留作为兼容回退,不修改全局密码套件列表。 + +SDK 没有向 APP 导出 `mbedtls_ssl_conf_curves()` 的 setter,因此使用该函数本来执行的同等配置字段赋值: + +```c +ssl->ssl_conf.curve_list = rws_tls_preferred_curves; +``` + +数组为静态存储,满足 TLS 配置生命周期要求;赋值发生在 `mbedtls_ssl_config_defaults()` 之后、`mbedtls_ssl_setup()` 之前。ABI 测试覆盖此字段及协商诊断所访问的结构体。 + +新增日志: + +```text +WSS TLS full handshake: prefer X25519, P256, P384, P521 +WSS TLS negotiated ECDHE group: 9 (X25519=9, P256=3, P384=4, P521=5) +``` + +第一条只表示配置偏好,第二条才表示实际解析到的协商结果。这里的 9/3/4/5 是 mbedTLS 内部枚举,不是 TLS 协议线上 NamedGroup 编号;例如 X25519 的 TLS 编号是 29,两者不能混淆。 + +### 13.3 主机新建 ECDH 基准 + +使用真实 SDK 算法,每轮重新生成客户端临时密钥并计算共享密钥,独立验证双方共享结果一致。各曲线 20 次: + +| 曲线 | 平均客户端生成密钥 + 共享密钥运算 | 测试额外峰值堆 | +| --- | ---: | ---: | +| X25519 | 1.55 ms | 1144 字节 | +| P-256 | 1.90 ms | 3688 字节 | +| P-384 | 3.40 ms | 4808 字节 | +| P-521 | 5.15 ms | 6376 字节 | + +峰值堆包含测试对端共享结果校验阶段的分配,不是板端完整 TLS 的峰值内存。测试使用确定性测试熵构造可重复输入,限于主机测试程序;固件继续使用其硬件熵与 CTR_DRBG 路径。 + +### 13.4 最新板端验证:完整握手 1455 ms + +用户补充的 15:52 日志从冷启动、联网到首次按键连接,出现: + +```text +WSS TLS negotiated ECDHE group: 9 (X25519=9, P256=3, P384=4, P521=5) +WSS TLS phase server certificate (3): elapsed=935 ms, calls=935 ms, retries=0 +WSS TLS phase client key exchange (8): elapsed=135 ms, calls=135 ms, retries=0 +WSS TLS handshake total=1455 ms, state=16, ret=0 +WSS TLS handshake and certificate/hostname verification passed: banban.api.talkingq.com:443 +WebSocket upgrade verified: HTTP 101 +ws connect okay +``` + +可以确认: + +- 新 APP 已生效,实际协商到 X25519。 +- 执行了证书校验和客户端密钥交换等完整握手阶段。 +- TLS 验证通过,WebSocket Upgrade 成功。 +- 客户端密钥交换从 445 ms 降到 135 ms,减少 310 ms,约减少 69.7%,该阶段约快 3.3 倍。 +- TLS 总耗时从 1820 ms 降到 1455 ms,减少 365 ms,约减少 20.1%。 + +前一版板端没有记录实际曲线名称,所以“前一版为 P-521”的依据是 SDK 默认顺序和主机对后台的复现;最新板端 X25519 则有直接协商日志证据。 + +### 13.5 运算窗口调整为何没有采用 + +还比较了 `MBEDTLS_ECP_WINDOW_SIZE` 的 4、5、6。此参数影响点乘预计算表大小,窗口增大可能减少部分运算,但预计算和分配也有成本。 + +| 窗口 | 同一证书链平均校验 | 测试峰值分配 | +| --- | ---: | ---: | +| 4 | 10.35 ms | 11913 字节 | +| 5 | 10.20 ms | 16009 字节 | +| 6 | 10.45 ms | 18697 字节 | + +收益不稳定,内存开销增加,因此固件保留默认 window=4。参数更大并不保证一次性完整握手更快。 + +## 14. 各种密码算法分别负责什么 + +### 14.1 ECDSA:验证“是谁签的” + +ECDSA 是椭圆曲线数字签名算法。本项目用它验证证书链以及服务器临时密钥参数上的签名。 + +简化验证关系如下,实际实现还要验证输入、曲线点、数值范围和错误条件: + +```text +已知:签名 (r, s)、消息摘要 e、公钥 Q、基点 G、子群阶 n +w = s^(-1) mod n +u1 = e × w mod n +u2 = r × w mod n +R = u1 × G + u2 × Q +验证 R 的横坐标 mod n 是否等于 r +``` + +这个过程中有大整数运算、求逆和椭圆曲线点乘,解释了为什么低功耗 MCU 上证书验证会有明显成本。 + +证书中的公钥曲线、证书的签名算法、TLS 临时密钥交换曲线是三个不同概念。例如当前叶证书公钥为 P-256,但证书由上级 CA 使用 ECDSA/SHA-384 签名;TLS 临时密钥现在可以使用 X25519。 + +### 14.2 ECDHE:双方协商临时共享秘密 + +ECDHE 是临时椭圆曲线 Diffie-Hellman。简化表示为: + +```text +客户端临时私钥 a,公钥 A = aG +服务器临时私钥 b,公钥 B = bG +客户端计算 aB,服务器计算 bA,得到同一共享秘密 +``` + +共享秘密再结合 TLS 随机数和派生过程得到记录层密钥,不是直接把某个公钥当作 AES 密钥。临时密钥交换可提供前向保密性质,前提包括正确随机数、临时私钥管理和实际安全实现。 + +本次始终保持每次新连接的完整临时密钥交换,没有通过固定私钥或复用临时密钥来提速。 + +### 14.3 X25519:适合高效密钥交换的标准函数 + +X25519 基于 Curve25519 的 Montgomery 曲线,底层素数为: + +```text +p = 2^255 - 19 +曲线常数 A = 486662 +``` + +它采用规定的标量处理和基于 Montgomery ladder 的计算方式进行密钥交换。这里描述算法背景,实际代码使用 SDK 自带实现,并非本次自行重写;也没有因此宣称完成了独立侧信道安全审计。 + +X25519 通常提供约 128 位安全强度。P-521 的理论强度更高、运算量也更大;本服务的叶证书 P-256 本身约为 128 位安全强度,不能根据 AES-256 或 P-521 单一名称就断言整个协议具备 256 位综合安全强度。 + +本次在标准广泛使用的 X25519 与当前业务身份体系之间做性能选择,保留服务器证书、域名、日期和握手签名校验。 + +### 14.4 AES-GCM:加密和验证业务数据完整性 + +后台探测实际协商的 TLS 1.2 套件为: + +```text +TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 +OpenSSL 名称:ECDHE-ECDSA-AES256-GCM-SHA384 +``` + +| 名称组成 | 职责 | +| --- | --- | +| ECDHE | 临时密钥交换 | +| ECDSA | 服务器身份相关签名验证 | +| AES-256-GCM | 记录层对称加密和认证标签 | +| SHA-384 | 该 TLS 1.2 套件的 PRF/握手相关哈希选择 | + +GCM 结合计数器模式加密与 GHASH 认证,属于 AEAD。它主要作用于握手后大量业务数据,不能把证书校验的 935 ms 全部归因于 AES。 + +套件名不规定 ECDHE 必须用 P-521,也不代表每张证书都由 SHA-384 签名。实际探测中,证书链为 ECDSA/SHA-384,服务器握手参数签名显示 ECDSA/P-256/SHA-256;这些并不矛盾。 + +固件没有新增“只允许上述一个套件”的固定白名单。上述套件是本次后台实际协商结果,服务器配置变动后应重新观察。 + +### 14.5 CTR_DRBG 与随机数 + +固件使用 mbedTLS CTR_DRBG,并通过 SDK 硬件熵接口播种。随机性用于 TLS、临时密钥以及 WebSocket 握手 nonce 等流程。 + +本次优化没有关闭随机数、改成固定随机种子,也没有用主机 benchmark 的确定性测试熵替换固件随机源。 + +### 14.6 根信任与交叉签名 + +根 CA 是设备预先信任的锚;链条中的其他证书需要沿签发关系验证到它。根证书自签名的存在不是“第一次信任它”的理由,信任来自设备内置的可信配置。 + +Root YE 交叉签名证书使其能够连接到设备已信任的 ISRG Root X2。若未来希望缩短验证链,不能直接删掉中间证书或把任意下载到的证书当作根;需要协调可信根部署、完整链验证和证书生命周期。 + +## 15. 最新耗时归因:设备端还是服务端 + +### 15.1 两轮板端阶段对比 + +| 阶段 | NIST 版,14:38 | X25519 版,15:52 | 解释 | +| --- | ---: | ---: | --- | +| ClientHello | 5 ms | 5 ms | 本地构造/发送 | +| 等待 ServerHello | 50 ms | 40 ms | 网络、服务端处理与本地轮询 | +| 服务器证书校验 | 965 ms | **935 ms** | SDK 内部证书处理为主 | +| ServerKeyExchange | 160 ms | 165 ms | 验证握手签名等;最新 `calls=160 ms` | +| ClientKeyExchange | **445 ms** | **135 ms** | 本地临时密钥与共享密钥运算,主要优化目标 | +| 后续等待阶段 12 | 120 ms | 90 ms | 服务端后续消息、网络与轮询 | +| 其他阶段/记录开销 | 约 75 ms | 约 85 ms | 差额项,含其他阶段、日志、调度等 | +| **TLS 总计** | **1820 ms** | **1455 ms** | 设备内部统计 | + +差额项是总计扣除表中单列项目,并不等同于独立测量出的“串口开销”。两次证书校验相差 30 ms,也不能算作 X25519 对证书验证的优化收益,因为该阶段算法与证书链未改。 + +当前证书阶段占 TLS 总时间: + +```text +935 / 1455 ≈ 64.3% +``` + +证书、服务器密钥交换、客户端密钥交换三个阶段的 `calls` 合计约 1230 ms,占总时间约 84.5%。主要时间仍在 SDK 调用内部,因此当前连接瓶颈主要是设备端处理,而不是等待服务器响应。 + +必须保留的归因边界:`calls` 含调度时间;没有 CPU 周期/占用率采样,不能把这 1230 ms 全称为纯密码运算。网络等待阶段也不能直接拆成“运营商耗时”和“服务器 CPU 耗时”。 + +### 15.2 用户最关心的按键到 WebSocket 成功 + +| 时间点/指标 | NIST 版 | X25519 版 | +| --- | --- | --- | +| 按键 | 14:38:46.455 | 15:52:25.453 | +| 进入业务连接函数 | 14:38:46.605 | 15:52:25.645 | +| TCP 成功 | 14:38:46.731 | 15:52:25.788 | +| WebSocket 101 | 14:38:48.683 | 15:52:27.389 | +| **按键 → 101** | **2.228 秒** | **1.936 秒** | +| 连接函数入口 → 101 | 2.078 秒 | 1.744 秒 | + +按键到 101 减少约 292 ms,即约 13.1%。它与 TLS 内部减少的 365 ms 不完全相同,是因为按键调度、DNS/TCP、HTTP Upgrade 以及日志批次时间也在变化。 + +串口接收时间可能受缓冲和分片影响,设备内部 tick 更适合比较 TLS 阶段;按键到 101 的端到端指标仍应在同一测试环境多次测量。 + +### 15.3 提示音不属于本轮目标耗时 + +最新日志在 15:52:27.389 连接成功,15:52:30.624 左右提示音结束并开始录音,另有约 3.24 秒。 + +这是连接后的音频业务等待,不应计入 TLS 握手。用户已明确优先优化“按键到 WebSocket 成功”,本次没有修改提示音。 + +### 15.4 其他日志现象的正确理解 + +- 14:38 的 `tts_error_set_speech1` 是上一轮业务等待触发的主动断开,与随后完整握手成功不是同一个故障阶段。缺少那一轮完整请求/响应上下文,不能据此直接归因后端慢。 +- `frames:500, speech:0` 对应约 10 秒录音未识别到语音后停止,属于 VAD/录音链路判断。如用户当时有说话,应查音频采集和 VAD。 +- 最新日志先有 `CFUN0`、PMIC 关机,再出现 `cold power on` 和 `long press, do poweron!!`。该片段本身不足以认定是 TLS 引起的异常重启。 +- 反复出现的 SDK 启动提示、音频 `UNDERRUN` 不能仅凭字面与 TLS 因果关联;需要相应模块的上下文和功能表现。 + +## 16. Git 提交记录及职责划分 + +旧板基础分支为 `legacy-board`,WSS 开发分支为 `legacy-board-wss`。GNSS 绕过和默认音量不是 WSS 提交新增的行为,而是分支继承的基线。 + +| 提交 | 日期 | 内容 | 对编译/运行的主要影响 | +| --- | --- | --- | --- | +| `f283223` | 2026-09-15 | 无 GNSS 旧板适配 | 基础硬件启动/定位行为调整 | +| `4b56595` | 2026-09-15 | 默认音量 100 | 旧板 WSS 分支的基线 | +| `3e463f5` | 2026-09-16 | 首轮 WSS 接入 | 地址迁移、严格 TLS、Upgrade 验证、收发/任务处理、测试与文档 | +| `5c3e7ee` | 2026-09-16 | ECC/RTC 与接收重试修复 | 共享 profile、ECDSA/GCM、日期来源、ABI 检查、WANT 误断线修复;涉及内核 | +| `3a0714c` | 2026-09-16 | NIST 加速与 TLS 阶段计时 | 内核运算优化、APP 计时、测试基准 | +| `551a7bb` | 2026-09-16 | X25519 优先的完整握手 | APP 曲线列表、协商日志、ABI 扩展、曲线探测与算法基准 | + +四个 WSS 提交的完整标识与标题: + +```text +3e463f57b69732ced0562e8e52915cc1566c4b6c +Add verified WSS transport for legacy boards + +5c3e7eee6dc3bbf6d514af6bb93465bc81d6c952 +Fix legacy WSS certificate support and receive retries + +3a0714c735f5eec3eaab19ec04f12ef26e8145c1 +Accelerate legacy WSS elliptic-curve operations and time TLS phases + +551a7bb1e657c12f45ac0a1f2ca851625723a63d +Prefer X25519 for legacy WSS full handshakes +``` + +这些提交在本会话中完成的是本地提交,没有执行远端 push。无关的 `docs/EC800_AITALK_KEY-V1.01.pdf` 未加入这些提交。 + +提交时间、包生成时间和串口时间并非一个统一时钟,也不是逐一对应的版本号。可靠定位应结合 Git 标识、包哈希、镜像内容和新增日志,而不是只比时间戳。 + +## 17. 固件包版本、镜像变化与回退 + +以下均为本工作区已生成并核对的包;不是根据提交号推测的包体大小。文件路径根目录均为 `D:\banban\project\nfc_gnss`。 + +| 包所在子目录/文件 | ZIP 字节数 | cp.bin 字节数 | customer_app.bin 字节数 | 状态 | +| --- | ---: | ---: | ---: | --- | +| `artifacts/wss/EG800AKCN_11LG-legacy-wss.zip` | 6526785 | 2539520 | 205956 | 首轮旧包,内核缺 ECDSA;仅供历史对照 | +| `artifacts/wss/ecc-fix/EG800AKCN_11LG-legacy-wss-ecc.zip` | 6537607 | 2543616 | 206180 | 已补 ECC/RTC,但仍有接收误断线;仅供历史对照 | +| `artifacts/wss/recv-fix/EG800AKCN_11LG-legacy-wss-recv.zip` | 6537490 | 2543616 | 206060 | 已验证功能,TLS 约 9.6 秒 | +| `artifacts/wss/tls-speed/EG800AKCN_11LG-legacy-wss-fast.zip` | 6544532 | 2547712 | 206580 | 板端 TLS 1820 ms | +| `artifacts/wss/full-handshake/EG800AKCN_11LG-legacy-wss-x25519.zip` | 6544840 | 2547712 | 206780 | 最新板端 TLS 1455 ms、X25519、HTTP 101 | + +具体影响: + +- ECC/RTC 内核镜像相对首轮 WSS 包增加 4096 字节。 +- NIST 加速内核相对 ECC/RTC 包再增加 4096 字节。 +- X25519 包与 NIST 包的 `cp.bin` 已逐字节核对一致,APP 增加 200 字节。 +- 上述是打包后的镜像大小差,不等于某一算法源码编译后精确占用量;对齐、压缩和链接布局也会影响结果。 + +最新包: + +[EG800AKCN_11LG-legacy-wss-x25519.zip](D:/banban/project/nfc_gnss/artifacts/wss/full-handshake/EG800AKCN_11LG-legacy-wss-x25519.zip) + +标准构建输出也为相同内容: + +[target/EG800AKCN_11LG/EG800AKCN_11LG.zip](D:/banban/project/nfc_gnss/target/EG800AKCN_11LG/EG800AKCN_11LG.zip) + +各 ZIP 的 SHA-256: + +```text +初版 WSS: +87747b0cc6c7223e5509e381fda8920d475aea5ba41016ca6d97e930e1a334ec + +ECC/RTC: +f8db36b72838f869d8529715e34485509f3805899945d75fa0aeae072ae11956 + +接收修复: +d3fd2894dfffdb4aec915e2b53409d0454d6c7691200198efb5990b0bc489d9b + +NIST 加速: +8ca26df0e5efbd2e21db7c7aef9356ac129f086dacb61a351dc82f2499c7b356 + +X25519 最新: +fe28313cb43f7cc3fc05ed59431b1c0239257a867e3d65d07bfd32e4945a7fb1 +``` + +最新包内镜像 SHA-256: + +```text +cp.bin: +4bfbf8a01a05c16e983fb854c057b9925f66c713cea80107be943b6e5746915f + +customer_app.bin: +7b82a10cab51d8bbd75a62de4876d9b2c51b225930a43376940ab337a0c30a27 +``` + +构建包、探测 JSON、公共证书和日志位于本地 `artifacts/wss`,该目录通过 `.gitignore` 排除绝大多数生成物,Git 保留说明文件等指定内容。代码提交不等于已经把 ZIP 或本机证据文件同步给其他人。 + +## 18. 构建、打包与实际烧录的区别 + +### 18.1 全新检出的完整构建 + +在本工作区根目录依次执行: + +```powershell +Set-Location 'D:\banban\project\nfc_gnss' +.\build.bat kernel +.\build.bat app +.\build.bat firmware +``` + +内核需要可用的 ARMCC 工具链与合法可用的许可。已有构建环境中已经完成上述构建。 + +### 18.2 已有匹配内核时的 APP 改动 + +在当前已经构建 NIST 加速内核的工作区,接收逻辑或 X25519 APP 配置改动可以执行: + +```powershell +.\build.bat app +.\build.bat firmware +``` + +前提是打包使用的内核确实与 APP 的共享配置相匹配。不能把这一结论泛化为“以后 WSS 改动永远不用编译内核”。 + +### 18.3 APP-only 编译不等于 APP-only 烧录 + +`build.bat firmware` 生成的内层 ZIP 仍是多分区完整包。最新 `download.json` 包含内核、APP、文件系统及其他固件分区,还包含 NVM/FOTA 参数等擦除指令,`factory_a` 有 `productionOnly` 条件。 + +因此: + +- “这次只改 APP”描述源码和编译范围。 +- “这次只刷 APP”必须由下载清单/工具选择明确保证。 +- 使用本文提供的完整 ZIP,应按完整包理解;不能假设它只更新 `customer_app` 或一定保留所有用户配置。 +- 旧板绕过 GNSS 运行路径,不代表完整包里不再包含 GNSS 分区镜像。 + +实际烧录结果应以工具执行记录与清单为准。本文没有执行设备烧录,板端日志由用户提供。 + +### 18.4 构建验证不能只看批处理退出码 + +SDK 外层批处理的退出状态可能不能充分反映内部失败。验证同时检查: + +- APP/内核 ELF 或 AXF、BIN 是否正确生成。 +- ZIP CRC。 +- ZIP 中 `cp.bin`、`customer_app.bin` 与本次构建逐字节一致。 +- 必需算法、时间与诊断符号。 +- GNSS 绕过入口反汇编。 +- 固件默认 URL 与必要日志字符串。 + +内核构建会改写部分跟踪的生成输入,例如 `diagDB.o` 和链接反馈文件。此前构建对这些文件先备份、生成后另存、最后恢复原字节,避免把构建副产物混入功能提交。 + +## 19. 测试体系、结果与可复现命令 + +### 19.1 测试覆盖分层 + +| 层级 | 工具 | 覆盖内容 | 结果 | +| --- | --- | --- | --- | +| URL/HTTP 纯逻辑 | `tools/test_wss.c` | 地址迁移、非法 URL、端口、边界、每个响应分片边界、101/Accept/头字段 | 通过 | +| TLS 写入/对象取消 | `tools/test_wss_io.py` | 实际函数提取,短写、WANT、EOF、错误、超时、tick 回绕、worker 释放 | 通过 | +| TLS 接收 + Upgrade | `tools/test_wss_receive.py` | 实际接收/等待函数和解析器组合,复现并修复误断线 | 通过 | +| 分步握手控制 | `tools/test_wss_handshake.py` | 正常推进、WANT、致命错误、截止预算、tick 回绕、完成状态、协商日志分支 | 通过 | +| ARMCC/GCC ABI | `tools/check_mbedtls_abi.py` | 实际头文件结构大小、字段偏移和功能宏 | 通过 | +| SDK 算法与证书 | `tools/test_mbedtls_cert.py` / `.c` | 根 CA、证书链、错误域名/不可信根/日期、AES-GCM 向量、ECDH 双方一致与释放 | 通过 | +| 后台 WSS 探测 | `tools/probe_talkingq_wss.ps1` | 系统信任、TLS、HTTP 101 和 Accept | 443 通过 | +| 固件根 CA 单独信任 | `tools/probe_wss_root.py` | 不依赖 OS 根库或中间证书下载,含错误域名/空信任库负例 | 通过 | +| 后台曲线选择 | `tools/probe_wss_groups.py` | 原顺序及新固件顺序的实际完整握手 | 新顺序选择 X25519 | +| 包完整性 | `tools/verify_wss_package.py` | ZIP、镜像一致性、内核能力、GNSS 绕过、关键日志 | 通过 | +| 硬件运行 | 用户板端日志 | TLS、协商曲线、HTTP 101、录音初始化和真实耗时 | X25519 版本已通过上述项目 | + +主机 TLS 桩测试不等于完整蜂窝网络端到端测试。实际 SDK 算法主机测试使用真实算法源码,但分配器、时钟、日志和 CPU 架构与设备不同。所有结论应按对应证据层级使用。 + +### 19.2 常用执行方式 + +```powershell +Set-Location 'D:\banban\project\nfc_gnss' +.\tools\test_wss.cmd +.\ql-cross-tool\win32\owtoolchain\Python\python.exe tools\check_mbedtls_abi.py +.\ql-cross-tool\win32\owtoolchain\Python\python.exe tools\verify_wss_package.py +``` + +算法测试需在 Visual Studio 开发者命令行中执行,使 `cl` 可用: + +```bat +ql-cross-tool\win32\owtoolchain\Python\python.exe tools\test_mbedtls_cert.py +ql-cross-tool\win32\owtoolchain\Python\python.exe tools\test_mbedtls_cert.py --compare-nist +ql-cross-tool\win32\owtoolchain\Python\python.exe tools\test_mbedtls_cert.py --compare-windows +``` + +后台探测: + +```powershell +powershell.exe -NoProfile -ExecutionPolicy Bypass -File tools\probe_talkingq_wss.ps1 +.\ql-cross-tool\win32\owtoolchain\Python\python.exe tools\probe_wss_root.py +.\ql-cross-tool\win32\owtoolchain\Python\python.exe tools\probe_wss_groups.py +``` + +`probe_wss_groups.py` 当前使用 Git for Windows 自带的 OpenSSL 路径。跨电脑使用应核对该路径。证书测试默认使用本地已捕获的证书链,未来叶证书过期后需要更新测试输入,不能通过关闭日期验证使旧样本继续“通过”。 + +包校验器针对当前构建的能力与符号要求,不是所有历史版本的通用校验器。当前 APP 与历史包不同,直接传入历史包出现镜像不一致属于预期,应切换到对应代码/构建再比较,或只做独立历史哈希校验。 + +## 20. 解决后的影响与兼容性 + +### 20.1 安全行为 + +| 方面 | 修改后的行为 | 运维影响 | +| --- | --- | --- | +| WebSocket 传输 | 通过 TLS 加密与完整性保护 | 运营商/网络须允许实际 TLS 入口 | +| 服务器身份 | 根 CA、证书链、日期、域名、握手签名验证 | 证书或时间异常会明确失败 | +| SNI | 发送业务域名 | 支持按域名选择证书的 TLS 入口 | +| 客户端身份 | 原应用层消息 | 不需要给每台设备新增 TLS 客户端证书 | +| 协议降级 | 不自动从 WSS 降回 WS | 不能用错误端口/路径“凑合连接” | +| 证书续期 | 依赖可构建到内置根的有效链 | 后台换根或改链需重新评估 | +| 吊销检查 | 未增加 OCSP/CRL 查询 | 不能宣称已实现在线证书吊销检查 | + +共享 mini profile 为兼容原 SDK 保留了部分历史算法/协议宏;WSS 单独设置 TLS 1.2 下限。不能因为 WSS 达到 TLS 1.2,就宣称系统所有 TLS 用户都已收紧到同一策略。也不能把本轮修复视为对整个厂商 TLS 栈的完整安全审计。 + +### 20.2 功能行为 + +- 默认 URL 与已知旧地址的读取迁移会影响实际连接目标。 +- 服务器证书或系统时间不正确时,设备会连接失败,而不是跳过验证。 +- WebSocket 101/Accept 校验更严格,错误反向代理响应会被拒绝。 +- 设备鉴权字段、业务消息、提示音和录音时序保持原逻辑。 +- 用户无 GNSS 旧板逻辑和默认音量 100 继续保留。 +- TLS 成功后的音频业务超时依然需要按业务链路分析,不能因传输层升级而认为业务超时问题已经全部解决。 + +### 20.3 性能、内存与功耗 + +- 全新 WSS 连接比明文 WS 多了 TLS 握手工作;性能优化缩短了这部分,但没有消除协议本身的成本。 +- NIST 优化增加部分内核代码体积;X25519 APP 增量较小,算法基准中的密钥交换峰值分配更低。 +- worker 栈增加到 16 KiB,需纳入整体内存预算。 +- 运算时间减少可能减少相应 CPU 活跃时间,但本次没有电流波形或能耗积分测试,不给出续航提升数值。 +- 没有引入预连接或保活策略改变来换取响应速度,因此没有通过新增常驻连接有意扩大待机功耗。 + +### 20.4 可维护性 + +- TLS 功能由共享配置集中管理,降低 APP/内核独立修改造成的风险。 +- 日志区分 CA 解析、TCP、TLS 阶段、HTTP Upgrade,定位精度提高。 +- 新增 SDK 内部结构读取用于曲线诊断,要求升级 SDK 时重新检查 `ssl_internal.h` 与 ABI,不能只复制业务 APP。 +- 协商优先级只改变当前 WSS 的配置,不通过修改 SDK 全局默认曲线顺序影响其他连接。 +- 包哈希、镜像一致性与明确的历史包路径,减少旧包混用。 + +## 21. 现有边界、尚未完成的验证与建议补充 + +以下是根据当前源码和本轮证据列出的边界,不表示它们都已经造成现场故障。 + +### 21.1 配置输入长度 + +URL 解析器有输出容量和字符检查,但原 `hal_os_set_talkingq_url()` 的 64 字节临时缓冲区仍使用 `strcpy`,共享属性处理也存在相似复制方式。**解析阶段的边界检查不能替代保存入口的边界检查。** + +后续建议统一在属性接收和 KV 保存前验证类型、长度及 URL 合法性,拒绝超过存储容量的配置。此项没有在本轮 WSS 提交中额外修改,避免把已完成范围描述为覆盖了全部配置输入安全。 + +### 21.2 运行稳定性与业务验收 + +目前已有多次板端建连和用户功能反馈,最新片段确认 TLS、HTTP 101、发送鉴权消息和录音启动。仍建议保留正式验收项: + +- 服务端明确记录设备鉴权成功,而不只看设备发送了身份。 +- 长时间音频收发、连续多轮对话、断网重连、服务器重启、弱网。 +- 多次冷启动与休眠/唤醒后的完整握手。 +- 运行中堆峰值、栈水位、对象释放和长期内存趋势。 +- 不同运营商/网络状态的延迟分布。 + +不应使用一次成功日志替代上述稳定性结论。 + +### 21.3 证书与时间生命周期 + +要监控叶证书续期、链条变化和设备时钟。相同域名不代表证书永远由同一根签发;只有一张根 CA 的信任集有利于范围明确,也意味着服务端换根时需要设备更新策略。 + +当前主机测试样本有明确有效期,过期后应更换样本。固件长期运行的正确做法是正常验证新证书,而不是绕过日期校验。 + +### 21.4 当前耗时还可优化到什么程度 + +在“不提前建连、不使用会话恢复、每次完整握手”的约束下,优先级建议如下: + +1. **证书链处理**:当前 935 ms,占约 64%,是最大剩余项。可以评估是否有重复解析/不必要工作,以及经过基准验证的 SDK 运算优化。 +2. **后台链条设计**:与后台/证书运维一起评估更短且可验证的链。前提是明确可信根分发、兼容性和轮换方案,不能只是删中间证书。 +3. **网络等待策略**:当前两个主要等待阶段合计约 130 ms,空间小于证书运算。可测量 readiness 通知与轮询差异,但要同时考虑 CPU 占用和 RTOS 调度。 +4. **日志开销**:当前分阶段日志便于诊断。产品版本可评估降低输出量的收益,但应保留必要总计和失败诊断,并做同条件对照。 +5. **更深层编译/硬件加速**:仅在明确硬件能力、SDK 适配和实测数据后考虑,不直接修改全局频率或重写密码算法以追求数字。 + +不能根据 935 ms 证书阶段直接承诺“必定还能降到几百毫秒”,更不能通过关闭证书验证来满足耗时目标。 + +### 21.5 会话恢复探测作为补充资料 + +在用户明确最终策略之前,做过一次主机 TLS 1.2 会话恢复探测:启用 Session Ticket 时,后台提供 300 秒 lifetime hint,后续连接确实复用会话;禁用 Ticket 的那组测试未观察到 Session ID 复用。 + +主机样本中完整握手约 36.8 ms,Ticket 恢复约 14.7/17.1 ms,均完成 101。该结论仅反映当时主机与服务器组合,不能换算为设备效果,也不能推断后台所有节点永久具有同一配置。 + +用户选择仅优化完整握手后,没有将这条路线加入固件。当前共享配置未启用 `MBEDTLS_SSL_SESSION_TICKETS`,业务代码未增加 session 保存/恢复逻辑。该探测不是最新 1455 ms 的来源。 + +### 21.6 建议的下一轮性能记录方式 + +采用同一块板、同一固件、同一运营商环境,每个版本至少记录一组多次完整握手样本,区分冷启动首次连接与同次开机的后续新连接。 + +每条记录建议包含: + +| 字段 | 用途 | +| --- | --- | +| Git 提交号、固件 ZIP SHA-256 | 证明版本 | +| 是否冷启动、数据网络是否已就绪 | 区分建连前置条件 | +| 按键、TCP、TLS、101 时间 | 端到端与分层耗时 | +| 实际 ECDHE group | 确认优化确实被协商使用 | +| 各阶段 elapsed/calls/retries | 归因运算、调度和等待 | +| 信号/网络信息与成功率 | 解释离群样本 | +| 堆峰值、栈水位 | 验证空间代价 | + +统计中位数、P95、最大值和失败率,比只比较一次最快日志更适合作为产品验收依据。本次已有数据足以证明改动生效,但尚不足以形成上述统计分布。 + +## 22. 常见日志排障速查 + +| 现象 | 优先解释/检查 | +| --- | --- | +| `WSS trust anchor loaded` | 仅表示 CA 数据已加载,继续查解析结果 | +| `-9774` / `-0x262E` | 检查实际运行内核是否包含 ECDSA,以及是否刷到正确版本 | +| `WSS requires valid network/RTC time` | 检查 RTC/NITZ,不要关闭日期验证 | +| `getaddrinfo` 失败 | DNS、PDP、域名与白名单 | +| TCP 成功但 TLS 失败 | 端口协议、证书链、时间、算法、网络或 ABI;看具体阶段和错误码 | +| `socket break` | 旧日志表示退出连接循环;新日志已改名,不是断线 | +| TLS 验证成功但 `HTTP 404` | 当次 `/ws` 路由或反向代理配置问题 | +| `HTTP 0` | 尚未解析到有效状态码;检查前面的读错误、超时和响应完整性 | +| `HTTP 101` 但 Accept 不匹配 | Upgrade 响应不属于本次 Key,或代理/实现错误;必须拒绝 | +| `WSS TLS negotiated ECDHE group: 9` | 本次实际使用 X25519 | +| `ws connect okay` | WebSocket 连接层完成;仍应独立确认业务鉴权 | +| `tts_error_set_speech1` | 业务等待超时;需要对应请求/响应上下文 | +| `frames:500, speech:0` | 录音/VAD 未识别语音,不是 TLS 阶段耗时 | +| 日志仍为旧格式 | 核查工具选包、实际镜像、哈希及是否重启生效 | + +## 23. 关键源码与证据索引 + +以下链接指向本机工作区或用户提供的本地日志附件,便于复核;转交文档时应同时提供需要的文件,因为绝对路径不会自动复制内容。 + +### 23.1 主要实现 + +| 文件 | 职责 | +| --- | --- | +| [talkingq_wss.h](D:/banban/project/nfc_gnss/ql-application/threadx/interface/custom_app/inc/talkingq_wss.h) | 默认 URL 与缓冲区容量 | +| [talkingq_wss.c](D:/banban/project/nfc_gnss/ql-application/threadx/interface/custom_app/talkingq_wss.c) | URL 解析、历史地址识别 | +| [talkingq_root_ca.c](D:/banban/project/nfc_gnss/ql-application/threadx/interface/custom_app/talkingq_root_ca.c) | 内置信任根 | +| [hal.c](D:/banban/project/nfc_gnss/ql-application/threadx/interface/custom_app/lib/hal/hal.c) | KV 地址读取、保存与迁移 | +| [fota.c](D:/banban/project/nfc_gnss/ql-application/threadx/interface/custom_app/fota.c) | 原共享属性中的地址保存调用 | +| [ws_talkingq.c](D:/banban/project/nfc_gnss/ql-application/threadx/interface/custom_app/ws_talkingq.c) | 业务连接、回调和原身份鉴权 | +| [rws_socketpriv.c](D:/banban/project/nfc_gnss/ql-application/threadx/interface/custom_app/lib/librws/src/rws_socketpriv.c) | TLS 建连/收发、曲线策略、阶段计时、worker | +| [rws_socketpub.c](D:/banban/project/nfc_gnss/ql-application/threadx/interface/custom_app/lib/librws/src/rws_socketpub.c) | 取消连接和对象生命周期 | +| [rws_handshake.c](D:/banban/project/nfc_gnss/ql-application/threadx/interface/custom_app/lib/librws/src/rws_handshake.c) | HTTP 101/Accept 与分片响应验证 | +| [talkingq_mbedtls_config.h](D:/banban/project/nfc_gnss/ql-config/config/talkingq_mbedtls_config.h) | APP/内核共享 TLS profile、NIST 开关 | +| [内核 x509.c](D:/banban/project/nfc_gnss/ql-kernel/threadx/quec_mbedtls/x509.c) | 证书当前时间来源修复 | +| [内核 ecp_curves.c](D:/banban/project/nfc_gnss/ql-kernel/threadx/quec_mbedtls/ecp_curves.c) | SDK 原有 NIST 快速模约减实现 | +| [内核 ecp.c](D:/banban/project/nfc_gnss/ql-kernel/threadx/quec_mbedtls/ecp.c) | SDK 点乘、默认曲线顺序与窗口策略 | + +### 23.2 测试和包证据 + +| 文件 | 内容 | +| --- | --- | +| [test_wss.cmd](D:/banban/project/nfc_gnss/tools/test_wss.cmd) | 常用回归入口 | +| [check_mbedtls_abi.py](D:/banban/project/nfc_gnss/tools/check_mbedtls_abi.py) | 双编译器 ABI/宏校验 | +| [test_mbedtls_cert.c](D:/banban/project/nfc_gnss/tools/test_mbedtls_cert.c) | 算法、证书、ECDH 与内存基准 | +| [test_mbedtls_cert.py](D:/banban/project/nfc_gnss/tools/test_mbedtls_cert.py) | 主机 SDK 算法编译入口 | +| [probe_wss_groups.py](D:/banban/project/nfc_gnss/tools/probe_wss_groups.py) | 实际后台曲线协商探测 | +| [verify_wss_package.py](D:/banban/project/nfc_gnss/tools/verify_wss_package.py) | 当前构建与包一致性校验 | +| [443 复测证据](D:/banban/project/nfc_gnss/artifacts/wss/retest-443/server-probe.json) | TLS、证书信息和 HTTP 101 | +| [根 CA 单独验证证据](D:/banban/project/nfc_gnss/artifacts/wss/root-only-probe.json) | 固件根信任与负例结果 | +| [ABI 检查产物](D:/banban/project/nfc_gnss/artifacts/wss/ecc-fix/tls-abi.json) | 最新检查的实际结构大小和偏移 | +| [曲线探测证据](D:/banban/project/nfc_gnss/artifacts/wss/full-handshake/group-probe.json) | 原顺序与新固件顺序的协商结果 | +| [最新包校验记录](D:/banban/project/nfc_gnss/artifacts/wss/full-handshake/verification.json) | 包/镜像哈希、清单与静态校验 | +| [Session 探测记录](D:/banban/project/nfc_gnss/artifacts/wss/session-probe.json) | 未纳入固件的会话恢复路线探测 | + +部分报告是在新板端日志之前生成,其中 `hardware_test` 字段可能仍写“待上板”。这是生成时的历史状态;15:52 的新增板端结果以本文和下面的原始附件为准,不把后来的运行结果伪装成早期报告已经知道的事实。 + +### 23.3 用户板端日志来源 + +| 日志 | 用途 | +| --- | --- | +| [11:41 原始附件](C:/Users/talkingq/.codex/attachments/353f070d-8be2-435e-9774-5fa670c3eb96/pasted-text.txt) | 根 CA 解析失败调查 | +| [13:54 原始附件](C:/Users/talkingq/.codex/attachments/7aea2c62-ff1c-4905-a6a0-d9f9d2244872/pasted-text.txt) | 旧 APP 日志格式与包生效检查 | +| [14:06 原始附件](C:/Users/talkingq/.codex/attachments/2a56182d-f92b-409d-a1b7-3212af6ed0b3/pasted-text.txt) | TLS 通过后接收误断线 | +| 本会话 14:20 直接粘贴日志 | 约 9.6 秒 TLS 基线 | +| 本会话 14:38 直接粘贴日志 | NIST 版 1820 ms 与阶段耗时 | +| [15:52 X25519 原始附件](C:/Users/talkingq/.codex/attachments/b88fd282-bae0-44d5-9028-3b9a56a96530/pasted-text.txt) | 实际 group=9、TLS 1455 ms、HTTP 101 | + +为便于总结传播,本文未重复原始日志中的设备 IMEI、具体设备 ID、序列号或任何认证密钥;原始日志附件仍应按项目资料管理。 + +## 24. 交付状态 + +- 四个 WSS 功能提交已存在于本地 `legacy-board-wss`,最新为 `551a7bb`。 +- 最新完整包已生成并通过镜像/ZIP/符号校验。 +- 用户 15:52 日志已验证 X25519、完整 TLS 握手 1455 ms 和 HTTP 101。 +- 当前最大已观测连接耗时项为设备证书链处理,约 935 ms。 +- 本文是对既有实现、提交、测试和新增设备日志的总结,不包含新的固件功能改动。 +- 是否将本文另行提交或推送,属于后续文档发布操作;本次整理本身不改变既有固件包内容与 SHA-256。 diff --git a/docs/new_board_wss.md b/docs/new_board_wss.md new file mode 100644 index 0000000..4cc1b4e --- /dev/null +++ b/docs/new_board_wss.md @@ -0,0 +1,125 @@ +# 新板 main 分支 WSS 迁移说明 + +> 最新上板反馈(2026-09-16):用户确认将 MQTT 改为 banban.api.talkingq.com:1883 后已连接成功。该反馈支持域名访问方式适配新板受限 eSIM 的判断;未提供本次成功日志,本文不据此宣称 GNSS、全部业务及 WSS 性能均已验收。 + +更新日期:2026-09-16。适用工作区:`D:\banban\project\nfc_gnss`,分支:`main`。 + +## 1. 迁移范围 + +以原主分支 `2746cc3d4ebbd90f8fa0c1e68db93b199b297714` 的新板代码为基础,迁入旧板已经完成联调的 WSS 实现、故障修复、完整握手优化与测试工具。新板仍使用自身的 GNSS 检测和定位任务。 + +| 旧板来源提交 | 迁入内容 | +| --- | --- | +| `3e463f5` | WSS 地址解析、可信根 CA、服务器证书及域名验证、WebSocket Upgrade 校验 | +| `5c3e7ee` | 内核 ECDSA/GCM 能力、APP 与内核共享配置、RTC 证书日期校验、TLS 接收重试修复 | +| `3a0714c` | NIST 曲线模约减加速、握手阶段计时、连接循环日志修正 | +| `551a7bb` | 完整握手优先协商 X25519,保留原有其他曲线作为回退 | +| `54bf67c` | 旧板联调过程、算法说明与实测总结,作为历史资料保留 | + +这些提交的修改迁入工作区,不直接合并旧板分支。旧板关闭 GNSS 的提交 `f283223` 和音量改为 100 的提交 `4b56595` 未迁入。 + +## 2. 新板硬件与业务行为 + +- 内核 `quec_get_gnssid_task()` 仍创建 GNSS 型号识别任务 `quec_get_ocname_by_gnss_task`。 +- APP `app_gnss_init()` 仍创建定位任务 `quec_gnss_test`,`set_gnss_mode()` 仍更新定位模式。 +- `audio.c` 与原主分支一致:音量优先读取设备保存值,读取失败时回退至 70。 +- 设备身份仍沿用 `device_id` / `serial_number`,不改后台鉴权格式。 +- 按键触发连接;每次新连接仍执行完整 TLS 握手,没有提前建连或新增会话恢复逻辑。 + +## 3. WSS 与密码算法 + +默认地址:`wss://banban.api.talkingq.com:443/ws`。 + +使用 TLS 1.2,配置 ISRG Root X2 公共根 CA,验证服务器证书链、有效期和主机名。单向 TLS 不需要设备客户端证书,但服务器证书校验仍必须通过。WebSocket 层继续验证 HTTP 101 与 `Sec-WebSocket-Accept`。 + +内核提供 ECDSA 签名验证、ECDHE 密钥交换及 AES-GCM 等能力。APP 和内核共用 `talkingq_mbedtls_config.h`,避免跨边界使用 mbedTLS 结构体时因宏配置不同导致布局不一致。证书时间检查使用真实 RTC 和 UTC 转换,不再依赖原空时间实现。 + +ECDHE 优先使用 X25519;证书签名算法不因此改变。NIST 优化针对证书链和回退曲线的有限域计算,X25519 优化针对临时密钥交换,二者可同时受益。服务器最终选择的曲线以设备协商日志为准。 + +TLS 非阻塞读写返回 `WANT_READ` / `WANT_WRITE` 时继续等待或重试,不把暂时没有数据误判为连接断开。工作线程使用 16 KiB 栈,并保留完整握手总耗时、各阶段耗时及协商信息日志。 + +更多算法和问题根因见 [旧板完整总结](D:/banban/project/nfc_gnss/docs/WSS适配与性能优化完整总结.md)。其中的默认音量、关闭 GNSS 和实测性能均属于旧板历史。 + +## 4. 构建与切分支缓存 + +从原新板 main 升级至此版本,需要同时更新内核和 APP,因为原内核没有本次补齐的完整 TLS 算法与配置。不能只编译 APP 并沿用原 main 内核。 + +在仓库根目录执行: + +```bat +build.bat kernel +build.bat app +build.bat firmware +``` + +首次切换发现旧 GNSS `.d` 文件仍引用旧板专用 `board_features.h`,导致内核构建提示依赖不存在。这是跨分支残留编译缓存,不是新板缺失硬件配置。处理方法为备份并移走内核 `gps_app` 和 APP `gnss` 的旧 `.o`、`.d` 文件,再重新构建;没有添加旧板配置头或跳过 GNSS 编译。 + +本次缓存备份和构建日志位于 `artifacts/wss/new-board/`。SDK 生成的诊断对象和链接反馈文件另行备份,包生成后恢复其原始受版本控制的内容,避免把构建副产物混入源码修改。 + +`build.bat firmware` 生成完整多分区固件包。提供的下载包来自 `target/EG800AKCN_11LG/EG800AKCN_11LG.zip` 内层 ZIP;它不是仅含 APP 的更新包。 + +## 5. 产物与验证 + +新板包:[EG800AKCN_11LG-new-board-wss-x25519.zip](D:/banban/project/nfc_gnss/artifacts/wss/new-board/EG800AKCN_11LG-new-board-wss-x25519.zip)。 + +本地验证报告:[verification.json](D:/banban/project/nfc_gnss/artifacts/wss/new-board/verification.json)。该报告记录包 SHA-256、镜像大小和哈希、下载清单及检查结果。 + +验证覆盖: + +- WSS URL、HTTP Upgrade、TLS 读写及接收回归测试。 +- APP/内核 mbedTLS ABI、实际 SDK 证书链验证及 ECDH 运算测试。 +- ZIP CRC,以及包内 `cp.bin`、`customer_app.bin` 与本次构建输出逐字节一致性。 +- 最终 ELF 中 ECDSA、GCM、NIST 优化、RTC 时间转换和 WSS 关键符号。 +- 反汇编确认 GNSS 识别及定位入口仍创建任务,且对应 worker 存在;新板镜像不包含旧板跳过 GNSS 的日志标记。 + +主机算法测试仅证明算法与配置可用,不能代替设备端速度测量。构建和静态校验也不代表已经完成新板上电、定位或语音业务测试。 + +## 6. 上板验收与影响 + +新板仍需验证正常启动、GNSS 识别、定位任务和语音业务。WSS 日志应出现证书/域名验证成功、HTTP 101,以及原有设备身份发送流程。关注 RTC 是否有效、网络信号、完整握手协商曲线与各阶段耗时。 + +旧板实测从最初约 9.6 秒 TLS 握手,经 NIST 优化降至 1820 ms,再经 X25519 优化降至 1455 ms。上述数据不能直接标注为新板测试结果;新板 GNSS 等任务可能影响调度和 CPU 负载,需要采集新日志比较。 + +证书校验继续要求正确时间、匹配域名和受信任证书链;未来后台更换证书链或根 CA 时需要复核。共享 TLS 配置改变了内核密码能力,其他使用相同内核接口的模块也需在新板回归时观察。 + +旧板分支和历史包保留,供旧板使用与回溯。新板使用本说明中的独立包目录,避免与 `artifacts/wss/full-handshake/` 的旧板包混淆。 + + +## 7. MQTT 连接诊断版本(2026-09-16) + +新板 16:43 日志确认拨号获得 IP,但 MQTTConnect 返回 -1。语音键被识别后,因现有入口要求“拨号在线且 MQTT 在线”,播放网络检查提示,尚未发起 WSS。本轮增加连接诊断,GNSS 及网络准入、鉴权、重连策略保持原逻辑。 + +诊断包:[EG800AKCN_11LG-new-board-wss-mqtt-diag.zip](D:/banban/project/nfc_gnss/artifacts/wss/new-board/mqtt-diag/EG800AKCN_11LG-new-board-wss-mqtt-diag.zip)。这是完整多分区包;内核与上一新板 WSS 包逐字节相同,APP 增加日志。已刷入上一新板 WSS 内核时,本轮只需 build.bat app 和 build.bat firmware,无需重编内核。报告和构建日志位于包的同一目录。 + +| 日志 | 含义 | +| --- | --- | +| [MQTT-DIAG] TCP begin/end | MQTT 服务地址、端口、拨号状态、连接返回值与耗时 | +| CONNECT begin | 协议版本、会话选项、超时及 SDK 客户端状态 | +| write request / rc | SDK 写回调请求及返回字节数;负值表示失败 | +| read request / rc | SDK 读回调返回值及耗时;0 或负值不等于鉴权拒绝 | +| CONNECT end | MQTT 最终返回值、总耗时、读写次数及字节数 | +| CONNACK code=0 | 服务端接受连接 | +| CONNACK code=1/2/3/4/5 | 协议版本不支持 / Client ID 被拒绝 / 服务不可用 / 用户名或密码错误 / 未授权 | +| no response bytes returned by SDK read | SDK 读回调未返回有效字节,不能单凭此项断定服务端原因 | +| no valid initial CONNACK | 已收到数据,但开头不构成完整合法 CONNACK | +| failed before transport write | 尚未调用发送回调,优先检查客户端状态或 CONNECT 序列化 | +| [NET-GATE] blocked_mqtt_offline | 按键已识别,但 MQTT 未在线,因此未尝试 WSS | +| [NET-GATE] start_voice | 通过网络准入,进入原语音流程 | + +SDK 读回调把 EOF 和部分 socket 错误统一映射为 -1。errno_snapshot 是即时读取的错误快照,可能残留旧值,不能单凭它断言服务端拒绝或关闭。只有完整合法 CONNACK 中的拒绝码才作为服务端拒绝证据。诊断只观察原回调,不替换底层 socket 实现。 + +诊断仅在同步 MQTT CONNECT 期间挂接原有读写回调,结束即恢复,随后才启动 MQTT 后台线程。代码不打印 CONNECT 原文、账号、密码或业务报文,仅暂存接收开头四字节用于识别 CONNACK。诊断状态按现有单一 MQTT 连接工作线程的串行使用约束实现。 + +在 Visual Studio 开发命令行运行 tools/test_mqtt_diag.py,可测试参数和返回值透传、成功与失败后回调恢复、分片 CONNACK、服务端拒绝、无效响应、读写错误、无发送提前返回、时钟回绕,以及凭据测试标记不出现在日志中。 + +APP 构建、诊断测试和固件镜像校验已通过。SDK 原有隐式声明等编译警告仍存在,本轮没有修改这些接口。具体 MQTT 根因仍需新板运行诊断包后取得日志。 + +## 8. MQTT 域名试验版本(2026-09-16) + +根据新板使用受限 eSIM 的情况,将 mqtt.c 中 DEFAULT_SERVER_DOMAIN 从 101.35.224.118 改为 banban.api.talkingq.com,端口仍为 1883,沿用明文 MQTT 和原有鉴权、注册流程。保留 MQTT-DIAG 与 NET-GATE 日志。 + +电脑侧已验证该域名解析到 101.35.224.118,使用固件现有账号、临时 Client ID 可收到 CONNACK=0。该结果不能代替新板 eSIM 白名单验证:若卡商还限制端口或协议,仅改域名可能仍无法通过。 + +本次包:[EG800AKCN_11LG-new-board-wss-mqtt-domain.zip](D:/banban/project/nfc_gnss/artifacts/wss/new-board/mqtt-domain/EG800AKCN_11LG-new-board-wss-mqtt-domain.zip)。内核与上一诊断包相同,APP 编译、固件打包和镜像校验通过;用户随后确认改域名后已连接成功。已使用本轮新板 WSS 内核时,只需 build.bat app 和 build.bat firmware。本包仍是完整多分区包。 + +开机应看到 [MQTT-DIAG] TCP begin host=banban.api.talkingq.com port=1883。随后观察 CONNACK、设备注册和按语音键后的 WSS 连接结果。本轮不更改提示音下载地址。 diff --git a/docs/talkingq_wss.md b/docs/talkingq_wss.md new file mode 100644 index 0000000..8298cbe --- /dev/null +++ b/docs/talkingq_wss.md @@ -0,0 +1,128 @@ +# 旧板 WSS 适配与联调 + +> 新板 main 说明:本文保留旧板历史过程、配置与实测数据。新板已迁入 WSS,保留 GNSS 与原 main 音量行为;新板构建、下载包及验收请见 [新板 WSS 迁移说明](D:/banban/project/nfc_gnss/docs/new_board_wss.md)。旧板实测耗时不代表新板实测。 + +本次修改位于 `legacy-board-wss`(基于 `legacy-board`),默认地址为 `wss://banban.api.talkingq.com:443/ws`。沿用无 GNSS、默认音量 100 的旧板配置。上板暴露内核缺少 ECDSA 后,已补齐内核 TLS 能力并统一 APP/内核配置;从原明文旧板版本升级时必须更新内核和 APP。已有匹配 NIST 加速内核时,最新 X25519 调整只需更新 APP。 + +完整的问题根因、算法、提交、性能数据和影响说明见 [WSS 适配与性能优化完整总结](D:/banban/project/nfc_gnss/docs/WSS适配与性能优化完整总结.md)。2026-09-16 15:52 最新板端已确认 X25519 协商、完整 TLS 握手 1455 ms 和 HTTP 101。 + +## 后台实测(2026-09-16) + +| 地址 | 结果 | +| --- | --- | +| `wss://banban.api.talkingq.com:443/ws` | 11:32 复测:TLS 1.2、证书链、域名、WebSocket Accept 校验通过,返回 HTTP 101;此前 404 已解决 | +| `wss://banban.api.talkingq.com:8080/ws` | TLS 握手失败,端口未提供可用的 TLS 服务 | +| `ws://banban.api.talkingq.com:8080/ws` | 明文 Upgrade 返回 HTTP 101,Accept 值正确 | + +8080 当前是明文 WebSocket 服务,443 的 WSS 入口已可用。测试没有发送设备身份或业务数据,也没有修改服务器。 + +若 nginx 与 8080 服务部署在同一主机,可在现有 `listen 443 ssl` 的域名配置中参考以下转发(由后台按真实部署调整): + +```nginx +location /ws { + proxy_pass http://127.0.0.1:8080; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_read_timeout 300s; +} +``` + +可重新运行 `powershell.exe -NoProfile -ExecutionPolicy Bypass -File tools\probe_talkingq_wss.ps1`。必须得到有效 HTTP 101 和匹配的 `Sec-WebSocket-Accept`;仅 HTTPS 打得开或证书正常不代表 WebSocket 已可用。 + +## 上板 -9774 的修复 + +11:42 日志中,联网和 MQTT 正常,WSS 在解析根 CA 时返回 `-9774`(`-0x262E`:未知签名算法)。ISRG Root X2 使用 ECDSA/SHA-384,原内核 mini TLS 配置没有编译 ECDSA。此前主机 OpenSSL 验证通过,仅能证明证书链有效,不能证明内核支持它。 + +- 新增 `ql-config/config/talkingq_mbedtls_config.h`,由 APP 和内核 mini profile 共用;增加 ECDSA、ECDHE-ECDSA、AES-GCM 和证书日期校验。 +- 内核缺失的 `mbedtls/ecdsa.h` 从 APP 中同版本 2.28.9 SDK 头文件补入。 +- ARMCC 编译内核头文件、GCC 编译 APP 头文件,对比 10 种 TLS 类型的大小和关键字段偏移,防止调用内核 API 时结构体布局不一致。 +- 内核的 `GetCurrentCompTime()` 在此产品上是空 shim。X.509 时间检查改用 `mbedtls_time()` 的真实 RTC 时间和 UTC 转换,保留证书日期验证。 +- 日志增加失败阶段及十六进制错误码;CA 解析成功会输出 `WSS root CA parsed successfully`。 + +不能仅刷 APP 修复本次问题,也不能只用未修改配置的旧内核重新打包。 + +## 固件行为 + +2026-09-16 14:06 板端已通过根 CA 解析、TLS 握手、服务器证书和域名校验。后续 `recv data failed` / `HTTP 0` 定位到 APP 接收函数:TLS 返回 WANT_READ/WANT_WRITE 后跳出循环,错误变量仍为初始值 -1,导致误断线。现已在该分支明确清除错误状态,由原握手循环继续等待;真实 EOF、TLS 错误和握手超时仍会结束连接。 + +- `inc/talkingq_wss.h` 集中定义默认地址。解析独立处理域名、端口、路径,默认端口 443、无路径时默认 `/ws`;拒绝明文 URL、非法端口、过长字段和 CR/LF 注入。现有存储容量为 64 字节;不支持 IPv6 字面量。 +- `hal_os_get_talkingq_url()` 在没有保存地址、或保存值与已知旧默认地址完全匹配时,返回新默认 WSS 地址。此迁移在读取时生效,不改写 Flash。自定义地址保留;自定义明文地址会明确失败,不自动降级。 +- 启用 librws 的 mbedTLS 实现,统一公共和私有头文件中的宏。TCP 继续使用现有蜂窝 PDP profile 1,避免 SDK 定制 `mbedtls_net_connect` 的 CID/端口 ABI 差异。 +- 设置 SNI 和预期服务器域名,使用 `MBEDTLS_SSL_VERIFY_REQUIRED` 和 TLS 1.2 下限。没有客户端证书、客户端私钥或双向 TLS。 +- 使用现有 NITZ/RTC 时间检查证书有效期;时间明显未初始化会拒绝连接并打印原因。不会通过关闭校验来绕过时间问题。上板需要确认运营商时间同步有效。 +- 修复 TLS 短写、WANT_READ/WANT_WRITE、断线处理与资源清理;TLS 握手最多等待 20 秒,HTTP Upgrade 最多 10 秒,应用连接等待 45 秒。DNS/TCP 调用和任务调度还会消耗时间,45 秒不是所有底层调用的硬性总期限。 +- WSS 每次产生随机 WebSocket nonce,校验 HTTP 101、Upgrade、Connection、对应 Accept;支持拆分到多个 TLS 记录的响应头,保留响应头后的 WebSocket 数据。 +- 连接失败唤醒等待方;超时停止待连接 socket,回调只处理对应 socket。工作任务栈从 4 KiB 增至 16 KiB,给 TLS 证书和密码运算留出空间;仍需上板观察实际栈和堆余量。 +- WebSocket 成功后,仍由原 `sendAuthentication()` 发送 `device_id`、`serial_number`。本次不改变 MQTT、HTTP 下载及其他业务连接。 + +## TLS 握手耗时优化(2026-09-16) + +14:20 板端日志中,TCP 在 14:20:39.114 已连接,TLS 在 14:20:48.752 左右完成,约 9.6 秒;HTTP 101 在 14:20:48.894 完成,约再耗时 0.1 秒。原 `socket break` 仅表示退出 TCP 连接重试循环,现改为 `TCP connected; leaving connect loop`。这不是固定 10 秒延时,也不是 WebSocket HTTP 握手耗时。 + +共享 TLS 配置启用 `MBEDTLS_ECP_NIST_OPTIM`,使用 SDK 自带的 NIST 曲线快速模约减,减少证书 ECDSA 校验和相应 ECDHE 运算的开销。不改变证书信任、域名和日期校验规则,不调整服务器地址、设备鉴权、曲线列表或连接生命周期。 + +APP 通过 SDK 导出的 `mbedtls_ssl_handshake_step` 驱动同一 TLS 1.2 握手状态机,保留 WANT 重试和 20 秒超时;仅在 WANT 状态等待,正常状态推进不增加睡眠。每阶段打印 `WSS TLS phase ... elapsed=... ms, calls=... ms, retries=...`,结束打印 `WSS TLS handshake total=... ms`。`elapsed` 是该阶段总时间,`calls` 是 SDK 调用内累计经过时间(含任务调度,并非纯 CPU 时间),`retries` 是等待 I/O 的返回次数;时间分辨率为 SDK 的 5 ms tick。证书和密钥交换阶段仍可能同时包含网络与运算时间,不能单凭阶段名归因。 + +同一 Windows 主机上用实际 SDK crypto/X.509 源码验证相同证书链,各运行 20 次:关闭 NIST 优化平均 36.8 ms,开启后 10.2 ms,约 3.6 倍。两种配置均通过证书链、错误域名、不可信根、证书日期与 AES-GCM 检查。这是主机算法对比,不是板端总握手时间预测。可运行 `tools/test_mbedtls_cert.py --compare-nist` 复测;`tools/test_wss_handshake.py` 验证计时握手循环的状态推进、WANT、真实错误、超时与 tick 回绕。 + +第一轮加速包是 `artifacts/wss/tls-speed/EG800AKCN_11LG-legacy-wss-fast.zip`,相对早期版本需更新内核和 APP。14:38 上板已确认 TLS 握手 1820 ms,其中证书校验 965 ms、服务器密钥交换 160 ms、客户端密钥交换 445 ms,HTTP 101 正常。 + +### 完整握手的曲线协商优化 + +用户要求每次完整握手且不提前建连。WSS 的 `ssl_conf.curve_list` 改为 X25519、P-256、P-384、P-521 优先,其他原已启用曲线继续作为回退;不启用会话恢复、不改变按键/休眠/提示音逻辑。SDK 没有向 APP 导出 `mbedtls_ssl_conf_curves`,因此采用其实现同样的配置字段赋值。ABI 检查扩展到该字段、握手参数及 ECDH 上下文,验证 ARMCC 内核与 GCC APP 的实际布局一致。协商日志直接读取已匹配的上下文,`WSS TLS negotiated ECDHE group: 9` 表示 X25519(P-256=3、P-384=4、P-521=5)。 + +`tools/probe_wss_groups.py` 用同一固件根 CA、TLS 1.2 和证书/域名校验进行独立完整握手,读取固件的曲线数组进行验证:实际后台在 SDK 默认顺序下选择 P-521,在新固件顺序下选择 X25519;密码套件均为 ECDHE-ECDSA-AES256-GCM-SHA384。证据见 `artifacts/wss/full-handshake/group-probe.json`。X25519 是标准的约 128 位安全强度密钥交换;P-521 的参数更大,单纯参数更大不等于更适合本设备。当前服务端叶证书是 P-256 ECDSA,证书链、有效期和域名校验保持必需。 + +主机实际 SDK 新建 ECDH(每组 20 次,重新生成临时密钥并计算共享密钥)平均:X25519 1.55 ms、P-256 1.90 ms、P-384 3.40 ms、P-521 5.15 ms;X25519 测试峰值额外堆 1144 字节,P-521 6376 字节(包含测试对端共享密钥校验的内存)。每次校验双方计算结果相同并检查内存释放。15:52 板端补充日志已确认 group=9,客户端密钥交换 135 ms(上一版 445 ms),TLS 总计 1455 ms(上一版 1820 ms),HTTP 101 正常。两次日志样本中 TLS 再缩短约 20%;不能把主机基准比例套用到整个握手。 + +另对比 ECP window=4/5/6:证书校验约 10.35/10.20/10.45 ms,峰值分配约 11913/16009/18697 字节,收益不稳定,因此固件保留 window=4。可在 MSVC 开发者终端运行 `tools/test_mbedtls_cert.py --compare-windows` 复测。 + +最新包 `artifacts/wss/full-handshake/EG800AKCN_11LG-legacy-wss-x25519.zip` 沿用已验证的 NIST 内核,只更新 APP。当前工作区可 `build.bat app`、`build.bat firmware`;全新检出仍需先构建匹配的内核。旧 `tls-speed` 包保留,作为板端 1820 ms 的对照。 + +## 根证书来源与验证 + +固件内置的是公共根 CA **ISRG Root X2**,不是短期服务器证书。 + +- 来源:对目标域名进行 Windows 系统信任和域名校验后导出的证书链根。 +- 根证书 DER SHA-256:`69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470`。 +- 根证书有效期到 2040-09-17。 +- 实测链:`banban.api.talkingq.com → Let's Encrypt YE1 → Root YE(由 X2 交叉签名)→ ISRG Root X2`。 +- 当前服务器证书有效期:2026-08-28 至 2026-11-26。后台正常续期且仍能链到内置根时,不需要随服务器证书续期更新固件。 +- Python/OpenSSL 仅加载从固件源码提取的这一张根 CA,没有加载系统证书库或自动下载中间证书,TLS 1.2 验证成功;错误域名和空信任库均验证失败。 +- 固件进行证书链、有效期和域名验证;未增加 OCSP/CRL 吊销查询。后端更换到其他根 CA 时,需要评估并更新信任根。 + +可重跑:`ql-cross-tool\win32\owtoolchain\Python\python.exe tools\probe_wss_root.py`。该测试验证服务器链完整性和内置信任根,不能代替板端 mbedTLS 实测。 + +## 构建与验证 + +```bat +tools\test_wss.cmd +ql-cross-tool\win32\owtoolchain\Python\python.exe tools\check_mbedtls_abi.py +build.bat kernel +build.bat app +build.bat firmware +``` + +主机测试使用 MSVC 编译实际 URL 和握手解析源码;另从真实实现提取 TLS 写入和取消连接函数,注入桩测试短写、重试、超时、时钟回绕和资源释放。`tools/test_wss_receive.py` 提取实际接收和握手等待函数,结合实际 HTTP 解析器验证 WANT_READ/WANT_WRITE、分片 101、响应后帧数据保留、超时和时钟回绕、EOF/真实错误、空 TLS 上下文及错误 Accept;修复前可复现误断线,修复后通过。解析测试覆盖合法地址、非法端口、明文拒绝、缓冲区边界、旧地址识别、每个响应头分片边界、非 101、错误/重复 Accept、缺失 Upgrade/Connection 和响应大小上限。 + +在 Visual Studio 开发者终端运行 `ql-cross-tool\win32\owtoolchain\Python\python.exe tools\test_mbedtls_cert.py`,使用 SDK 实际 crypto/X.509 源码和共享配置验证内置根 CA、当前服务器证书链、错误域名、空信任库、过期/尚未生效日期,以及 AES-GCM 标准测试向量。测试中的分配器、UTC 时钟和日志适配到 Windows,文件读取由测试程序完成;没有替换证书算法实现。默认使用 `artifacts/wss/retest-443/chain-0.pem` 至 `chain-2.pem`,可把探测输出目录作为脚本参数。 + +导出到下述路径后运行 `ql-cross-tool\win32\owtoolchain\Python\python.exe tools\verify_wss_package.py`,核对 ZIP CRC、APP/内核与当前构建的字节一致性、无 GNSS 入口以及内核 ECDSA/GCM/日期校验符号。SDK 有既有编译警告,不能仅凭外层批处理退出码认定成功。 + +最新优化包位于 `artifacts/wss/full-handshake/EG800AKCN_11LG-legacy-wss-x25519.zip`,标准输出为 `target/EG800AKCN_11LG/EG800AKCN_11LG.zip`,两者字节一致。这是完整多分区烧录包,内核与上一版 NIST 加速包字节一致。运行 `ql-cross-tool\win32\owtoolchain\Python\python.exe tools\verify_wss_package.py` 校验默认最新包;也可显式传入该 ZIP 路径。 + +`ecc-fix/EG800AKCN_11LG-legacy-wss-ecc.zip` 保留用于对照接收错误。原 `artifacts/wss/EG800AKCN_11LG-legacy-wss.zip` 存在缺失 ECDSA 的问题,请勿用于验证本次修复。旧板明文 WS 包仍保留在 `artifacts/legacy-no-gnss/`。 + +## 上板验收 + +443 `/ws` 已通过主机握手测试;ECC/RTC、接收修复、NIST 加速和 X25519 优先配置均已在板端通过 TLS、HTTP 101。下面作为后续多次重复测试与业务稳定性验收步骤: + +1. 无 GNSS 旧板正常启动、蜂窝网络就绪、RTC 时间正确。 +2. 先出现 `WSS root CA parsed successfully`,再出现 `WSS TLS handshake and certificate/hostname verification passed`。 +3. 出现 `WebSocket upgrade verified: HTTP 101` 和 `ws connect okay`。 +4. 服务器确认原设备鉴权成功,再测试收发音频、断网重连和休眠唤醒。 +5. 确认 `WSS TLS negotiated ECDHE group: 9`;记录 `WSS TLS phase` 和 `WSS TLS handshake total`,同一网络环境多次对比上一版 1820 ms 的 TLS 握手耗时。 + +TLS 成功、WebSocket 成功、设备鉴权成功是三个不同阶段,不能只看其中一条日志就认定业务已跑通。 diff --git a/ql-application/threadx/common/include/mbedtls/config.h b/ql-application/threadx/common/include/mbedtls/config.h index a6f222f..b056d90 100644 --- a/ql-application/threadx/common/include/mbedtls/config.h +++ b/ql-application/threadx/common/include/mbedtls/config.h @@ -1,4255 +1,11 @@ -/** - * \file config.h - * - * \brief Configuration options (set of defines) - * - * This set of compile-time options may be used to enable - * or disable features selectively, and reduce the global - * memory footprint. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later - */ - #ifndef MBEDTLS_CONFIG_H #define MBEDTLS_CONFIG_H - -#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) -#define _CRT_SECURE_NO_DEPRECATE 1 -#endif - -/** - * \name SECTION: System support - * - * This section sets system specific settings. - * \{ - */ - -/** - * \def MBEDTLS_HAVE_ASM - * - * The compiler has support for asm(). - * - * Requires support for asm() in compiler. - * - * Used in: - * library/aria.c - * library/timing.c - * include/mbedtls/bn_mul.h - * - * Required by: - * MBEDTLS_AESNI_C (on some platforms) - * MBEDTLS_PADLOCK_C - * - * Comment to disable the use of assembly code. - */ -#define MBEDTLS_HAVE_ASM - -/** - * \def MBEDTLS_NO_UDBL_DIVISION - * - * The platform lacks support for double-width integer division (64-bit - * division on a 32-bit platform, 128-bit division on a 64-bit platform). - * - * Used in: - * include/mbedtls/bignum.h - * library/bignum.c - * - * The bignum code uses double-width division to speed up some operations. - * Double-width division is often implemented in software that needs to - * be linked with the program. The presence of a double-width integer - * type is usually detected automatically through preprocessor macros, - * but the automatic detection cannot know whether the code needs to - * and can be linked with an implementation of division for that type. - * By default division is assumed to be usable if the type is present. - * Uncomment this option to prevent the use of double-width division. - * - * Note that division for the native integer type is always required. - * Furthermore, a 64-bit type is always required even on a 32-bit - * platform, but it need not support multiplication or division. In some - * cases it is also desirable to disable some double-width operations. For - * example, if double-width division is implemented in software, disabling - * it can reduce code size in some embedded targets. - */ -//#define MBEDTLS_NO_UDBL_DIVISION - -/** - * \def MBEDTLS_NO_64BIT_MULTIPLICATION - * - * The platform lacks support for 32x32 -> 64-bit multiplication. - * - * Used in: - * library/poly1305.c - * - * Some parts of the library may use multiplication of two unsigned 32-bit - * operands with a 64-bit result in order to speed up computations. On some - * platforms, this is not available in hardware and has to be implemented in - * software, usually in a library provided by the toolchain. - * - * Sometimes it is not desirable to have to link to that library. This option - * removes the dependency of that library on platforms that lack a hardware - * 64-bit multiplier by embedding a software implementation in Mbed TLS. - * - * Note that depending on the compiler, this may decrease performance compared - * to using the library function provided by the toolchain. - */ -//#define MBEDTLS_NO_64BIT_MULTIPLICATION - -/** - * \def MBEDTLS_HAVE_SSE2 - * - * CPU supports SSE2 instruction set. - * - * Uncomment if the CPU supports SSE2 (IA-32 specific). - */ -//#define MBEDTLS_HAVE_SSE2 - -/** - * \def MBEDTLS_HAVE_TIME - * - * System has time.h and time(). - * The time does not need to be correct, only time differences are used, - * by contrast with MBEDTLS_HAVE_TIME_DATE - * - * Defining MBEDTLS_HAVE_TIME allows you to specify MBEDTLS_PLATFORM_TIME_ALT, - * MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and - * MBEDTLS_PLATFORM_STD_TIME. - * - * Comment if your system does not support time functions. - * - * \note If MBEDTLS_TIMING_C is set - to enable the semi-portable timing - * interface - timing.c will include time.h on suitable platforms - * regardless of the setting of MBEDTLS_HAVE_TIME, unless - * MBEDTLS_TIMING_ALT is used. See timing.c for more information. - */ -#define MBEDTLS_HAVE_TIME - -/** - * \def MBEDTLS_HAVE_TIME_DATE - * - * System has time.h, time(), and an implementation for - * mbedtls_platform_gmtime_r() (see below). - * The time needs to be correct (not necessarily very accurate, but at least - * the date should be correct). This is used to verify the validity period of - * X.509 certificates. - * - * Comment if your system does not have a correct clock. - * - * \note mbedtls_platform_gmtime_r() is an abstraction in platform_util.h that - * behaves similarly to the gmtime_r() function from the C standard. Refer to - * the documentation for mbedtls_platform_gmtime_r() for more information. - * - * \note It is possible to configure an implementation for - * mbedtls_platform_gmtime_r() at compile-time by using the macro - * MBEDTLS_PLATFORM_GMTIME_R_ALT. - */ -#define MBEDTLS_HAVE_TIME_DATE - -/** - * \def MBEDTLS_PLATFORM_MEMORY - * - * Enable the memory allocation layer. - * - * By default Mbed TLS uses the system-provided calloc() and free(). - * This allows different allocators (self-implemented or provided) to be - * provided to the platform abstraction layer. - * - * Enabling #MBEDTLS_PLATFORM_MEMORY without the - * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide - * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and - * free() function pointer at runtime. - * - * Enabling #MBEDTLS_PLATFORM_MEMORY and specifying - * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the - * alternate function at compile time. - * - * An overview of how the value of mbedtls_calloc is determined: - * - * - if !MBEDTLS_PLATFORM_MEMORY - * - mbedtls_calloc = calloc - * - if MBEDTLS_PLATFORM_MEMORY - * - if (MBEDTLS_PLATFORM_CALLOC_MACRO && MBEDTLS_PLATFORM_FREE_MACRO): - * - mbedtls_calloc = MBEDTLS_PLATFORM_CALLOC_MACRO - * - if !(MBEDTLS_PLATFORM_CALLOC_MACRO && MBEDTLS_PLATFORM_FREE_MACRO): - * - Dynamic setup via mbedtls_platform_set_calloc_free is now possible with a default value MBEDTLS_PLATFORM_STD_CALLOC. - * - How is MBEDTLS_PLATFORM_STD_CALLOC handled? - * - if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS: - * - MBEDTLS_PLATFORM_STD_CALLOC is not set to anything; - * - MBEDTLS_PLATFORM_STD_MEM_HDR can be included if present; - * - if !MBEDTLS_PLATFORM_NO_STD_FUNCTIONS: - * - if MBEDTLS_PLATFORM_STD_CALLOC is present: - * - User-defined MBEDTLS_PLATFORM_STD_CALLOC is respected; - * - if !MBEDTLS_PLATFORM_STD_CALLOC: - * - MBEDTLS_PLATFORM_STD_CALLOC = calloc - * - * - At this point the presence of MBEDTLS_PLATFORM_STD_CALLOC is checked. - * - if !MBEDTLS_PLATFORM_STD_CALLOC - * - MBEDTLS_PLATFORM_STD_CALLOC = uninitialized_calloc - * - * - mbedtls_calloc = MBEDTLS_PLATFORM_STD_CALLOC. - * - * Defining MBEDTLS_PLATFORM_CALLOC_MACRO and #MBEDTLS_PLATFORM_STD_CALLOC at the same time is not possible. - * MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_FREE_MACRO must both be defined or undefined at the same time. - * #MBEDTLS_PLATFORM_STD_CALLOC and #MBEDTLS_PLATFORM_STD_FREE do not have to be defined at the same time, as, if they are used, - * dynamic setup of these functions is possible. See the tree above to see how are they handled in all cases. - * An uninitialized #MBEDTLS_PLATFORM_STD_CALLOC always fails, returning a null pointer. - * An uninitialized #MBEDTLS_PLATFORM_STD_FREE does not do anything. - * - * Requires: MBEDTLS_PLATFORM_C - * - * Enable this layer to allow use of alternative memory allocators. - */ -#define MBEDTLS_PLATFORM_MEMORY - -/** - * \def MBEDTLS_PLATFORM_NO_STD_FUNCTIONS - * - * Do not assign standard functions in the platform layer (e.g. calloc() to - * MBEDTLS_PLATFORM_STD_CALLOC and printf() to MBEDTLS_PLATFORM_STD_PRINTF) - * - * This makes sure there are no linking errors on platforms that do not support - * these functions. You will HAVE to provide alternatives, either at runtime - * via the platform_set_xxx() functions or at compile time by setting - * the MBEDTLS_PLATFORM_STD_XXX defines, or enabling a - * MBEDTLS_PLATFORM_XXX_MACRO. - * - * Requires: MBEDTLS_PLATFORM_C - * - * Uncomment to prevent default assignment of standard functions in the - * platform layer. - */ -//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS - -/** - * \def MBEDTLS_PLATFORM_EXIT_ALT - * - * MBEDTLS_PLATFORM_XXX_ALT: Uncomment a macro to let Mbed TLS support the - * function in the platform abstraction layer. - * - * Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, Mbed TLS will - * provide a function "mbedtls_platform_set_printf()" that allows you to set an - * alternative printf function pointer. - * - * All these define require MBEDTLS_PLATFORM_C to be defined! - * - * \note MBEDTLS_PLATFORM_SNPRINTF_ALT is required on Windows; - * it will be enabled automatically by check_config.h - * - * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as - * MBEDTLS_PLATFORM_XXX_MACRO! - * - * Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME - * - * Uncomment a macro to enable alternate implementation of specific base - * platform function - */ -//#define MBEDTLS_PLATFORM_EXIT_ALT -#define MBEDTLS_PLATFORM_TIME_ALT -//#define MBEDTLS_PLATFORM_FPRINTF_ALT -//#define MBEDTLS_PLATFORM_PRINTF_ALT -//#define MBEDTLS_PLATFORM_SNPRINTF_ALT -//#define MBEDTLS_PLATFORM_VSNPRINTF_ALT -//#define MBEDTLS_PLATFORM_NV_SEED_ALT -//#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT - -/** - * Uncomment the macro to let Mbed TLS use your alternate implementation of - * mbedtls_platform_gmtime_r(). This replaces the default implementation in - * platform_util.c. - * - * gmtime() is not a thread-safe function as defined in the C standard. The - * library will try to use safer implementations of this function, such as - * gmtime_r() when available. However, if Mbed TLS cannot identify the target - * system, the implementation of mbedtls_platform_gmtime_r() will default to - * using the standard gmtime(). In this case, calls from the library to - * gmtime() will be guarded by the global mutex mbedtls_threading_gmtime_mutex - * if MBEDTLS_THREADING_C is enabled. We recommend that calls from outside the - * library are also guarded with this mutex to avoid race conditions. However, - * if the macro MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, Mbed TLS will - * unconditionally use the implementation for mbedtls_platform_gmtime_r() - * supplied at compile time. - */ -//#define MBEDTLS_PLATFORM_GMTIME_R_ALT - -/** - * Uncomment the macro to let Mbed TLS use your alternate implementation of - * mbedtls_platform_zeroize(). This replaces the default implementation in - * platform_util.c. - * - * mbedtls_platform_zeroize() is a widely used function across the library to - * zero a block of memory. The implementation is expected to be secure in the - * sense that it has been written to prevent the compiler from removing calls - * to mbedtls_platform_zeroize() as part of redundant code elimination - * optimizations. However, it is difficult to guarantee that calls to - * mbedtls_platform_zeroize() will not be optimized by the compiler as older - * versions of the C language standards do not provide a secure implementation - * of memset(). Therefore, MBEDTLS_PLATFORM_ZEROIZE_ALT enables users to - * configure their own implementation of mbedtls_platform_zeroize(), for - * example by using directives specific to their compiler, features from newer - * C standards (e.g using memset_s() in C11) or calling a secure memset() from - * their system (e.g explicit_bzero() in BSD). - */ -//#define MBEDTLS_PLATFORM_ZEROIZE_ALT - -/** - * \def MBEDTLS_DEPRECATED_WARNING - * - * Mark deprecated functions and features so that they generate a warning if - * used. Functionality deprecated in one version will usually be removed in the - * next version. You can enable this to help you prepare the transition to a - * new major version by making sure your code is not using this functionality. - * - * This only works with GCC and Clang. With other compilers, you may want to - * use MBEDTLS_DEPRECATED_REMOVED - * - * Uncomment to get warnings on using deprecated functions and features. - */ -//#define MBEDTLS_DEPRECATED_WARNING - -/** - * \def MBEDTLS_DEPRECATED_REMOVED - * - * Remove deprecated functions and features so that they generate an error if - * used. Functionality deprecated in one version will usually be removed in the - * next version. You can enable this to help you prepare the transition to a - * new major version by making sure your code is not using this functionality. - * - * Uncomment to get errors on using deprecated functions and features. - */ -//#define MBEDTLS_DEPRECATED_REMOVED - -/** - * \def MBEDTLS_CHECK_PARAMS - * - * This configuration option controls whether the library validates more of - * the parameters passed to it. - * - * When this flag is not defined, the library only attempts to validate an - * input parameter if: (1) they may come from the outside world (such as the - * network, the filesystem, etc.) or (2) not validating them could result in - * internal memory errors such as overflowing a buffer controlled by the - * library. On the other hand, it doesn't attempt to validate parameters whose - * values are fully controlled by the application (such as pointers). - * - * When this flag is defined, the library additionally attempts to validate - * parameters that are fully controlled by the application, and should always - * be valid if the application code is fully correct and trusted. - * - * For example, when a function accepts as input a pointer to a buffer that may - * contain untrusted data, and its documentation mentions that this pointer - * must not be NULL: - * - The pointer is checked to be non-NULL only if this option is enabled. - * - The content of the buffer is always validated. - * - * When this flag is defined, if a library function receives a parameter that - * is invalid: - * 1. The function will invoke the macro MBEDTLS_PARAM_FAILED(). - * 2. If MBEDTLS_PARAM_FAILED() did not terminate the program, the function - * will immediately return. If the function returns an Mbed TLS error code, - * the error code in this case is MBEDTLS_ERR_xxx_BAD_INPUT_DATA. - * - * When defining this flag, you also need to arrange a definition for - * MBEDTLS_PARAM_FAILED(). You can do this by any of the following methods: - * - By default, the library defines MBEDTLS_PARAM_FAILED() to call a - * function mbedtls_param_failed(), but the library does not define this - * function. If you do not make any other arrangements, you must provide - * the function mbedtls_param_failed() in your application. - * See `platform_util.h` for its prototype. - * - If you enable the macro #MBEDTLS_CHECK_PARAMS_ASSERT, then the - * library defines MBEDTLS_PARAM_FAILED(\c cond) to be `assert(cond)`. - * You can still supply an alternative definition of - * MBEDTLS_PARAM_FAILED(), which may call `assert`. - * - If you define a macro MBEDTLS_PARAM_FAILED() before including `config.h` - * or you uncomment the definition of MBEDTLS_PARAM_FAILED() in `config.h`, - * the library will call the macro that you defined and will not supply - * its own version. Note that if MBEDTLS_PARAM_FAILED() calls `assert`, - * you need to enable #MBEDTLS_CHECK_PARAMS_ASSERT so that library source - * files include ``. - * - * Uncomment to enable validation of application-controlled parameters. - */ -//#define MBEDTLS_CHECK_PARAMS - -/** - * \def MBEDTLS_CHECK_PARAMS_ASSERT - * - * Allow MBEDTLS_PARAM_FAILED() to call `assert`, and make it default to - * `assert`. This macro is only used if #MBEDTLS_CHECK_PARAMS is defined. - * - * If this macro is not defined, then MBEDTLS_PARAM_FAILED() defaults to - * calling a function mbedtls_param_failed(). See the documentation of - * #MBEDTLS_CHECK_PARAMS for details. - * - * Uncomment to allow MBEDTLS_PARAM_FAILED() to call `assert`. - */ -//#define MBEDTLS_CHECK_PARAMS_ASSERT - -/** \} name SECTION: System support */ - -/** - * \name SECTION: Mbed TLS feature support - * - * This section sets support for features that are or are not needed - * within the modules that are enabled. - * \{ - */ - -/** - * \def MBEDTLS_TIMING_ALT - * - * Uncomment to provide your own alternate implementation for mbedtls_timing_hardclock(), - * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay() - * - * Only works if you have MBEDTLS_TIMING_C enabled. - * - * You will need to provide a header "timing_alt.h" and an implementation at - * compile time. - */ -//#define MBEDTLS_TIMING_ALT - -/** - * \def MBEDTLS_AES_ALT - * - * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let Mbed TLS use your - * alternate core implementation of a symmetric crypto, an arithmetic or hash - * module (e.g. platform specific assembly optimized implementations). Keep - * in mind that the function prototypes should remain the same. - * - * This replaces the whole module. If you only want to replace one of the - * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags. - * - * Example: In case you uncomment MBEDTLS_AES_ALT, Mbed TLS will no longer - * provide the "struct mbedtls_aes_context" definition and omit the base - * function declarations and implementations. "aes_alt.h" will be included from - * "aes.h" to include the new function definitions. - * - * Uncomment a macro to enable alternate implementation of the corresponding - * module. - * - * \warning MD2, MD4, MD5, ARC4, DES and SHA-1 are considered weak and their - * use constitutes a security risk. If possible, we recommend - * avoiding dependencies on them, and considering stronger message - * digests and ciphers instead. - * - */ -//#define MBEDTLS_AES_ALT -//#define MBEDTLS_ARC4_ALT -//#define MBEDTLS_ARIA_ALT -//#define MBEDTLS_BLOWFISH_ALT -//#define MBEDTLS_CAMELLIA_ALT -//#define MBEDTLS_CCM_ALT -//#define MBEDTLS_CHACHA20_ALT -//#define MBEDTLS_CHACHAPOLY_ALT -//#define MBEDTLS_CMAC_ALT -//#define MBEDTLS_DES_ALT -//#define MBEDTLS_DHM_ALT -//#define MBEDTLS_ECJPAKE_ALT -//#define MBEDTLS_GCM_ALT -//#define MBEDTLS_NIST_KW_ALT -//#define MBEDTLS_MD2_ALT -//#define MBEDTLS_MD4_ALT -//#define MBEDTLS_MD5_ALT -//#define MBEDTLS_POLY1305_ALT -//#define MBEDTLS_RIPEMD160_ALT -//#define MBEDTLS_RSA_ALT -//#define MBEDTLS_SHA1_ALT -//#define MBEDTLS_SHA256_ALT -//#define MBEDTLS_SHA512_ALT -//#define MBEDTLS_XTEA_ALT - -/* - * When replacing the elliptic curve module, please consider, that it is - * implemented with two .c files: - * - ecp.c - * - ecp_curves.c - * You can replace them very much like all the other MBEDTLS__MODULE_NAME__ALT - * macros as described above. The only difference is that you have to make sure - * that you provide functionality for both .c files. - */ -//#define MBEDTLS_ECP_ALT - -/** - * \def MBEDTLS_MD2_PROCESS_ALT - * - * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let Mbed TLS use you - * alternate core implementation of symmetric crypto or hash function. Keep in - * mind that function prototypes should remain the same. - * - * This replaces only one function. The header file from Mbed TLS is still - * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags. - * - * Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, Mbed TLS will - * no longer provide the mbedtls_sha1_process() function, but it will still provide - * the other function (using your mbedtls_sha1_process() function) and the definition - * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible - * with this definition. - * - * \note Because of a signature change, the core AES encryption and decryption routines are - * currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt, - * respectively. When setting up alternative implementations, these functions should - * be overridden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt - * must stay untouched. - * - * \note If you use the AES_xxx_ALT macros, then it is recommended to also set - * MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES - * tables. - * - * Uncomment a macro to enable alternate implementation of the corresponding - * function. - * - * \warning MD2, MD4, MD5, DES and SHA-1 are considered weak and their use - * constitutes a security risk. If possible, we recommend avoiding - * dependencies on them, and considering stronger message digests - * and ciphers instead. - * - * \warning If both MBEDTLS_ECDSA_SIGN_ALT and MBEDTLS_ECDSA_DETERMINISTIC are - * enabled, then the deterministic ECDH signature functions pass the - * the static HMAC-DRBG as RNG to mbedtls_ecdsa_sign(). Therefore - * alternative implementations should use the RNG only for generating - * the ephemeral key and nothing else. If this is not possible, then - * MBEDTLS_ECDSA_DETERMINISTIC should be disabled and an alternative - * implementation should be provided for mbedtls_ecdsa_sign_det_ext() - * (and for mbedtls_ecdsa_sign_det() too if backward compatibility is - * desirable). - * - */ -//#define MBEDTLS_MD2_PROCESS_ALT -//#define MBEDTLS_MD4_PROCESS_ALT -//#define MBEDTLS_MD5_PROCESS_ALT -//#define MBEDTLS_RIPEMD160_PROCESS_ALT -//#define MBEDTLS_SHA1_PROCESS_ALT -//#define MBEDTLS_SHA256_PROCESS_ALT -//#define MBEDTLS_SHA512_PROCESS_ALT -//#define MBEDTLS_DES_SETKEY_ALT -//#define MBEDTLS_DES_CRYPT_ECB_ALT -//#define MBEDTLS_DES3_CRYPT_ECB_ALT -//#define MBEDTLS_AES_SETKEY_ENC_ALT -//#define MBEDTLS_AES_SETKEY_DEC_ALT -//#define MBEDTLS_AES_ENCRYPT_ALT -//#define MBEDTLS_AES_DECRYPT_ALT -//#define MBEDTLS_ECDH_GEN_PUBLIC_ALT -//#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT -//#define MBEDTLS_ECDSA_VERIFY_ALT -//#define MBEDTLS_ECDSA_SIGN_ALT -//#define MBEDTLS_ECDSA_GENKEY_ALT - -/** - * \def MBEDTLS_ECP_INTERNAL_ALT - * - * Expose a part of the internal interface of the Elliptic Curve Point module. - * - * MBEDTLS_ECP__FUNCTION_NAME__ALT: Uncomment a macro to let Mbed TLS use your - * alternative core implementation of elliptic curve arithmetic. Keep in mind - * that function prototypes should remain the same. - * - * This partially replaces one function. The header file from Mbed TLS is still - * used, in contrast to the MBEDTLS_ECP_ALT flag. The original implementation - * is still present and it is used for group structures not supported by the - * alternative. - * - * The original implementation can in addition be removed by setting the - * MBEDTLS_ECP_NO_FALLBACK option, in which case any function for which the - * corresponding MBEDTLS_ECP__FUNCTION_NAME__ALT macro is defined will not be - * able to fallback to curves not supported by the alternative implementation. - * - * Any of these options become available by defining MBEDTLS_ECP_INTERNAL_ALT - * and implementing the following functions: - * unsigned char mbedtls_internal_ecp_grp_capable( - * const mbedtls_ecp_group *grp ) - * int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp ) - * void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp ) - * The mbedtls_internal_ecp_grp_capable function should return 1 if the - * replacement functions implement arithmetic for the given group and 0 - * otherwise. - * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_free are - * called before and after each point operation and provide an opportunity to - * implement optimized set up and tear down instructions. - * - * Example: In case you set MBEDTLS_ECP_INTERNAL_ALT and - * MBEDTLS_ECP_DOUBLE_JAC_ALT, Mbed TLS will still provide the ecp_double_jac() - * function, but will use your mbedtls_internal_ecp_double_jac() if the group - * for the operation is supported by your implementation (i.e. your - * mbedtls_internal_ecp_grp_capable() function returns 1 for this group). If the - * group is not supported by your implementation, then the original Mbed TLS - * implementation of ecp_double_jac() is used instead, unless this fallback - * behaviour is disabled by setting MBEDTLS_ECP_NO_FALLBACK (in which case - * ecp_double_jac() will return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE). - * - * The function prototypes and the definition of mbedtls_ecp_group and - * mbedtls_ecp_point will not change based on MBEDTLS_ECP_INTERNAL_ALT, so your - * implementation of mbedtls_internal_ecp__function_name__ must be compatible - * with their definitions. - * - * Uncomment a macro to enable alternate implementation of the corresponding - * function. - */ -/* Required for all the functions in this section */ -//#define MBEDTLS_ECP_INTERNAL_ALT -/* Turn off software fallback for curves not supported in hardware */ -//#define MBEDTLS_ECP_NO_FALLBACK -/* Support for Weierstrass curves with Jacobi representation */ -//#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT -//#define MBEDTLS_ECP_ADD_MIXED_ALT -//#define MBEDTLS_ECP_DOUBLE_JAC_ALT -//#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT -//#define MBEDTLS_ECP_NORMALIZE_JAC_ALT -/* Support for curves with Montgomery arithmetic */ -//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT -//#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT -//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT - -/** - * \def MBEDTLS_TEST_NULL_ENTROPY - * - * Enables testing and use of Mbed TLS without any configured entropy sources. - * This permits use of the library on platforms before an entropy source has - * been integrated (see for example the MBEDTLS_ENTROPY_HARDWARE_ALT or the - * MBEDTLS_ENTROPY_NV_SEED switches). - * - * WARNING! This switch MUST be disabled in production builds, and is suitable - * only for development. - * Enabling the switch negates any security provided by the library. - * - * Requires MBEDTLS_ENTROPY_C, MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES - * - */ -//#define MBEDTLS_TEST_NULL_ENTROPY - -/** - * \def MBEDTLS_ENTROPY_HARDWARE_ALT - * - * Uncomment this macro to let Mbed TLS use your own implementation of a - * hardware entropy collector. - * - * Your function must be called \c mbedtls_hardware_poll(), have the same - * prototype as declared in entropy_poll.h, and accept NULL as first argument. - * - * Uncomment to use your own hardware entropy collector. - */ -#define MBEDTLS_ENTROPY_HARDWARE_ALT - -/** - * \def MBEDTLS_AES_ROM_TABLES - * - * Use precomputed AES tables stored in ROM. - * - * Uncomment this macro to use precomputed AES tables stored in ROM. - * Comment this macro to generate AES tables in RAM at runtime. - * - * Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb - * (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the - * initialization time before the first AES operation can be performed. - * It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c - * MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded - * performance if ROM access is slower than RAM access. - * - * This option is independent of \c MBEDTLS_AES_FEWER_TABLES. - * - */ -//#define MBEDTLS_AES_ROM_TABLES - -/** - * \def MBEDTLS_AES_FEWER_TABLES - * - * Use less ROM/RAM for AES tables. - * - * Uncommenting this macro omits 75% of the AES tables from - * ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES) - * by computing their values on the fly during operations - * (the tables are entry-wise rotations of one another). - * - * Tradeoff: Uncommenting this reduces the RAM / ROM footprint - * by ~6kb but at the cost of more arithmetic operations during - * runtime. Specifically, one has to compare 4 accesses within - * different tables to 4 accesses with additional arithmetic - * operations within the same table. The performance gain/loss - * depends on the system and memory details. - * - * This option is independent of \c MBEDTLS_AES_ROM_TABLES. - * - */ -//#define MBEDTLS_AES_FEWER_TABLES - -/** - * \def MBEDTLS_CAMELLIA_SMALL_MEMORY - * - * Use less ROM for the Camellia implementation (saves about 768 bytes). - * - * Uncomment this macro to use less memory for Camellia. - */ -//#define MBEDTLS_CAMELLIA_SMALL_MEMORY - -/** - * \def MBEDTLS_CHECK_RETURN_WARNING - * - * If this macro is defined, emit a compile-time warning if application code - * calls a function without checking its return value, but the return value - * should generally be checked in portable applications. - * - * This is only supported on platforms where #MBEDTLS_CHECK_RETURN is - * implemented. Otherwise this option has no effect. - * - * Uncomment to get warnings on using fallible functions without checking - * their return value. - * - * \note This feature is a work in progress. - * Warnings will be added to more functions in the future. - * - * \note A few functions are considered critical, and ignoring the return - * value of these functions will trigger a warning even if this - * macro is not defined. To completely disable return value check - * warnings, define #MBEDTLS_CHECK_RETURN with an empty expansion. - */ -//#define MBEDTLS_CHECK_RETURN_WARNING - -/** - * \def MBEDTLS_CIPHER_MODE_CBC - * - * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers. - */ -#define MBEDTLS_CIPHER_MODE_CBC - -/** - * \def MBEDTLS_CIPHER_MODE_CFB - * - * Enable Cipher Feedback mode (CFB) for symmetric ciphers. - */ -#define MBEDTLS_CIPHER_MODE_CFB - -/** - * \def MBEDTLS_CIPHER_MODE_CTR - * - * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. - */ -#define MBEDTLS_CIPHER_MODE_CTR - -/** - * \def MBEDTLS_CIPHER_MODE_OFB - * - * Enable Output Feedback mode (OFB) for symmetric ciphers. - */ -#define MBEDTLS_CIPHER_MODE_OFB - -/** - * \def MBEDTLS_CIPHER_MODE_XTS - * - * Enable Xor-encrypt-xor with ciphertext stealing mode (XTS) for AES. - */ -#define MBEDTLS_CIPHER_MODE_XTS - -/** - * \def MBEDTLS_CIPHER_NULL_CIPHER - * - * Enable NULL cipher. - * Warning: Only do so when you know what you are doing. This allows for - * encryption or channels without any security! - * - * Requires MBEDTLS_ENABLE_WEAK_CIPHERSUITES as well to enable - * the following ciphersuites: - * MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA - * MBEDTLS_TLS_RSA_WITH_NULL_SHA256 - * MBEDTLS_TLS_RSA_WITH_NULL_SHA - * MBEDTLS_TLS_RSA_WITH_NULL_MD5 - * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA - * MBEDTLS_TLS_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_PSK_WITH_NULL_SHA - * - * Uncomment this macro to enable the NULL cipher and ciphersuites - */ -//#define MBEDTLS_CIPHER_NULL_CIPHER - -/** - * \def MBEDTLS_CIPHER_PADDING_PKCS7 - * - * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for - * specific padding modes in the cipher layer with cipher modes that support - * padding (e.g. CBC) - * - * If you disable all padding modes, only full blocks can be used with CBC. - * - * Enable padding modes in the cipher layer. - */ -#define MBEDTLS_CIPHER_PADDING_PKCS7 -#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS -#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN -#define MBEDTLS_CIPHER_PADDING_ZEROS - -/** \def MBEDTLS_CTR_DRBG_USE_128_BIT_KEY - * - * Uncomment this macro to use a 128-bit key in the CTR_DRBG module. - * By default, CTR_DRBG uses a 256-bit key. - */ -//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY - -/** - * \def MBEDTLS_ENABLE_WEAK_CIPHERSUITES - * - * Enable weak ciphersuites in SSL / TLS. - * Warning: Only do so when you know what you are doing. This allows for - * channels with virtually no security at all! - * - * This enables the following ciphersuites: - * MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA - * - * Uncomment this macro to enable weak ciphersuites - * - * \warning DES is considered a weak cipher and its use constitutes a - * security risk. We recommend considering stronger ciphers instead. - */ -//#define MBEDTLS_ENABLE_WEAK_CIPHERSUITES - -/** - * \def MBEDTLS_REMOVE_ARC4_CIPHERSUITES - * - * Remove RC4 ciphersuites by default in SSL / TLS. - * This flag removes the ciphersuites based on RC4 from the default list as - * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible to - * enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including them - * explicitly. - * - * Uncomment this macro to remove RC4 ciphersuites by default. - */ -#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES - -/** - * \def MBEDTLS_REMOVE_3DES_CIPHERSUITES - * - * Remove 3DES ciphersuites by default in SSL / TLS. - * This flag removes the ciphersuites based on 3DES from the default list as - * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible - * to enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including - * them explicitly. - * - * A man-in-the-browser attacker can recover authentication tokens sent through - * a TLS connection using a 3DES based cipher suite (see "On the Practical - * (In-)Security of 64-bit Block Ciphers" by Karthikeyan Bhargavan and Gaëtan - * Leurent, see https://sweet32.info/SWEET32_CCS16.pdf). If this attack falls - * in your threat model or you are unsure, then you should keep this option - * enabled to remove 3DES based cipher suites. - * - * Comment this macro to keep 3DES in the default ciphersuite list. - */ -#define MBEDTLS_REMOVE_3DES_CIPHERSUITES - -/** - * Enable the verified implementations of ECDH primitives from Project Everest - * (currently only Curve25519). This feature changes the layout of ECDH - * contexts and therefore is a compatibility break for applications that access - * fields of a mbedtls_ecdh_context structure directly. See also - * MBEDTLS_ECDH_LEGACY_CONTEXT in include/mbedtls/ecdh.h. - * - * The Everest code is provided under the Apache 2.0 license only; therefore enabling this - * option is not compatible with taking the library under the GPL v2.0-or-later license. - */ -//#define MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED - -/** - * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED - * - * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve - * module. By default all supported curves are enabled. - * - * Comment macros to disable the curve and functions for it - */ -/* Short Weierstrass curves (supporting ECP, ECDH, ECDSA) */ -#define MBEDTLS_ECP_DP_SECP192R1_ENABLED -#define MBEDTLS_ECP_DP_SECP224R1_ENABLED -#define MBEDTLS_ECP_DP_SECP256R1_ENABLED -#define MBEDTLS_ECP_DP_SECP384R1_ENABLED -#define MBEDTLS_ECP_DP_SECP521R1_ENABLED -#define MBEDTLS_ECP_DP_SECP192K1_ENABLED -#define MBEDTLS_ECP_DP_SECP224K1_ENABLED -#define MBEDTLS_ECP_DP_SECP256K1_ENABLED -#define MBEDTLS_ECP_DP_BP256R1_ENABLED -#define MBEDTLS_ECP_DP_BP384R1_ENABLED -#define MBEDTLS_ECP_DP_BP512R1_ENABLED -/* Montgomery curves (supporting ECP) */ -#define MBEDTLS_ECP_DP_CURVE25519_ENABLED -#define MBEDTLS_ECP_DP_CURVE448_ENABLED - -/** - * \def MBEDTLS_ECP_NIST_OPTIM - * - * Enable specific 'modulo p' routines for each NIST prime. - * Depending on the prime and architecture, makes operations 4 to 8 times - * faster on the corresponding curve. - * - * Comment this macro to disable NIST curves optimisation. - */ -#define MBEDTLS_ECP_NIST_OPTIM - -/** - * \def MBEDTLS_ECP_NO_INTERNAL_RNG - * - * When this option is disabled, mbedtls_ecp_mul() will make use of an - * internal RNG when called with a NULL \c f_rng argument, in order to protect - * against some side-channel attacks. - * - * This protection introduces a dependency of the ECP module on one of the - * DRBG modules. For very constrained implementations that don't require this - * protection (for example, because you're only doing signature verification, - * so not manipulating any secret, or because local/physical side-channel - * attacks are outside your threat model), it might be desirable to get rid of - * that dependency. - * - * \warning Enabling this option makes some uses of ECP vulnerable to some - * side-channel attacks. Only enable it if you know that's not a problem for - * your use case. - * - * Uncomment this macro to disable some counter-measures in ECP. - */ -//#define MBEDTLS_ECP_NO_INTERNAL_RNG - -/** - * \def MBEDTLS_ECP_RESTARTABLE - * - * Enable "non-blocking" ECC operations that can return early and be resumed. - * - * This allows various functions to pause by returning - * #MBEDTLS_ERR_ECP_IN_PROGRESS (or, for functions in the SSL module, - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) and then be called later again in - * order to further progress and eventually complete their operation. This is - * controlled through mbedtls_ecp_set_max_ops() which limits the maximum - * number of ECC operations a function may perform before pausing; see - * mbedtls_ecp_set_max_ops() for more information. - * - * This is useful in non-threaded environments if you want to avoid blocking - * for too long on ECC (and, hence, X.509 or SSL/TLS) operations. - * - * This option: - * - Adds xxx_restartable() variants of existing operations in the - * following modules, with corresponding restart context types: - * - ECP (for Short Weierstrass curves only): scalar multiplication (mul), - * linear combination (muladd); - * - ECDSA: signature generation & verification; - * - PK: signature generation & verification; - * - X509: certificate chain verification. - * - Adds mbedtls_ecdh_enable_restart() in the ECDH module. - * - Changes the behaviour of TLS 1.2 clients (not servers) when using the - * ECDHE-ECDSA key exchange (not other key exchanges) to make all ECC - * computations restartable: - * - ECDH operations from the key exchange, only for Short Weierstrass - * curves; - * - verification of the server's key exchange signature; - * - verification of the server's certificate chain; - * - generation of the client's signature if client authentication is used, - * with an ECC key/certificate. - * - * \note In the cases above, the usual SSL/TLS functions, such as - * mbedtls_ssl_handshake(), can now return - * MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS. - * - * \note This option only works with the default software implementation of - * elliptic curve functionality. It is incompatible with - * MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT, MBEDTLS_ECDSA_XXX_ALT, - * MBEDTLS_ECDH_LEGACY_CONTEXT, and MBEDTLS_USE_PSA_CRYPTO. - * - * Requires: MBEDTLS_ECP_C - * - * Uncomment this macro to enable restartable ECC computations. - */ -//#define MBEDTLS_ECP_RESTARTABLE - -/** - * \def MBEDTLS_ECDH_LEGACY_CONTEXT - * - * Use a backward compatible ECDH context. - * - * Mbed TLS supports two formats for ECDH contexts (#mbedtls_ecdh_context - * defined in `ecdh.h`). For most applications, the choice of format makes - * no difference, since all library functions can work with either format, - * except that the new format is incompatible with MBEDTLS_ECP_RESTARTABLE. - - * The new format used when this option is disabled is smaller - * (56 bytes on a 32-bit platform). In future versions of the library, it - * will support alternative implementations of ECDH operations. - * The new format is incompatible with applications that access - * context fields directly and with restartable ECP operations. - * - * Define this macro if you enable MBEDTLS_ECP_RESTARTABLE or if you - * want to access ECDH context fields directly. Otherwise you should - * comment out this macro definition. - * - * This option has no effect if #MBEDTLS_ECDH_C is not enabled. - * - * \note This configuration option is experimental. Future versions of the - * library may modify the way the ECDH context layout is configured - * and may modify the layout of the new context type. - */ -//#define MBEDTLS_ECDH_LEGACY_CONTEXT - -/** - * \def MBEDTLS_ECDSA_DETERMINISTIC - * - * Enable deterministic ECDSA (RFC 6979). - * Standard ECDSA is "fragile" in the sense that lack of entropy when signing - * may result in a compromise of the long-term signing key. This is avoided by - * the deterministic variant. - * - * Requires: MBEDTLS_HMAC_DRBG_C, MBEDTLS_ECDSA_C - * - * Comment this macro to disable deterministic ECDSA. - */ -#define MBEDTLS_ECDSA_DETERMINISTIC - -/** - * \def MBEDTLS_KEY_EXCHANGE_PSK_ENABLED - * - * Enable the PSK based ciphersuite modes in SSL / TLS. - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_RC4_128_SHA - */ -#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED - * - * Enable the DHE-PSK based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_DHM_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA - * - * \warning Using DHE constitutes a security risk as it - * is not possible to validate custom DH parameters. - * If possible, it is recommended users should consider - * preferring other methods of key exchange. - * See dhm.h for more details. - * - */ -#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED - * - * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA - */ -#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED - * - * Enable the RSA-PSK based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA - */ -#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_RSA_ENABLED - * - * Enable the RSA-only based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 - */ -#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED - * - * Enable the DHE-RSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_DHM_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA - * - * \warning Using DHE constitutes a security risk as it - * is not possible to validate custom DH parameters. - * If possible, it is recommended users should consider - * preferring other methods of key exchange. - * See dhm.h for more details. - * - */ -#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED - * - * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA - */ -#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED - * - * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C, - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA - */ -#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED - * - * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - */ -#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED - * - * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 - */ -#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED - * - * Enable the ECJPAKE based ciphersuite modes in SSL / TLS. - * - * \warning This is currently experimental. EC J-PAKE support is based on the - * Thread v1.0.0 specification; incompatible changes to the specification - * might still happen. For this reason, this is disabled by default. - * - * Requires: MBEDTLS_ECJPAKE_C - * MBEDTLS_SHA256_C - * MBEDTLS_ECP_DP_SECP256R1_ENABLED - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 - */ -//#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED - -/** - * \def MBEDTLS_PK_PARSE_EC_EXTENDED - * - * Enhance support for reading EC keys using variants of SEC1 not allowed by - * RFC 5915 and RFC 5480. - * - * Currently this means parsing the SpecifiedECDomain choice of EC - * parameters (only known groups are supported, not arbitrary domains, to - * avoid validation issues). - * - * Disable if you only need to support RFC 5915 + 5480 key formats. - */ -#define MBEDTLS_PK_PARSE_EC_EXTENDED - -/** - * \def MBEDTLS_ERROR_STRERROR_DUMMY - * - * Enable a dummy error function to make use of mbedtls_strerror() in - * third party libraries easier when MBEDTLS_ERROR_C is disabled - * (no effect when MBEDTLS_ERROR_C is enabled). - * - * You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're - * not using mbedtls_strerror() or error_strerror() in your application. - * - * Disable if you run into name conflicts and want to really remove the - * mbedtls_strerror() - */ -#define MBEDTLS_ERROR_STRERROR_DUMMY - -/** - * \def MBEDTLS_GENPRIME - * - * Enable the prime-number generation code. - * - * Requires: MBEDTLS_BIGNUM_C - */ -#define MBEDTLS_GENPRIME - -/** - * \def MBEDTLS_FS_IO - * - * Enable functions that use the filesystem. - */ -#define MBEDTLS_FS_IO - -/** - * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES - * - * Do not add default entropy sources. These are the platform specific, - * mbedtls_timing_hardclock and HAVEGE based poll functions. - * - * This is useful to have more control over the added entropy sources in an - * application. - * - * Uncomment this macro to prevent loading of default entropy functions. - */ -//#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES - -/** - * \def MBEDTLS_NO_PLATFORM_ENTROPY - * - * Do not use built-in platform entropy functions. - * This is useful if your platform does not support - * standards like the /dev/urandom or Windows CryptoAPI. - * - * Uncomment this macro to disable the built-in platform entropy functions. - */ -#define MBEDTLS_NO_PLATFORM_ENTROPY //chris.peng - -/** - * \def MBEDTLS_ENTROPY_FORCE_SHA256 - * - * Force the entropy accumulator to use a SHA-256 accumulator instead of the - * default SHA-512 based one (if both are available). - * - * Requires: MBEDTLS_SHA256_C - * - * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option - * if you have performance concerns. - * - * This option is only useful if both MBEDTLS_SHA256_C and - * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used. - */ -//#define MBEDTLS_ENTROPY_FORCE_SHA256 - -/** - * \def MBEDTLS_ENTROPY_NV_SEED - * - * Enable the non-volatile (NV) seed file-based entropy source. - * (Also enables the NV seed read/write functions in the platform layer) - * - * This is crucial (if not required) on systems that do not have a - * cryptographic entropy source (in hardware or kernel) available. - * - * Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C - * - * \note The read/write functions that are used by the entropy source are - * determined in the platform layer, and can be modified at runtime and/or - * compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used. - * - * \note If you use the default implementation functions that read a seedfile - * with regular fopen(), please make sure you make a seedfile with the - * proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at - * least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from - * and written to or you will get an entropy source error! The default - * implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE - * bytes from the file. - * - * \note The entropy collector will write to the seed file before entropy is - * given to an external source, to update it. - */ -//#define MBEDTLS_ENTROPY_NV_SEED - -/* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER - * - * Enable key identifiers that encode a key owner identifier. - * - * The owner of a key is identified by a value of type ::mbedtls_key_owner_id_t - * which is currently hard-coded to be int32_t. - * - * Note that this option is meant for internal use only and may be removed - * without notice. It is incompatible with MBEDTLS_USE_PSA_CRYPTO. - */ -//#define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER - -/** - * \def MBEDTLS_MEMORY_DEBUG - * - * Enable debugging of buffer allocator memory issues. Automatically prints - * (to stderr) all (fatal) messages on memory allocation issues. Enables - * function for 'debug output' of allocated memory. - * - * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C - * - * Uncomment this macro to let the buffer allocator print out error messages. - */ -//#define MBEDTLS_MEMORY_DEBUG - -/** - * \def MBEDTLS_MEMORY_BACKTRACE - * - * Include backtrace information with each allocated block. - * - * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C - * GLIBC-compatible backtrace() and backtrace_symbols() support - * - * Uncomment this macro to include backtrace information - */ -//#define MBEDTLS_MEMORY_BACKTRACE - -/** - * \def MBEDTLS_PK_RSA_ALT_SUPPORT - * - * Support external private RSA keys (eg from a HSM) in the PK layer. - * - * Comment this macro to disable support for external private RSA keys. - */ -#define MBEDTLS_PK_RSA_ALT_SUPPORT - -/** - * \def MBEDTLS_PKCS1_V15 - * - * Enable support for PKCS#1 v1.5 encoding. - * - * Requires: MBEDTLS_RSA_C - * - * This enables support for PKCS#1 v1.5 operations. - */ -#define MBEDTLS_PKCS1_V15 - -/** - * \def MBEDTLS_PKCS1_V21 - * - * Enable support for PKCS#1 v2.1 encoding. - * - * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C - * - * This enables support for RSAES-OAEP and RSASSA-PSS operations. - */ -#define MBEDTLS_PKCS1_V21 - -/** \def MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS - * - * Enable support for platform built-in keys. If you enable this feature, - * you must implement the function mbedtls_psa_platform_get_builtin_key(). - * See the documentation of that function for more information. - * - * Built-in keys are typically derived from a hardware unique key or - * stored in a secure element. - * - * Requires: MBEDTLS_PSA_CRYPTO_C. - * - * \warning This interface is experimental and may change or be removed - * without notice. - */ -//#define MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS - -/** \def MBEDTLS_PSA_CRYPTO_CLIENT - * - * Enable support for PSA crypto client. - * - * \note This option allows to include the code necessary for a PSA - * crypto client when the PSA crypto implementation is not included in - * the library (MBEDTLS_PSA_CRYPTO_C disabled). The code included is the - * code to set and get PSA key attributes. - * The development of PSA drivers partially relying on the library to - * fulfill the hardware gaps is another possible usage of this option. - * - * \warning This interface is experimental and may change or be removed - * without notice. - */ -//#define MBEDTLS_PSA_CRYPTO_CLIENT - -/** \def MBEDTLS_PSA_CRYPTO_DRIVERS - * - * Enable support for the experimental PSA crypto driver interface. - * - * Requires: MBEDTLS_PSA_CRYPTO_C - * - * \warning This interface is experimental and may change or be removed - * without notice. - */ -//#define MBEDTLS_PSA_CRYPTO_DRIVERS - -/** \def MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG - * - * Make the PSA Crypto module use an external random generator provided - * by a driver, instead of Mbed TLS's entropy and DRBG modules. - * - * \note This random generator must deliver random numbers with cryptographic - * quality and high performance. It must supply unpredictable numbers - * with a uniform distribution. The implementation of this function - * is responsible for ensuring that the random generator is seeded - * with sufficient entropy. If you have a hardware TRNG which is slow - * or delivers non-uniform output, declare it as an entropy source - * with mbedtls_entropy_add_source() instead of enabling this option. - * - * If you enable this option, you must configure the type - * ::mbedtls_psa_external_random_context_t in psa/crypto_platform.h - * and define a function called mbedtls_psa_external_get_random() - * with the following prototype: - * ``` - * psa_status_t mbedtls_psa_external_get_random( - * mbedtls_psa_external_random_context_t *context, - * uint8_t *output, size_t output_size, size_t *output_length); - * ); - * ``` - * The \c context value is initialized to 0 before the first call. - * The function must fill the \c output buffer with \c output_size bytes - * of random data and set \c *output_length to \c output_size. - * - * Requires: MBEDTLS_PSA_CRYPTO_C - * - * \warning If you enable this option, code that uses the PSA cryptography - * interface will not use any of the entropy sources set up for - * the entropy module, nor the NV seed that MBEDTLS_ENTROPY_NV_SEED - * enables. - * - * \note This option is experimental and may be removed without notice. - */ -//#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG - -/** - * \def MBEDTLS_PSA_CRYPTO_SPM - * - * When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is built for SPM (Secure - * Partition Manager) integration which separates the code into two parts: a - * NSPE (Non-Secure Process Environment) and an SPE (Secure Process - * Environment). - * - * Module: library/psa_crypto.c - * Requires: MBEDTLS_PSA_CRYPTO_C - * - */ -//#define MBEDTLS_PSA_CRYPTO_SPM - -/** - * \def MBEDTLS_PSA_INJECT_ENTROPY - * - * Enable support for entropy injection at first boot. This feature is - * required on systems that do not have a built-in entropy source (TRNG). - * This feature is currently not supported on systems that have a built-in - * entropy source. - * - * Requires: MBEDTLS_PSA_CRYPTO_STORAGE_C, MBEDTLS_ENTROPY_NV_SEED - * - */ -//#define MBEDTLS_PSA_INJECT_ENTROPY - -/** - * \def MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS - * - * Assume all buffers passed to PSA functions are owned exclusively by the - * PSA function and are not stored in shared memory. - * - * This option may be enabled if all buffers passed to any PSA function reside - * in memory that is accessible only to the PSA function during its execution. - * - * This option MUST be disabled whenever buffer arguments are in memory shared - * with an untrusted party, for example where arguments to PSA calls are passed - * across a trust boundary. - * - * \note Enabling this option reduces memory usage and code size. - * - * \note Enabling this option causes overlap of input and output buffers - * not to be supported by PSA functions. - */ -//#define MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS - -/** - * \def MBEDTLS_RSA_NO_CRT - * - * Do not use the Chinese Remainder Theorem - * for the RSA private operation. - * - * Uncomment this macro to disable the use of CRT in RSA. - * - */ -//#define MBEDTLS_RSA_NO_CRT - -/** - * \def MBEDTLS_SELF_TEST - * - * Enable the checkup functions (*_self_test). - */ -//#define MBEDTLS_SELF_TEST - -/** - * \def MBEDTLS_SHA256_SMALLER - * - * Enable an implementation of SHA-256 that has lower ROM footprint but also - * lower performance. - * - * The default implementation is meant to be a reasonable compromise between - * performance and size. This version optimizes more aggressively for size at - * the expense of performance. Eg on Cortex-M4 it reduces the size of - * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about - * 30%. - * - * Uncomment to enable the smaller implementation of SHA256. - */ -//#define MBEDTLS_SHA256_SMALLER - -/** - * \def MBEDTLS_SHA512_SMALLER - * - * Enable an implementation of SHA-512 that has lower ROM footprint but also - * lower performance. - * - * Uncomment to enable the smaller implementation of SHA512. - */ -//#define MBEDTLS_SHA512_SMALLER - -/** - * \def MBEDTLS_SHA512_NO_SHA384 - * - * Disable the SHA-384 option of the SHA-512 module. Use this to save some - * code size on devices that don't use SHA-384. - * - * Requires: MBEDTLS_SHA512_C - * - * Uncomment to disable SHA-384 - */ -//#define MBEDTLS_SHA512_NO_SHA384 - -/** - * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES - * - * Enable sending of alert messages in case of encountered errors as per RFC. - * If you choose not to send the alert messages, Mbed TLS can still communicate - * with other servers, only debugging of failures is harder. - * - * The advantage of not sending alert messages, is that no information is given - * about reasons for failures thus preventing adversaries of gaining intel. - * - * Enable sending of all alert messages - */ -#define MBEDTLS_SSL_ALL_ALERT_MESSAGES - -/** - * \def MBEDTLS_SSL_RECORD_CHECKING - * - * Enable the function mbedtls_ssl_check_record() which can be used to check - * the validity and authenticity of an incoming record, to verify that it has - * not been seen before. These checks are performed without modifying the - * externally visible state of the SSL context. - * - * See mbedtls_ssl_check_record() for more information. - * - * Uncomment to enable support for record checking. - */ -#define MBEDTLS_SSL_RECORD_CHECKING - -/** - * \def MBEDTLS_SSL_DTLS_CONNECTION_ID - * - * Enable support for the DTLS Connection ID extension - * (version draft-ietf-tls-dtls-connection-id-05, - * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05) - * which allows to identify DTLS connections across changes - * in the underlying transport. - * - * Setting this option enables the SSL APIs `mbedtls_ssl_set_cid()`, - * `mbedtls_ssl_get_peer_cid()` and `mbedtls_ssl_conf_cid()`. - * See the corresponding documentation for more information. - * - * \warning The Connection ID extension is still in draft state. - * We make no stability promises for the availability - * or the shape of the API controlled by this option. - * - * The maximum lengths of outgoing and incoming CIDs can be configured - * through the options - * - MBEDTLS_SSL_CID_OUT_LEN_MAX - * - MBEDTLS_SSL_CID_IN_LEN_MAX. - * - * Requires: MBEDTLS_SSL_PROTO_DTLS - * - * Uncomment to enable the Connection ID extension. - */ -//#define MBEDTLS_SSL_DTLS_CONNECTION_ID - -/** - * \def MBEDTLS_SSL_ASYNC_PRIVATE - * - * Enable asynchronous external private key operations in SSL. This allows - * you to configure an SSL connection to call an external cryptographic - * module to perform private key operations instead of performing the - * operation inside the library. - * - */ -//#define MBEDTLS_SSL_ASYNC_PRIVATE - -/** - * \def MBEDTLS_SSL_CONTEXT_SERIALIZATION - * - * Enable serialization of the TLS context structures, through use of the - * functions mbedtls_ssl_context_save() and mbedtls_ssl_context_load(). - * - * This pair of functions allows one side of a connection to serialize the - * context associated with the connection, then free or re-use that context - * while the serialized state is persisted elsewhere, and finally deserialize - * that state to a live context for resuming read/write operations on the - * connection. From a protocol perspective, the state of the connection is - * unaffected, in particular this is entirely transparent to the peer. - * - * Note: this is distinct from TLS session resumption, which is part of the - * protocol and fully visible by the peer. TLS session resumption enables - * establishing new connections associated to a saved session with shorter, - * lighter handshakes, while context serialization is a local optimization in - * handling a single, potentially long-lived connection. - * - * Enabling these APIs makes some SSL structures larger, as 64 extra bytes are - * saved after the handshake to allow for more efficient serialization, so if - * you don't need this feature you'll save RAM by disabling it. - * - * Requires: MBEDTLS_GCM_C or MBEDTLS_CCM_C or MBEDTLS_CHACHAPOLY_C - * - * Comment to disable the context serialization APIs. - */ -#define MBEDTLS_SSL_CONTEXT_SERIALIZATION - -/** - * \def MBEDTLS_SSL_DEBUG_ALL - * - * Enable the debug messages in SSL module for all issues. - * Debug messages have been disabled in some places to prevent timing - * attacks due to (unbalanced) debugging function calls. - * - * If you need all error reporting you should enable this during debugging, - * but remove this for production servers that should log as well. - * - * Uncomment this macro to report all debug messages on errors introducing - * a timing side-channel. - * - */ -//#define MBEDTLS_SSL_DEBUG_ALL - -/** \def MBEDTLS_SSL_ENCRYPT_THEN_MAC - * - * Enable support for Encrypt-then-MAC, RFC 7366. - * - * This allows peers that both support it to use a more robust protection for - * ciphersuites using CBC, providing deep resistance against timing attacks - * on the padding or underlying cipher. - * - * This only affects CBC ciphersuites, and is useless if none is defined. - * - * Requires: MBEDTLS_SSL_PROTO_TLS1 or - * MBEDTLS_SSL_PROTO_TLS1_1 or - * MBEDTLS_SSL_PROTO_TLS1_2 - * - * Comment this macro to disable support for Encrypt-then-MAC - */ -#define MBEDTLS_SSL_ENCRYPT_THEN_MAC - -/** \def MBEDTLS_SSL_EXTENDED_MASTER_SECRET - * - * Enable support for RFC 7627: Session Hash and Extended Master Secret - * Extension. - * - * This was introduced as "the proper fix" to the Triple Handshake family of - * attacks, but it is recommended to always use it (even if you disable - * renegotiation), since it actually fixes a more fundamental issue in the - * original SSL/TLS design, and has implications beyond Triple Handshake. - * - * Requires: MBEDTLS_SSL_PROTO_TLS1 or - * MBEDTLS_SSL_PROTO_TLS1_1 or - * MBEDTLS_SSL_PROTO_TLS1_2 - * - * Comment this macro to disable support for Extended Master Secret. - */ -#define MBEDTLS_SSL_EXTENDED_MASTER_SECRET - -/** - * \def MBEDTLS_SSL_FALLBACK_SCSV - * - * Enable support for RFC 7507: Fallback Signaling Cipher Suite Value (SCSV) - * for Preventing Protocol Downgrade Attacks. - * - * For servers, it is recommended to always enable this, unless you support - * only one version of TLS, or know for sure that none of your clients - * implements a fallback strategy. - * - * For clients, you only need this if you're using a fallback strategy, which - * is not recommended in the first place, unless you absolutely need it to - * interoperate with buggy (version-intolerant) servers. - * - * Comment this macro to disable support for FALLBACK_SCSV - */ -#define MBEDTLS_SSL_FALLBACK_SCSV - -/** - * \def MBEDTLS_SSL_KEEP_PEER_CERTIFICATE - * - * This option controls the availability of the API mbedtls_ssl_get_peer_cert() - * giving access to the peer's certificate after completion of the handshake. - * - * Unless you need mbedtls_ssl_peer_cert() in your application, it is - * recommended to disable this option for reduced RAM usage. - * - * \note If this option is disabled, mbedtls_ssl_get_peer_cert() is still - * defined, but always returns \c NULL. - * - * \note This option has no influence on the protection against the - * triple handshake attack. Even if it is disabled, Mbed TLS will - * still ensure that certificates do not change during renegotiation, - * for example by keeping a hash of the peer's certificate. - * - * Comment this macro to disable storing the peer's certificate - * after the handshake. - */ -#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE - -/** - * \def MBEDTLS_SSL_HW_RECORD_ACCEL - * - * Enable hooking functions in SSL module for hardware acceleration of - * individual records. - * - * \deprecated This option is deprecated and will be removed in a future - * version of Mbed TLS. - * - * Uncomment this macro to enable hooking functions. - */ -//#define MBEDTLS_SSL_HW_RECORD_ACCEL - -/** - * \def MBEDTLS_SSL_CBC_RECORD_SPLITTING - * - * Enable 1/n-1 record splitting for CBC mode in SSLv3 and TLS 1.0. - * - * This is a countermeasure to the BEAST attack, which also minimizes the risk - * of interoperability issues compared to sending 0-length records. - * - * Comment this macro to disable 1/n-1 record splitting. - */ -#define MBEDTLS_SSL_CBC_RECORD_SPLITTING - -/** - * \def MBEDTLS_SSL_RENEGOTIATION - * - * Enable support for TLS renegotiation. - * - * The two main uses of renegotiation are (1) refresh keys on long-lived - * connections and (2) client authentication after the initial handshake. - * If you don't need renegotiation, it's probably better to disable it, since - * it has been associated with security issues in the past and is easy to - * misuse/misunderstand. - * - * Comment this to disable support for renegotiation. - * - * \note Even if this option is disabled, both client and server are aware - * of the Renegotiation Indication Extension (RFC 5746) used to - * prevent the SSL renegotiation attack (see RFC 5746 Sect. 1). - * (See \c mbedtls_ssl_conf_legacy_renegotiation for the - * configuration of this extension). - * - */ -#define MBEDTLS_SSL_RENEGOTIATION - -/** - * \def MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO - * - * Enable support for receiving and parsing SSLv2 Client Hello messages for the - * SSL Server module (MBEDTLS_SSL_SRV_C). - * - * \deprecated This option is deprecated and will be removed in a future - * version of Mbed TLS. - * - * Uncomment this macro to enable support for SSLv2 Client Hello messages. - */ -//#define MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO - -/** - * \def MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE - * - * Pick the ciphersuite according to the client's preferences rather than ours - * in the SSL Server module (MBEDTLS_SSL_SRV_C). - * - * Uncomment this macro to respect client's ciphersuite order - */ -//#define MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE - -/** - * \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH - * - * Enable support for RFC 6066 max_fragment_length extension in SSL. - * - * Comment this macro to disable support for the max_fragment_length extension - */ -#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH - -/** - * \def MBEDTLS_SSL_PROTO_SSL3 - * - * Enable support for SSL 3.0. - * - * Requires: MBEDTLS_MD5_C - * MBEDTLS_SHA1_C - * - * \deprecated This option is deprecated and will be removed in a future - * version of Mbed TLS. - * - * Comment this macro to disable support for SSL 3.0 - */ -//#define MBEDTLS_SSL_PROTO_SSL3 - -/** - * \def MBEDTLS_SSL_PROTO_TLS1 - * - * Enable support for TLS 1.0. - * - * Requires: MBEDTLS_MD5_C - * MBEDTLS_SHA1_C - * - * Comment this macro to disable support for TLS 1.0 - */ -#define MBEDTLS_SSL_PROTO_TLS1 - -/** - * \def MBEDTLS_SSL_PROTO_TLS1_1 - * - * Enable support for TLS 1.1 (and DTLS 1.0 if DTLS is enabled). - * - * Requires: MBEDTLS_MD5_C - * MBEDTLS_SHA1_C - * - * Comment this macro to disable support for TLS 1.1 / DTLS 1.0 - */ -#define MBEDTLS_SSL_PROTO_TLS1_1 - -/** - * \def MBEDTLS_SSL_PROTO_TLS1_2 - * - * Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled). - * - * Requires: MBEDTLS_SHA1_C or MBEDTLS_SHA256_C or MBEDTLS_SHA512_C - * (Depends on ciphersuites) - * - * Comment this macro to disable support for TLS 1.2 / DTLS 1.2 - */ -#define MBEDTLS_SSL_PROTO_TLS1_2 - -/** - * \def MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL - * - * This macro is used to selectively enable experimental parts - * of the code that contribute to the ongoing development of - * the prototype TLS 1.3 and DTLS 1.3 implementation, and provide - * no other purpose. - * - * \warning TLS 1.3 and DTLS 1.3 aren't yet supported in Mbed TLS, - * and no feature exposed through this macro is part of the - * public API. In particular, features under the control - * of this macro are experimental and don't come with any - * stability guarantees. - * - * Uncomment this macro to enable experimental and partial - * functionality specific to TLS 1.3. - */ -//#define MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL - -/** - * \def MBEDTLS_SSL_PROTO_DTLS - * - * Enable support for DTLS (all available versions). - * - * Enable this and MBEDTLS_SSL_PROTO_TLS1_1 to enable DTLS 1.0, - * and/or this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2. - * - * Requires: MBEDTLS_SSL_PROTO_TLS1_1 - * or MBEDTLS_SSL_PROTO_TLS1_2 - * - * Comment this macro to disable support for DTLS - */ -#define MBEDTLS_SSL_PROTO_DTLS - -/** - * \def MBEDTLS_SSL_ALPN - * - * Enable support for RFC 7301 Application Layer Protocol Negotiation. - * - * Comment this macro to disable support for ALPN. - */ -#define MBEDTLS_SSL_ALPN - -/** - * \def MBEDTLS_SSL_DTLS_ANTI_REPLAY - * - * Enable support for the anti-replay mechanism in DTLS. - * - * Requires: MBEDTLS_SSL_TLS_C - * MBEDTLS_SSL_PROTO_DTLS - * - * \warning Disabling this is often a security risk! - * See mbedtls_ssl_conf_dtls_anti_replay() for details. - * - * Comment this to disable anti-replay in DTLS. - */ -#define MBEDTLS_SSL_DTLS_ANTI_REPLAY - -/** - * \def MBEDTLS_SSL_DTLS_HELLO_VERIFY - * - * Enable support for HelloVerifyRequest on DTLS servers. - * - * This feature is highly recommended to prevent DTLS servers being used as - * amplifiers in DoS attacks against other hosts. It should always be enabled - * unless you know for sure amplification cannot be a problem in the - * environment in which your server operates. - * - * \warning Disabling this can be a security risk! (see above) - * - * Requires: MBEDTLS_SSL_PROTO_DTLS - * - * Comment this to disable support for HelloVerifyRequest. - */ -#define MBEDTLS_SSL_DTLS_HELLO_VERIFY - -/** - * \def MBEDTLS_SSL_DTLS_SRTP - * - * Enable support for negotiation of DTLS-SRTP (RFC 5764) - * through the use_srtp extension. - * - * \note This feature provides the minimum functionality required - * to negotiate the use of DTLS-SRTP and to allow the derivation of - * the associated SRTP packet protection key material. - * In particular, the SRTP packet protection itself, as well as the - * demultiplexing of RTP and DTLS packets at the datagram layer - * (see Section 5 of RFC 5764), are not handled by this feature. - * Instead, after successful completion of a handshake negotiating - * the use of DTLS-SRTP, the extended key exporter API - * mbedtls_ssl_conf_export_keys_ext_cb() should be used to implement - * the key exporter described in Section 4.2 of RFC 5764 and RFC 5705 - * (this is implemented in the SSL example programs). - * The resulting key should then be passed to an SRTP stack. - * - * Setting this option enables the runtime API - * mbedtls_ssl_conf_dtls_srtp_protection_profiles() - * through which the supported DTLS-SRTP protection - * profiles can be configured. You must call this API at - * runtime if you wish to negotiate the use of DTLS-SRTP. - * - * Requires: MBEDTLS_SSL_PROTO_DTLS - * - * Uncomment this to enable support for use_srtp extension. - */ -//#define MBEDTLS_SSL_DTLS_SRTP - -/** - * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE - * - * Enable server-side support for clients that reconnect from the same port. - * - * Some clients unexpectedly close the connection and try to reconnect using the - * same source port. This needs special support from the server to handle the - * new connection securely, as described in section 4.2.8 of RFC 6347. This - * flag enables that support. - * - * Requires: MBEDTLS_SSL_DTLS_HELLO_VERIFY - * - * Comment this to disable support for clients reusing the source port. - */ -#define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE - -/** - * \def MBEDTLS_SSL_DTLS_BADMAC_LIMIT - * - * Enable support for a limit of records with bad MAC. - * - * See mbedtls_ssl_conf_dtls_badmac_limit(). - * - * Requires: MBEDTLS_SSL_PROTO_DTLS - */ -#define MBEDTLS_SSL_DTLS_BADMAC_LIMIT - -/** - * \def MBEDTLS_SSL_SESSION_TICKETS - * - * Enable support for RFC 5077 session tickets in SSL. - * Client-side, provides full support for session tickets (maintenance of a - * session store remains the responsibility of the application, though). - * Server-side, you also need to provide callbacks for writing and parsing - * tickets, including authenticated encryption and key management. Example - * callbacks are provided by MBEDTLS_SSL_TICKET_C. - * - * Comment this macro to disable support for SSL session tickets - */ -#define MBEDTLS_SSL_SESSION_TICKETS - -/** - * \def MBEDTLS_SSL_EXPORT_KEYS - * - * Enable support for exporting key block and master secret. - * This is required for certain users of TLS, e.g. EAP-TLS. - * - * Comment this macro to disable support for key export - */ -#define MBEDTLS_SSL_EXPORT_KEYS - -/** - * \def MBEDTLS_SSL_SERVER_NAME_INDICATION - * - * Enable support for RFC 6066 server name indication (SNI) in SSL. - * - * Requires: MBEDTLS_X509_CRT_PARSE_C - * - * Comment this macro to disable support for server name indication in SSL - */ -#define MBEDTLS_SSL_SERVER_NAME_INDICATION - -/** - * \def MBEDTLS_SSL_TRUNCATED_HMAC - * - * Enable support for RFC 6066 truncated HMAC in SSL. - * - * Comment this macro to disable support for truncated HMAC in SSL - */ -#define MBEDTLS_SSL_TRUNCATED_HMAC - -/** - * \def MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT - * - * Fallback to old (pre-2.7), non-conforming implementation of the truncated - * HMAC extension which also truncates the HMAC key. Note that this option is - * only meant for a transitory upgrade period and will be removed in a future - * version of the library. - * - * \warning The old implementation is non-compliant and has a security weakness - * (2^80 brute force attack on the HMAC key used for a single, - * uninterrupted connection). This should only be enabled temporarily - * when (1) the use of truncated HMAC is essential in order to save - * bandwidth, and (2) the peer is an Mbed TLS stack that doesn't use - * the fixed implementation yet (pre-2.7). - * - * \deprecated This option is deprecated and will be removed in a - * future version of Mbed TLS. - * - * Uncomment to fallback to old, non-compliant truncated HMAC implementation. - * - * Requires: MBEDTLS_SSL_TRUNCATED_HMAC - */ -//#define MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT - -/** - * \def MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH - * - * When this option is enabled, the SSL buffer will be resized automatically - * based on the negotiated maximum fragment length in each direction. - * - * Requires: MBEDTLS_SSL_MAX_FRAGMENT_LENGTH - */ -//#define MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH - -/** - * Allow SHA-1 in the default TLS configuration for TLS 1.2 handshake - * signature and ciphersuite selection. Without this build-time option, SHA-1 - * support must be activated explicitly through mbedtls_ssl_conf_sig_hashes. - * The use of SHA-1 in TLS <= 1.1 and in HMAC-SHA-1 is always allowed by - * default. At the time of writing, there is no practical attack on the use - * of SHA-1 in handshake signatures, hence this option is turned on by default - * to preserve compatibility with existing peers, but the general - * warning applies nonetheless: - * - * \warning SHA-1 is considered a weak message digest and its use constitutes - * a security risk. If possible, we recommend avoiding dependencies - * on it, and considering stronger message digests instead. - * - */ -//#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE - -/** - * \def MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN - * - * Enable testing of the constant-flow nature of some sensitive functions with - * clang's MemorySanitizer. This causes some existing tests to also test - * this non-functional property of the code under test. - * - * This setting requires compiling with clang -fsanitize=memory. The test - * suites can then be run normally. - * - * \warning This macro is only used for extended testing; it is not considered - * part of the library's API, so it may change or disappear at any time. - * - * Uncomment to enable testing of the constant-flow nature of selected code. - */ -//#define MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN - -/** - * \def MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND - * - * Enable testing of the constant-flow nature of some sensitive functions with - * valgrind's memcheck tool. This causes some existing tests to also test - * this non-functional property of the code under test. - * - * This setting requires valgrind headers for building, and is only useful for - * testing if the tests suites are run with valgrind's memcheck. This can be - * done for an individual test suite with 'valgrind ./test_suite_xxx', or when - * using CMake, this can be done for all test suites with 'make memcheck'. - * - * \warning This macro is only used for extended testing; it is not considered - * part of the library's API, so it may change or disappear at any time. - * - * Uncomment to enable testing of the constant-flow nature of selected code. - */ -//#define MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND - -/** - * \def MBEDTLS_TEST_HOOKS - * - * Enable features for invasive testing such as introspection functions and - * hooks for fault injection. This enables additional unit tests. - * - * Merely enabling this feature should not change the behavior of the product. - * It only adds new code, and new branching points where the default behavior - * is the same as when this feature is disabled. - * However, this feature increases the attack surface: there is an added - * risk of vulnerabilities, and more gadgets that can make exploits easier. - * Therefore this feature must never be enabled in production. - * - * See `docs/architecture/testing/mbed-crypto-invasive-testing.md` for more - * information. - * - * Uncomment to enable invasive tests. - */ -//#define MBEDTLS_TEST_HOOKS - -/** - * \def MBEDTLS_THREADING_ALT - * - * Provide your own alternate threading implementation. - * - * Requires: MBEDTLS_THREADING_C - * - * Uncomment this to allow your own alternate threading implementation. - */ -//#define MBEDTLS_THREADING_ALT - -/** - * \def MBEDTLS_THREADING_PTHREAD - * - * Enable the pthread wrapper layer for the threading layer. - * - * Requires: MBEDTLS_THREADING_C - * - * Uncomment this to enable pthread mutexes. - */ -//#define MBEDTLS_THREADING_PTHREAD - -/** - * \def MBEDTLS_USE_PSA_CRYPTO - * - * Make the X.509 and TLS library use PSA for cryptographic operations, and - * enable new APIs for using keys handled by PSA Crypto. - * - * \note Development of this option is currently in progress, and parts of Mbed - * TLS's X.509 and TLS modules are not ported to PSA yet. However, these parts - * will still continue to work as usual, so enabling this option should not - * break backwards compatibility. - * - * \note See docs/use-psa-crypto.md for a complete description of what this - * option currently does, and of parts that are not affected by it so far. - * - * \warning This option enables new Mbed TLS APIs which are currently - * considered experimental and may change in incompatible ways at any time. - * That is, the APIs enabled by this option are not covered by the usual - * promises of API stability. - * - * Requires: MBEDTLS_PSA_CRYPTO_C. - * - * Uncomment this to enable internal use of PSA Crypto and new associated APIs. - */ -//#define MBEDTLS_USE_PSA_CRYPTO - -/** - * \def MBEDTLS_PSA_CRYPTO_CONFIG - * - * This setting allows support for cryptographic mechanisms through the PSA - * API to be configured separately from support through the mbedtls API. - * - * When this option is disabled, the PSA API exposes the cryptographic - * mechanisms that can be implemented on top of the `mbedtls_xxx` API - * configured with `MBEDTLS_XXX` symbols. - * - * When this option is enabled, the PSA API exposes the cryptographic - * mechanisms requested by the `PSA_WANT_XXX` symbols defined in - * include/psa/crypto_config.h. The corresponding `MBEDTLS_XXX` settings are - * automatically enabled if required (i.e. if no PSA driver provides the - * mechanism). You may still freely enable additional `MBEDTLS_XXX` symbols - * in config.h. - * - * If the symbol #MBEDTLS_PSA_CRYPTO_CONFIG_FILE is defined, it specifies - * an alternative header to include instead of include/psa/crypto_config.h. - * - * If you enable this option and write your own configuration file, you must - * include mbedtls/config_psa.h in your configuration file. The default - * provided mbedtls/config.h contains the necessary inclusion. - * - * This feature is still experimental and is not ready for production since - * it is not completed. - */ -//#define MBEDTLS_PSA_CRYPTO_CONFIG - -/** - * \def MBEDTLS_VERSION_FEATURES - * - * Allow run-time checking of compile-time enabled features. Thus allowing users - * to check at run-time if the library is for instance compiled with threading - * support via mbedtls_version_check_feature(). - * - * Requires: MBEDTLS_VERSION_C - * - * Comment this to disable run-time checking and save ROM space - */ -#define MBEDTLS_VERSION_FEATURES - -/** - * \def MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 - * - * If set, the X509 parser will not break-off when parsing an X509 certificate - * and encountering an extension in a v1 or v2 certificate. - * - * Uncomment to prevent an error. - */ -//#define MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 - -/** - * \def MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION - * - * If set, the X509 parser will not break-off when parsing an X509 certificate - * and encountering an unknown critical extension. - * - * \warning Depending on your PKI use, enabling this can be a security risk! - * - * Uncomment to prevent an error. - */ -//#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION - -/** - * \def MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK - * - * If set, this enables the X.509 API `mbedtls_x509_crt_verify_with_ca_cb()` - * and the SSL API `mbedtls_ssl_conf_ca_cb()` which allow users to configure - * the set of trusted certificates through a callback instead of a linked - * list. - * - * This is useful for example in environments where a large number of trusted - * certificates is present and storing them in a linked list isn't efficient - * enough, or when the set of trusted certificates changes frequently. - * - * See the documentation of `mbedtls_x509_crt_verify_with_ca_cb()` and - * `mbedtls_ssl_conf_ca_cb()` for more information. - * - * Uncomment to enable trusted certificate callbacks. - */ -//#define MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK - -/** - * \def MBEDTLS_X509_CHECK_KEY_USAGE - * - * Enable verification of the keyUsage extension (CA and leaf certificates). - * - * Disabling this avoids problems with mis-issued and/or misused - * (intermediate) CA and leaf certificates. - * - * \warning Depending on your PKI use, disabling this can be a security risk! - * - * Comment to skip keyUsage checking for both CA and leaf certificates. - */ -#define MBEDTLS_X509_CHECK_KEY_USAGE - -/** - * \def MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE - * - * Enable verification of the extendedKeyUsage extension (leaf certificates). - * - * Disabling this avoids problems with mis-issued and/or misused certificates. - * - * \warning Depending on your PKI use, disabling this can be a security risk! - * - * Comment to skip extendedKeyUsage checking for certificates. - */ -#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE - -/** - * \def MBEDTLS_X509_RSASSA_PSS_SUPPORT - * - * Enable parsing and verification of X.509 certificates, CRLs and CSRS - * signed with RSASSA-PSS (aka PKCS#1 v2.1). - * - * Comment this macro to disallow using RSASSA-PSS in certificates. - */ -#define MBEDTLS_X509_RSASSA_PSS_SUPPORT - -/** - * \def MBEDTLS_ZLIB_SUPPORT - * - * If set, the SSL/TLS module uses ZLIB to support compression and - * decompression of packet data. - * - * \warning TLS-level compression MAY REDUCE SECURITY! See for example the - * CRIME attack. Before enabling this option, you should examine with care if - * CRIME or similar exploits may be applicable to your use case. - * - * \note Currently compression can't be used with DTLS. - * - * \deprecated This feature is deprecated and will be removed - * in the next major revision of the library. - * - * Used in: library/ssl_tls.c - * library/ssl_cli.c - * library/ssl_srv.c - * - * This feature requires zlib library and headers to be present. - * - * Uncomment to enable use of ZLIB - */ -//#define MBEDTLS_ZLIB_SUPPORT -/** \} name SECTION: Mbed TLS feature support */ - -/** - * \name SECTION: Mbed TLS modules - * - * This section enables or disables entire modules in Mbed TLS - * \{ - */ - -/** - * \def MBEDTLS_AESNI_C - * - * Enable AES-NI support on x86-64 or x86-32. - * - * \note AESNI is only supported with certain compilers and target options: - * - Visual Studio 2013: supported. - * - GCC, x86-64, target not explicitly supporting AESNI: - * requires MBEDTLS_HAVE_ASM. - * - GCC, x86-32, target not explicitly supporting AESNI: - * not supported. - * - GCC, x86-64 or x86-32, target supporting AESNI: supported. - * For this assembly-less implementation, you must currently compile - * `library/aesni.c` and `library/aes.c` with machine options to enable - * SSE2 and AESNI instructions: `gcc -msse2 -maes -mpclmul` or - * `clang -maes -mpclmul`. - * - Non-x86 targets: this option is silently ignored. - * - Other compilers: this option is silently ignored. - * - * \note - * Above, "GCC" includes compatible compilers such as Clang. - * The limitations on target support are likely to be relaxed in the future. - * - * Module: library/aesni.c - * Caller: library/aes.c - * - * Requires: MBEDTLS_HAVE_ASM (on some platforms, see note) - * - * This modules adds support for the AES-NI instructions on x86. - */ -#define MBEDTLS_AESNI_C - -/** - * \def MBEDTLS_AES_C - * - * Enable the AES block cipher. - * - * Module: library/aes.c - * Caller: library/cipher.c - * library/pem.c - * library/ctr_drbg.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA - * - * PEM_PARSE uses AES for decrypting encrypted keys. - */ -#define MBEDTLS_AES_C - -/** - * \def MBEDTLS_ARC4_C - * - * Enable the ARCFOUR stream cipher. - * - * Module: library/arc4.c - * Caller: library/cipher.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA - * MBEDTLS_TLS_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 - * MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA - * MBEDTLS_TLS_PSK_WITH_RC4_128_SHA - * - * \warning ARC4 is considered a weak cipher and its use constitutes a - * security risk. If possible, we recommend avoiding dependencies on - * it, and considering stronger ciphers instead. - * - */ -#define MBEDTLS_ARC4_C - -/** - * \def MBEDTLS_ASN1_PARSE_C - * - * Enable the generic ASN1 parser. - * - * Module: library/asn1.c - * Caller: library/x509.c - * library/dhm.c - * library/pkcs12.c - * library/pkcs5.c - * library/pkparse.c - */ -#define MBEDTLS_ASN1_PARSE_C - -/** - * \def MBEDTLS_ASN1_WRITE_C - * - * Enable the generic ASN1 writer. - * - * Module: library/asn1write.c - * Caller: library/ecdsa.c - * library/pkwrite.c - * library/x509_create.c - * library/x509write_crt.c - * library/x509write_csr.c - */ -#define MBEDTLS_ASN1_WRITE_C - -/** - * \def MBEDTLS_BASE64_C - * - * Enable the Base64 module. - * - * Module: library/base64.c - * Caller: library/pem.c - * - * This module is required for PEM support (required by X.509). - */ -#define MBEDTLS_BASE64_C - -/** - * \def MBEDTLS_BIGNUM_C - * - * Enable the multi-precision integer library. - * - * Module: library/bignum.c - * Caller: library/dhm.c - * library/ecp.c - * library/ecdsa.c - * library/rsa.c - * library/rsa_internal.c - * library/ssl_tls.c - * - * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. - */ -#define MBEDTLS_BIGNUM_C - -/** - * \def MBEDTLS_BLOWFISH_C - * - * Enable the Blowfish block cipher. - * - * Module: library/blowfish.c - */ -#define MBEDTLS_BLOWFISH_C - -/** - * \def MBEDTLS_CAMELLIA_C - * - * Enable the Camellia block cipher. - * - * Module: library/camellia.c - * Caller: library/cipher.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 - */ -#define MBEDTLS_CAMELLIA_C - -/** - * \def MBEDTLS_ARIA_C - * - * Enable the ARIA block cipher. - * - * Module: library/aria.c - * Caller: library/cipher.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * - * MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 - */ -//#define MBEDTLS_ARIA_C - -/** - * \def MBEDTLS_CCM_C - * - * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher. - * - * Module: library/ccm.c - * - * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C - * - * This module enables the AES-CCM ciphersuites, if other requisites are - * enabled as well. - */ -#define MBEDTLS_CCM_C - -/** - * \def MBEDTLS_CERTS_C - * - * Enable the test certificates. - * - * Module: library/certs.c - * Caller: - * - * This module is used for testing (ssl_client/server). - */ -#define MBEDTLS_CERTS_C - -/** - * \def MBEDTLS_CHACHA20_C - * - * Enable the ChaCha20 stream cipher. - * - * Module: library/chacha20.c - */ -#define MBEDTLS_CHACHA20_C - -/** - * \def MBEDTLS_CHACHAPOLY_C - * - * Enable the ChaCha20-Poly1305 AEAD algorithm. - * - * Module: library/chachapoly.c - * - * This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C - */ -#define MBEDTLS_CHACHAPOLY_C - -/** - * \def MBEDTLS_CIPHER_C - * - * Enable the generic cipher layer. - * - * Module: library/cipher.c - * Caller: library/ssl_tls.c - * - * Uncomment to enable generic cipher wrappers. - */ -#define MBEDTLS_CIPHER_C - -/** - * \def MBEDTLS_CMAC_C - * - * Enable the CMAC (Cipher-based Message Authentication Code) mode for block - * ciphers. - * - * \note When #MBEDTLS_CMAC_ALT is active, meaning that the underlying - * implementation of the CMAC algorithm is provided by an alternate - * implementation, that alternate implementation may opt to not support - * AES-192 or 3DES as underlying block ciphers for the CMAC operation. - * - * Module: library/cmac.c - * - * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C - * - */ -//#define MBEDTLS_CMAC_C - -/** - * \def MBEDTLS_CTR_DRBG_C - * - * Enable the CTR_DRBG AES-based random generator. - * The CTR_DRBG generator uses AES-256 by default. - * To use AES-128 instead, enable \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY above. - * - * \note To achieve a 256-bit security strength with CTR_DRBG, - * you must use AES-256 *and* use sufficient entropy. - * See ctr_drbg.h for more details. - * - * Module: library/ctr_drbg.c - * Caller: - * - * Requires: MBEDTLS_AES_C - * - * This module provides the CTR_DRBG AES random number generator. - */ -#define MBEDTLS_CTR_DRBG_C - -/** - * \def MBEDTLS_DEBUG_C - * - * Enable the debug functions. - * - * Module: library/debug.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * - * This module provides debugging functions. - */ -#define MBEDTLS_DEBUG_C - -/** - * \def MBEDTLS_DES_C - * - * Enable the DES block cipher. - * - * Module: library/des.c - * Caller: library/pem.c - * library/cipher.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA - * - * PEM_PARSE uses DES/3DES for decrypting encrypted keys. - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers instead. - */ -#define MBEDTLS_DES_C - -/** - * \def MBEDTLS_DHM_C - * - * Enable the Diffie-Hellman-Merkle module. - * - * Module: library/dhm.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * - * This module is used by the following key exchanges: - * DHE-RSA, DHE-PSK - * - * \warning Using DHE constitutes a security risk as it - * is not possible to validate custom DH parameters. - * If possible, it is recommended users should consider - * preferring other methods of key exchange. - * See dhm.h for more details. - * - */ -#define MBEDTLS_DHM_C - -/** - * \def MBEDTLS_ECDH_C - * - * Enable the elliptic curve Diffie-Hellman library. - * - * Module: library/ecdh.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * - * This module is used by the following key exchanges: - * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK - * - * Requires: MBEDTLS_ECP_C - */ -#define MBEDTLS_ECDH_C - -/** - * \def MBEDTLS_ECDSA_C - * - * Enable the elliptic curve DSA library. - * - * Module: library/ecdsa.c - * Caller: - * - * This module is used by the following key exchanges: - * ECDHE-ECDSA - * - * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C, - * and at least one MBEDTLS_ECP_DP_XXX_ENABLED for a - * short Weierstrass curve. - */ -#define MBEDTLS_ECDSA_C - -/** - * \def MBEDTLS_ECJPAKE_C - * - * Enable the elliptic curve J-PAKE library. - * - * \warning This is currently experimental. EC J-PAKE support is based on the - * Thread v1.0.0 specification; incompatible changes to the specification - * might still happen. For this reason, this is disabled by default. - * - * Module: library/ecjpake.c - * Caller: - * - * This module is used by the following key exchanges: - * ECJPAKE - * - * Requires: MBEDTLS_ECP_C, MBEDTLS_MD_C - */ -//#define MBEDTLS_ECJPAKE_C - -/** - * \def MBEDTLS_ECP_C - * - * Enable the elliptic curve over GF(p) library. - * - * Module: library/ecp.c - * Caller: library/ecdh.c - * library/ecdsa.c - * library/ecjpake.c - * - * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED - */ -#define MBEDTLS_ECP_C - -/** - * \def MBEDTLS_ENTROPY_C - * - * Enable the platform-specific entropy code. - * - * Module: library/entropy.c - * Caller: - * - * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C - * - * This module provides a generic entropy pool - */ -#define MBEDTLS_ENTROPY_C - -/** - * \def MBEDTLS_ERROR_C - * - * Enable error code to error string conversion. - * - * Module: library/error.c - * Caller: - * - * This module enables mbedtls_strerror(). - */ -#define MBEDTLS_ERROR_C - -/** - * \def MBEDTLS_GCM_C - * - * Enable the Galois/Counter Mode (GCM). - * - * Module: library/gcm.c - * - * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or MBEDTLS_ARIA_C - * - * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other - * requisites are enabled as well. - */ -#define MBEDTLS_GCM_C - -/** - * \def MBEDTLS_HAVEGE_C - * - * Enable the HAVEGE random generator. - * - * Warning: the HAVEGE random generator is not suitable for virtualized - * environments - * - * Warning: the HAVEGE random generator is dependent on timing and specific - * processor traits. It is therefore not advised to use HAVEGE as - * your applications primary random generator or primary entropy pool - * input. As a secondary input to your entropy pool, it IS able add - * the (limited) extra entropy it provides. - * - * Module: library/havege.c - * Caller: - * - * Requires: MBEDTLS_TIMING_C - * - * Uncomment to enable the HAVEGE random generator. - */ -//#define MBEDTLS_HAVEGE_C - -/** - * \def MBEDTLS_HKDF_C - * - * Enable the HKDF algorithm (RFC 5869). - * - * Module: library/hkdf.c - * Caller: - * - * Requires: MBEDTLS_MD_C - * - * This module adds support for the Hashed Message Authentication Code - * (HMAC)-based key derivation function (HKDF). - */ -#define MBEDTLS_HKDF_C - -/** - * \def MBEDTLS_HMAC_DRBG_C - * - * Enable the HMAC_DRBG random generator. - * - * Module: library/hmac_drbg.c - * Caller: - * - * Requires: MBEDTLS_MD_C - * - * Uncomment to enable the HMAC_DRBG random number generator. - */ -#define MBEDTLS_HMAC_DRBG_C - -/** - * \def MBEDTLS_NIST_KW_C - * - * Enable the Key Wrapping mode for 128-bit block ciphers, - * as defined in NIST SP 800-38F. Only KW and KWP modes - * are supported. At the moment, only AES is approved by NIST. - * - * Module: library/nist_kw.c - * - * Requires: MBEDTLS_AES_C and MBEDTLS_CIPHER_C - */ -//#define MBEDTLS_NIST_KW_C - -/** - * \def MBEDTLS_MD_C - * - * Enable the generic message digest layer. - * - * Module: library/md.c - * Caller: - * - * Uncomment to enable generic message digest wrappers. - */ -#define MBEDTLS_MD_C - -/** - * \def MBEDTLS_MD2_C - * - * Enable the MD2 hash algorithm. - * - * Module: library/md2.c - * Caller: - * - * Uncomment to enable support for (rare) MD2-signed X.509 certs. - * - * \warning MD2 is considered a weak message digest and its use constitutes a - * security risk. If possible, we recommend avoiding dependencies on - * it, and considering stronger message digests instead. - * - */ -//#define MBEDTLS_MD2_C - -/** - * \def MBEDTLS_MD4_C - * - * Enable the MD4 hash algorithm. - * - * Module: library/md4.c - * Caller: - * - * Uncomment to enable support for (rare) MD4-signed X.509 certs. - * - * \warning MD4 is considered a weak message digest and its use constitutes a - * security risk. If possible, we recommend avoiding dependencies on - * it, and considering stronger message digests instead. - * - */ -//#define MBEDTLS_MD4_C - -/** - * \def MBEDTLS_MD5_C - * - * Enable the MD5 hash algorithm. - * - * Module: library/md5.c - * Caller: library/md.c - * library/pem.c - * library/ssl_tls.c - * - * This module is required for SSL/TLS up to version 1.1, and for TLS 1.2 - * depending on the handshake parameters. Further, it is used for checking - * MD5-signed certificates, and for PBKDF1 when decrypting PEM-encoded - * encrypted keys. - * - * \warning MD5 is considered a weak message digest and its use constitutes a - * security risk. If possible, we recommend avoiding dependencies on - * it, and considering stronger message digests instead. - * - */ -#define MBEDTLS_MD5_C - -/** - * \def MBEDTLS_MEMORY_BUFFER_ALLOC_C - * - * Enable the buffer allocator implementation that makes use of a (stack) - * based buffer to 'allocate' dynamic memory. (replaces calloc() and free() - * calls) - * - * Module: library/memory_buffer_alloc.c - * - * Requires: MBEDTLS_PLATFORM_C - * MBEDTLS_PLATFORM_MEMORY (to use it within Mbed TLS) - * - * Enable this module to enable the buffer memory allocator. - */ -//#define MBEDTLS_MEMORY_BUFFER_ALLOC_C - -/** - * \def MBEDTLS_NET_C - * - * Enable the TCP and UDP over IPv6/IPv4 networking routines. - * - * \note This module only works on POSIX/Unix (including Linux, BSD and OS X) - * and Windows. For other platforms, you'll want to disable it, and write your - * own networking callbacks to be passed to \c mbedtls_ssl_set_bio(). - * - * \note See also our Knowledge Base article about porting to a new - * environment: - * https://mbed-tls.readthedocs.io/en/latest/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS - * - * Module: library/net_sockets.c - * - * This module provides networking routines. - */ -#define MBEDTLS_NET_C - -/** - * \def MBEDTLS_OID_C - * - * Enable the OID database. - * - * Module: library/oid.c - * Caller: library/asn1write.c - * library/pkcs5.c - * library/pkparse.c - * library/pkwrite.c - * library/rsa.c - * library/x509.c - * library/x509_create.c - * library/x509_crl.c - * library/x509_crt.c - * library/x509_csr.c - * library/x509write_crt.c - * library/x509write_csr.c - * - * This modules translates between OIDs and internal values. - */ -#define MBEDTLS_OID_C - -/** - * \def MBEDTLS_PADLOCK_C - * - * Enable VIA Padlock support on x86. - * - * Module: library/padlock.c - * Caller: library/aes.c - * - * Requires: MBEDTLS_HAVE_ASM - * - * This modules adds support for the VIA PadLock on x86. - */ -#define MBEDTLS_PADLOCK_C - -/** - * \def MBEDTLS_PEM_PARSE_C - * - * Enable PEM decoding / parsing. - * - * Module: library/pem.c - * Caller: library/dhm.c - * library/pkparse.c - * library/x509_crl.c - * library/x509_crt.c - * library/x509_csr.c - * - * Requires: MBEDTLS_BASE64_C - * - * This modules adds support for decoding / parsing PEM files. - */ -#define MBEDTLS_PEM_PARSE_C - -/** - * \def MBEDTLS_PEM_WRITE_C - * - * Enable PEM encoding / writing. - * - * Module: library/pem.c - * Caller: library/pkwrite.c - * library/x509write_crt.c - * library/x509write_csr.c - * - * Requires: MBEDTLS_BASE64_C - * - * This modules adds support for encoding / writing PEM files. - */ -#define MBEDTLS_PEM_WRITE_C - -/** - * \def MBEDTLS_PK_C - * - * Enable the generic public (asymmetric) key layer. - * - * Module: library/pk.c - * Caller: library/ssl_tls.c - * library/ssl_cli.c - * library/ssl_srv.c - * - * Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C - * - * Uncomment to enable generic public key wrappers. - */ -#define MBEDTLS_PK_C - -/** - * \def MBEDTLS_PK_PARSE_C - * - * Enable the generic public (asymmetric) key parser. - * - * Module: library/pkparse.c - * Caller: library/x509_crt.c - * library/x509_csr.c - * - * Requires: MBEDTLS_PK_C - * - * Uncomment to enable generic public key parse functions. - */ -#define MBEDTLS_PK_PARSE_C - -/** - * \def MBEDTLS_PK_WRITE_C - * - * Enable the generic public (asymmetric) key writer. - * - * Module: library/pkwrite.c - * Caller: library/x509write.c - * - * Requires: MBEDTLS_PK_C - * - * Uncomment to enable generic public key write functions. - */ -#define MBEDTLS_PK_WRITE_C - -/** - * \def MBEDTLS_PKCS5_C - * - * Enable PKCS#5 functions. - * - * Module: library/pkcs5.c - * - * Requires: MBEDTLS_MD_C - * - * This module adds support for the PKCS#5 functions. - */ -#define MBEDTLS_PKCS5_C - -/** - * \def MBEDTLS_PKCS11_C - * - * Enable wrapper for PKCS#11 smartcard support via the pkcs11-helper library. - * - * \deprecated This option is deprecated and will be removed in a future - * version of Mbed TLS. - * - * Module: library/pkcs11.c - * Caller: library/pk.c - * - * Requires: MBEDTLS_PK_C - * - * This module enables SSL/TLS PKCS #11 smartcard support. - * Requires the presence of the PKCS#11 helper library (libpkcs11-helper) - */ -//#define MBEDTLS_PKCS11_C - -/** - * \def MBEDTLS_PKCS12_C - * - * Enable PKCS#12 PBE functions. - * Adds algorithms for parsing PKCS#8 encrypted private keys - * - * Module: library/pkcs12.c - * Caller: library/pkparse.c - * - * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C, MBEDTLS_MD_C - * Can use: MBEDTLS_ARC4_C - * - * This module enables PKCS#12 functions. - */ -#define MBEDTLS_PKCS12_C - -/** - * \def MBEDTLS_PLATFORM_C - * - * Enable the platform abstraction layer that allows you to re-assign - * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit(). - * - * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT - * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned - * above to be specified at runtime or compile time respectively. - * - * \note This abstraction layer must be enabled on Windows (including MSYS2) - * as other module rely on it for a fixed snprintf implementation. - * - * Module: library/platform.c - * Caller: Most other .c files - * - * This module enables abstraction of common (libc) functions. - */ -#define MBEDTLS_PLATFORM_C - -/** - * \def MBEDTLS_POLY1305_C - * - * Enable the Poly1305 MAC algorithm. - * - * Module: library/poly1305.c - * Caller: library/chachapoly.c - */ -#define MBEDTLS_POLY1305_C - -/** - * \def MBEDTLS_PSA_CRYPTO_C - * - * Enable the Platform Security Architecture cryptography API. - * - * Module: library/psa_crypto.c - * - * Requires: either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C, - * or MBEDTLS_HMAC_DRBG_C and MBEDTLS_ENTROPY_C, - * or MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG. - * - */ -#define MBEDTLS_PSA_CRYPTO_C - -/** - * \def MBEDTLS_PSA_CRYPTO_SE_C - * - * Enable secure element support in the Platform Security Architecture - * cryptography API. - * - * \warning This feature is not yet suitable for production. It is provided - * for API evaluation and testing purposes only. - * - * Module: library/psa_crypto_se.c - * - * Requires: MBEDTLS_PSA_CRYPTO_C, MBEDTLS_PSA_CRYPTO_STORAGE_C - * - */ -//#define MBEDTLS_PSA_CRYPTO_SE_C - -/** - * \def MBEDTLS_PSA_CRYPTO_STORAGE_C - * - * Enable the Platform Security Architecture persistent key storage. - * - * Module: library/psa_crypto_storage.c - * - * Requires: MBEDTLS_PSA_CRYPTO_C, - * either MBEDTLS_PSA_ITS_FILE_C or a native implementation of - * the PSA ITS interface - */ -#define MBEDTLS_PSA_CRYPTO_STORAGE_C - -/** - * \def MBEDTLS_PSA_ITS_FILE_C - * - * Enable the emulation of the Platform Security Architecture - * Internal Trusted Storage (PSA ITS) over files. - * - * Module: library/psa_its_file.c - * - * Requires: MBEDTLS_FS_IO - */ -#define MBEDTLS_PSA_ITS_FILE_C - -/** - * \def MBEDTLS_RIPEMD160_C - * - * Enable the RIPEMD-160 hash algorithm. - * - * Module: library/ripemd160.c - * Caller: library/md.c - * - */ -#define MBEDTLS_RIPEMD160_C - -/** - * \def MBEDTLS_RSA_C - * - * Enable the RSA public-key cryptosystem. - * - * Module: library/rsa.c - * library/rsa_internal.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * library/x509.c - * - * This module is used by the following key exchanges: - * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK - * - * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C - */ -#define MBEDTLS_RSA_C - -/** - * \def MBEDTLS_SHA1_C - * - * Enable the SHA1 cryptographic hash algorithm. - * - * Module: library/sha1.c - * Caller: library/md.c - * library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * library/x509write_crt.c - * - * This module is required for SSL/TLS up to version 1.1, for TLS 1.2 - * depending on the handshake parameters, and for SHA1-signed certificates. - * - * \warning SHA-1 is considered a weak message digest and its use constitutes - * a security risk. If possible, we recommend avoiding dependencies - * on it, and considering stronger message digests instead. - * - */ -#define MBEDTLS_SHA1_C - -/** - * \def MBEDTLS_SHA256_C - * - * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. - * - * Module: library/sha256.c - * Caller: library/entropy.c - * library/md.c - * library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * - * This module adds support for SHA-224 and SHA-256. - * This module is required for the SSL/TLS 1.2 PRF function. - */ -#define MBEDTLS_SHA256_C - -/** - * \def MBEDTLS_SHA512_C - * - * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. - * - * Module: library/sha512.c - * Caller: library/entropy.c - * library/md.c - * library/ssl_cli.c - * library/ssl_srv.c - * - * This module adds support for SHA-384 and SHA-512. - */ -#define MBEDTLS_SHA512_C - -/** - * \def MBEDTLS_SSL_CACHE_C - * - * Enable simple SSL cache implementation. - * - * Module: library/ssl_cache.c - * Caller: - * - * Requires: MBEDTLS_SSL_CACHE_C - */ -#define MBEDTLS_SSL_CACHE_C - -/** - * \def MBEDTLS_SSL_COOKIE_C - * - * Enable basic implementation of DTLS cookies for hello verification. - * - * Module: library/ssl_cookie.c - * Caller: - */ -#define MBEDTLS_SSL_COOKIE_C - -/** - * \def MBEDTLS_SSL_TICKET_C - * - * Enable an implementation of TLS server-side callbacks for session tickets. - * - * Module: library/ssl_ticket.c - * Caller: - * - * Requires: MBEDTLS_CIPHER_C && - * ( MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C ) - */ -#define MBEDTLS_SSL_TICKET_C - -/** - * \def MBEDTLS_SSL_CLI_C - * - * Enable the SSL/TLS client code. - * - * Module: library/ssl_cli.c - * Caller: - * - * Requires: MBEDTLS_SSL_TLS_C - * - * This module is required for SSL/TLS client support. - */ -#define MBEDTLS_SSL_CLI_C - -/** - * \def MBEDTLS_SSL_SRV_C - * - * Enable the SSL/TLS server code. - * - * Module: library/ssl_srv.c - * Caller: - * - * Requires: MBEDTLS_SSL_TLS_C - * - * This module is required for SSL/TLS server support. - */ -//#define MBEDTLS_SSL_SRV_C - -/** - * \def MBEDTLS_SSL_TLS_C - * - * Enable the generic SSL/TLS code. - * - * Module: library/ssl_tls.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * - * Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C - * and at least one of the MBEDTLS_SSL_PROTO_XXX defines - * - * This module is required for SSL/TLS. - */ -#define MBEDTLS_SSL_TLS_C - -/** - * \def MBEDTLS_THREADING_C - * - * Enable the threading abstraction layer. - * By default Mbed TLS assumes it is used in a non-threaded environment or that - * contexts are not shared between threads. If you do intend to use contexts - * between threads, you will need to enable this layer to prevent race - * conditions. See also our Knowledge Base article about threading: - * https://mbed-tls.readthedocs.io/en/latest/kb/development/thread-safety-and-multi-threading - * - * Module: library/threading.c - * - * This allows different threading implementations (self-implemented or - * provided). - * - * You will have to enable either MBEDTLS_THREADING_ALT or - * MBEDTLS_THREADING_PTHREAD. - * - * Enable this layer to allow use of mutexes within Mbed TLS - */ -//#define MBEDTLS_THREADING_C - -/** - * \def MBEDTLS_TIMING_C - * - * Enable the semi-portable timing interface. - * - * \note The provided implementation only works on POSIX/Unix (including Linux, - * BSD and OS X) and Windows. On other platforms, you can either disable that - * module and provide your own implementations of the callbacks needed by - * \c mbedtls_ssl_set_timer_cb() for DTLS, or leave it enabled and provide - * your own implementation of the whole module by setting - * \c MBEDTLS_TIMING_ALT in the current file. - * - * \note The timing module will include time.h on suitable platforms - * regardless of the setting of MBEDTLS_HAVE_TIME, unless - * MBEDTLS_TIMING_ALT is used. See timing.c for more information. - * - * \note See also our Knowledge Base article about porting to a new - * environment: - * https://mbed-tls.readthedocs.io/en/latest/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS - * - * Module: library/timing.c - * Caller: library/havege.c - * - * This module is used by the HAVEGE random number generator. - */ -#define MBEDTLS_TIMING_C - -/** - * \def MBEDTLS_VERSION_C - * - * Enable run-time version information. - * - * Module: library/version.c - * - * This module provides run-time version information. - */ -#define MBEDTLS_VERSION_C - -/** - * \def MBEDTLS_X509_USE_C - * - * Enable X.509 core for using certificates. - * - * Module: library/x509.c - * Caller: library/x509_crl.c - * library/x509_crt.c - * library/x509_csr.c - * - * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, - * MBEDTLS_PK_PARSE_C - * - * This module is required for the X.509 parsing modules. - */ -#define MBEDTLS_X509_USE_C - -/** - * \def MBEDTLS_X509_CRT_PARSE_C - * - * Enable X.509 certificate parsing. - * - * Module: library/x509_crt.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * - * Requires: MBEDTLS_X509_USE_C - * - * This module is required for X.509 certificate parsing. - */ -#define MBEDTLS_X509_CRT_PARSE_C - -/** - * \def MBEDTLS_X509_CRL_PARSE_C - * - * Enable X.509 CRL parsing. - * - * Module: library/x509_crl.c - * Caller: library/x509_crt.c - * - * Requires: MBEDTLS_X509_USE_C - * - * This module is required for X.509 CRL parsing. - */ -#define MBEDTLS_X509_CRL_PARSE_C - -/** - * \def MBEDTLS_X509_CSR_PARSE_C - * - * Enable X.509 Certificate Signing Request (CSR) parsing. - * - * Module: library/x509_csr.c - * Caller: library/x509_crt_write.c - * - * Requires: MBEDTLS_X509_USE_C - * - * This module is used for reading X.509 certificate request. - */ -#define MBEDTLS_X509_CSR_PARSE_C - -/** - * \def MBEDTLS_X509_CREATE_C - * - * Enable X.509 core for creating certificates. - * - * Module: library/x509_create.c - * - * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_WRITE_C - * - * This module is the basis for creating X.509 certificates and CSRs. - */ -#define MBEDTLS_X509_CREATE_C - -/** - * \def MBEDTLS_X509_CRT_WRITE_C - * - * Enable creating X.509 certificates. - * - * Module: library/x509_crt_write.c - * - * Requires: MBEDTLS_X509_CREATE_C - * - * This module is required for X.509 certificate creation. - */ -#define MBEDTLS_X509_CRT_WRITE_C - -/** - * \def MBEDTLS_X509_CSR_WRITE_C - * - * Enable creating X.509 Certificate Signing Requests (CSR). - * - * Module: library/x509_csr_write.c - * - * Requires: MBEDTLS_X509_CREATE_C - * - * This module is required for X.509 certificate request writing. - */ -#define MBEDTLS_X509_CSR_WRITE_C - -/** - * \def MBEDTLS_XTEA_C - * - * Enable the XTEA block cipher. - * - * Module: library/xtea.c - * Caller: - */ -#define MBEDTLS_XTEA_C - -/** \} name SECTION: Mbed TLS modules */ - -/** - * \name SECTION: General configuration options - * - * This section contains Mbed TLS build settings that are not associated - * with a particular module. - * - * \{ - */ - -/** - * \def MBEDTLS_CONFIG_FILE - * - * If defined, this is a header which will be included instead of - * `"mbedtls/config.h"`. - * This header file specifies the compile-time configuration of Mbed TLS. - * Unlike other configuration options, this one must be defined on the - * compiler command line: a definition in `config.h` would have no effect. - * - * This macro is expanded after an \#include directive. This is a popular but - * non-standard feature of the C language, so this feature is only available - * with compilers that perform macro expansion on an \#include line. - * - * The value of this symbol is typically a path in double quotes, either - * absolute or relative to a directory on the include search path. - */ -//#define MBEDTLS_CONFIG_FILE "mbedtls/config.h" - -/** - * \def MBEDTLS_USER_CONFIG_FILE - * - * If defined, this is a header which will be included after - * `"mbedtls/config.h"` or #MBEDTLS_CONFIG_FILE. - * This allows you to modify the default configuration, including the ability - * to undefine options that are enabled by default. - * - * This macro is expanded after an \#include directive. This is a popular but - * non-standard feature of the C language, so this feature is only available - * with compilers that perform macro expansion on an \#include line. - * - * The value of this symbol is typically a path in double quotes, either - * absolute or relative to a directory on the include search path. - */ -//#define MBEDTLS_USER_CONFIG_FILE "/dev/null" - -/** - * \def MBEDTLS_PSA_CRYPTO_CONFIG_FILE - * - * If defined, this is a header which will be included instead of - * `"psa/crypto_config.h"`. - * This header file specifies which cryptographic mechanisms are available - * through the PSA API when #MBEDTLS_PSA_CRYPTO_CONFIG is enabled, and - * is not used when #MBEDTLS_PSA_CRYPTO_CONFIG is disabled. - * - * This macro is expanded after an \#include directive. This is a popular but - * non-standard feature of the C language, so this feature is only available - * with compilers that perform macro expansion on an \#include line. - * - * The value of this symbol is typically a path in double quotes, either - * absolute or relative to a directory on the include search path. - */ -//#define MBEDTLS_PSA_CRYPTO_CONFIG_FILE "psa/crypto_config.h" - -/** - * \def MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE - * - * If defined, this is a header which will be included after - * `"psa/crypto_config.h"` or #MBEDTLS_PSA_CRYPTO_CONFIG_FILE. - * This allows you to modify the default configuration, including the ability - * to undefine options that are enabled by default. - * - * This macro is expanded after an \#include directive. This is a popular but - * non-standard feature of the C language, so this feature is only available - * with compilers that perform macro expansion on an \#include line. - * - * The value of this symbol is typically a path in double quotes, either - * absolute or relative to a directory on the include search path. - */ -//#define MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE "/dev/null" - -/** \} name SECTION: General configuration options */ - -/** - * \name SECTION: Module configuration options - * - * This section allows for the setting of module specific sizes and - * configuration options. The default values are already present in the - * relevant header files and should suffice for the regular use cases. - * - * Our advice is to enable options and change their values here - * only if you have a good reason and know the consequences. - * \{ - */ -/* The Doxygen documentation here is used when a user comments out a - * setting and runs doxygen themselves. On the other hand, when we typeset - * the full documentation including disabled settings, the documentation - * in specific modules' header files is used if present. When editing this - * file, make sure that each option is documented in exactly one place, - * plus optionally a same-line Doxygen comment here if there is a Doxygen - * comment in the specific module. */ - -/* MPI / BIGNUM options */ -//#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum window size used. */ -//#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ - -/* CTR_DRBG options */ -//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ -//#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ -//#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ -//#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ -//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ - -/* HMAC_DRBG options */ -//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ -//#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ -//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ -//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ - -/* ECP options */ -//#define MBEDTLS_ECP_MAX_BITS 521 /**< Maximum bit size of groups. Normally determined automatically from the configured curves. */ -//#define MBEDTLS_ECP_WINDOW_SIZE 4 /**< Maximum window size used */ -//#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ - -/* Entropy options */ -//#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ -//#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ -//#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */ - -/* Memory buffer allocator options */ -//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ - -/* Platform options */ -//#define MBEDTLS_PLATFORM_STD_MEM_HDR /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ - -/** \def MBEDTLS_PLATFORM_STD_CALLOC - * - * Default allocator to use, can be undefined. - * It must initialize the allocated buffer memory to zeroes. - * The size of the buffer is the product of the two parameters. - * The calloc function returns either a null pointer or a pointer to the allocated space. - * If the product is 0, the function may either return NULL or a valid pointer to an array of size 0 which is a valid input to the deallocation function. - * An uninitialized #MBEDTLS_PLATFORM_STD_CALLOC always fails, returning a null pointer. - * See the description of #MBEDTLS_PLATFORM_MEMORY for more details. - * The corresponding deallocation function is #MBEDTLS_PLATFORM_STD_FREE. - */ -//#define MBEDTLS_PLATFORM_STD_CALLOC calloc - -/** \def MBEDTLS_PLATFORM_STD_FREE - * - * Default free to use, can be undefined. - * NULL is a valid parameter, and the function must do nothing. - * A non-null parameter will always be a pointer previously returned by #MBEDTLS_PLATFORM_STD_CALLOC and not yet freed. - * An uninitialized #MBEDTLS_PLATFORM_STD_FREE does not do anything. - * See the description of #MBEDTLS_PLATFORM_MEMORY for more details (same principles as for MBEDTLS_PLATFORM_STD_CALLOC apply). - */ -//#define MBEDTLS_PLATFORM_STD_FREE free -//#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ -//#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ -/* Note: your snprintf must correctly zero-terminate the buffer! */ -//#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS 0 /**< Default exit value to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE 1 /**< Default exit value to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" /**< Seed file to read/write with default implementation */ - -/* To use the following function macros, MBEDTLS_PLATFORM_C must be enabled. */ -/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */ -//#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined. See MBEDTLS_PLATFORM_STD_CALLOC for requirements. */ -//#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined. See MBEDTLS_PLATFORM_STD_FREE for requirements. */ -//#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ -//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ -//#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */ -/* Note: your snprintf must correctly zero-terminate the buffer! */ -//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_VSNPRINTF_MACRO vsnprintf /**< Default vsnprintf macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ -//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ - -/** - * \brief This macro is invoked by the library when an invalid parameter - * is detected that is only checked with #MBEDTLS_CHECK_PARAMS - * (see the documentation of that option for context). - * - * When you leave this undefined here, the library provides - * a default definition. If the macro #MBEDTLS_CHECK_PARAMS_ASSERT - * is defined, the default definition is `assert(cond)`, - * otherwise the default definition calls a function - * mbedtls_param_failed(). This function is declared in - * `platform_util.h` for the benefit of the library, but - * you need to define in your application. - * - * When you define this here, this replaces the default - * definition in platform_util.h (which no longer declares the - * function mbedtls_param_failed()) and it is your responsibility - * to make sure this macro expands to something suitable (in - * particular, that all the necessary declarations are visible - * from within the library - you can ensure that by providing - * them in this file next to the macro definition). - * If you define this macro to call `assert`, also define - * #MBEDTLS_CHECK_PARAMS_ASSERT so that library source files - * include ``. - * - * Note that you may define this macro to expand to nothing, in - * which case you don't have to worry about declarations or - * definitions. However, you will then be notified about invalid - * parameters only in non-void functions, and void function will - * just silently return early on invalid parameters, which - * partially negates the benefits of enabling - * #MBEDTLS_CHECK_PARAMS in the first place, so is discouraged. - * - * \param cond The expression that should evaluate to true, but doesn't. - */ -//#define MBEDTLS_PARAM_FAILED( cond ) assert( cond ) - -/** \def MBEDTLS_CHECK_RETURN - * - * This macro is used at the beginning of the declaration of a function - * to indicate that its return value should be checked. It should - * instruct the compiler to emit a warning or an error if the function - * is called without checking its return value. - * - * There is a default implementation for popular compilers in platform_util.h. - * You can override the default implementation by defining your own here. - * - * If the implementation here is empty, this will effectively disable the - * checking of functions' return values. - */ -//#define MBEDTLS_CHECK_RETURN __attribute__((__warn_unused_result__)) - -/** \def MBEDTLS_IGNORE_RETURN - * - * This macro requires one argument, which should be a C function call. - * If that function call would cause a #MBEDTLS_CHECK_RETURN warning, this - * warning is suppressed. - */ -//#define MBEDTLS_IGNORE_RETURN( result ) ((void) !(result)) - -/* PSA options */ -/** - * Use HMAC_DRBG with the specified hash algorithm for HMAC_DRBG for the - * PSA crypto subsystem. - * - * If this option is unset, the library chooses a hash (currently between - * #MBEDTLS_MD_SHA512 and #MBEDTLS_MD_SHA256) based on availability and - * unspecified heuristics. - * - * \note The PSA crypto subsystem uses the first available mechanism amongst - * the following: - * - #MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG if enabled; - * - Entropy from #MBEDTLS_ENTROPY_C plus CTR_DRBG with AES - * if #MBEDTLS_CTR_DRBG_C is enabled; - * - Entropy from #MBEDTLS_ENTROPY_C plus HMAC_DRBG. - * - * A future version may reevaluate the prioritization of DRBG mechanisms. - */ -//#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256 - -/** \def MBEDTLS_PSA_KEY_SLOT_COUNT - * - * The maximum amount of PSA keys simultaneously in memory. This counts all - * volatile keys, plus loaded persistent keys. - * - * Currently, persistent keys do not need to be loaded all the time while - * a multipart operation is in progress, only while the operation is being - * set up. This may change in future versions of the library. - * - * Currently, the library traverses of the whole table on each access to a - * persistent key. Therefore large values may cause poor performance. - * - * This option has no effect when #MBEDTLS_PSA_CRYPTO_C is disabled. - */ -//#define MBEDTLS_PSA_KEY_SLOT_COUNT 32 - -/* SSL Cache options */ -//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ -//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ - -/* SSL options */ - -/** \def MBEDTLS_SSL_MAX_CONTENT_LEN - * - * Maximum length (in bytes) of incoming and outgoing plaintext fragments. - * - * This determines the size of both the incoming and outgoing TLS I/O buffers - * in such a way that both are capable of holding the specified amount of - * plaintext data, regardless of the protection mechanism used. - * - * To configure incoming and outgoing I/O buffers separately, use - * #MBEDTLS_SSL_IN_CONTENT_LEN and #MBEDTLS_SSL_OUT_CONTENT_LEN, - * which overwrite the value set by this option. - * - * \note When using a value less than the default of 16KB on the client, it is - * recommended to use the Maximum Fragment Length (MFL) extension to - * inform the server about this limitation. On the server, there - * is no supported, standardized way of informing the client about - * restriction on the maximum size of incoming messages, and unless - * the limitation has been communicated by other means, it is recommended - * to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN - * while keeping the default value of 16KB for the incoming buffer. - * - * Uncomment to set the maximum plaintext size of both - * incoming and outgoing I/O buffers. - */ -//#define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 - -/** \def MBEDTLS_SSL_IN_CONTENT_LEN - * - * Maximum length (in bytes) of incoming plaintext fragments. - * - * This determines the size of the incoming TLS I/O buffer in such a way - * that it is capable of holding the specified amount of plaintext data, - * regardless of the protection mechanism used. - * - * If this option is undefined, it inherits its value from - * #MBEDTLS_SSL_MAX_CONTENT_LEN. - * - * \note When using a value less than the default of 16KB on the client, it is - * recommended to use the Maximum Fragment Length (MFL) extension to - * inform the server about this limitation. On the server, there - * is no supported, standardized way of informing the client about - * restriction on the maximum size of incoming messages, and unless - * the limitation has been communicated by other means, it is recommended - * to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN - * while keeping the default value of 16KB for the incoming buffer. - * - * Uncomment to set the maximum plaintext size of the incoming I/O buffer - * independently of the outgoing I/O buffer. - */ -//#define MBEDTLS_SSL_IN_CONTENT_LEN 16384 - -/** \def MBEDTLS_SSL_CID_IN_LEN_MAX - * - * The maximum length of CIDs used for incoming DTLS messages. - * - */ -//#define MBEDTLS_SSL_CID_IN_LEN_MAX 32 - -/** \def MBEDTLS_SSL_CID_OUT_LEN_MAX - * - * The maximum length of CIDs used for outgoing DTLS messages. - * - */ -//#define MBEDTLS_SSL_CID_OUT_LEN_MAX 32 - -/** \def MBEDTLS_SSL_CID_PADDING_GRANULARITY - * - * This option controls the use of record plaintext padding - * when using the Connection ID extension in DTLS 1.2. - * - * The padding will always be chosen so that the length of the - * padded plaintext is a multiple of the value of this option. - * - * Note: A value of \c 1 means that no padding will be used - * for outgoing records. - * - * Note: On systems lacking division instructions, - * a power of two should be preferred. - * - */ -//#define MBEDTLS_SSL_CID_PADDING_GRANULARITY 16 - -/** \def MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY - * - * This option controls the use of record plaintext padding - * in TLS 1.3. - * - * The padding will always be chosen so that the length of the - * padded plaintext is a multiple of the value of this option. - * - * Note: A value of \c 1 means that no padding will be used - * for outgoing records. - * - * Note: On systems lacking division instructions, - * a power of two should be preferred. - */ -//#define MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY 1 - -/** \def MBEDTLS_SSL_OUT_CONTENT_LEN - * - * Maximum length (in bytes) of outgoing plaintext fragments. - * - * This determines the size of the outgoing TLS I/O buffer in such a way - * that it is capable of holding the specified amount of plaintext data, - * regardless of the protection mechanism used. - * - * If this option undefined, it inherits its value from - * #MBEDTLS_SSL_MAX_CONTENT_LEN. - * - * It is possible to save RAM by setting a smaller outward buffer, while keeping - * the default inward 16384 byte buffer to conform to the TLS specification. - * - * The minimum required outward buffer size is determined by the handshake - * protocol's usage. Handshaking will fail if the outward buffer is too small. - * The specific size requirement depends on the configured ciphers and any - * certificate data which is sent during the handshake. - * - * Uncomment to set the maximum plaintext size of the outgoing I/O buffer - * independently of the incoming I/O buffer. - */ -//#define MBEDTLS_SSL_OUT_CONTENT_LEN 16384 - -/** \def MBEDTLS_SSL_DTLS_MAX_BUFFERING - * - * Maximum number of heap-allocated bytes for the purpose of - * DTLS handshake message reassembly and future message buffering. - * - * This should be at least 9/8 * MBEDTLS_SSL_IN_CONTENT_LEN - * to account for a reassembled handshake message of maximum size, - * together with its reassembly bitmap. - * - * A value of 2 * MBEDTLS_SSL_IN_CONTENT_LEN (32768 by default) - * should be sufficient for all practical situations as it allows - * to reassembly a large handshake message (such as a certificate) - * while buffering multiple smaller handshake messages. - * - */ -//#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768 - -//#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ -//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */ -//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */ - -/** \def MBEDTLS_TLS_EXT_CID - * - * At the time of writing, the CID extension has not been assigned its - * final value. Set this configuration option to make Mbed TLS use a - * different value. - * - * A future minor revision of Mbed TLS may change the default value of - * this option to match evolving standards and usage. - */ -//#define MBEDTLS_TLS_EXT_CID 254 - -/** - * Complete list of ciphersuites to use, in order of preference. - * - * \warning No dependency checking is done on that field! This option can only - * be used to restrict the set of available ciphersuites. It is your - * responsibility to make sure the needed modules are active. - * - * Use this to save a few hundred bytes of ROM (default ordering of all - * available ciphersuites) and a few to a few hundred bytes of RAM. - * - * The value below is only an example, not the default. - */ -//#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - -/* X509 options */ -//#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 /**< Maximum number of intermediate CAs in a verification chain. */ -//#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 /**< Maximum length of a path/filename string in bytes including the null terminator character ('\0'). */ - -/** \} name SECTION: Module configuration options */ - -/* Target and application specific configurations - * - * Allow user to override any previous default. - * - */ -#if defined(MBEDTLS_USER_CONFIG_FILE) -#include MBEDTLS_USER_CONFIG_FILE -#endif - -#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) -#include "mbedtls/config_psa.h" -#endif - -#define MBEDTLS_WITH_ASR -#define QUECTEL_MBEDTLS_GEU_RANDOM_SUPPORT #define QUECTEL_MBEDTLS_SUPPORT +#define MBEDTLS_SSL_VERSION_ALL_HIGH_FIRST -#define MBEDTLS_WITH_ASR - +/* APP calls the kernel TLS implementation through the SDK API map. + * Match its options so caller-allocated contexts have the same layout. */ +#include "../../../../../ql-config/config/talkingq_mbedtls_config.h" #include "mbedtls/check_config.h" -#endif /* MBEDTLS_CONFIG_H */ +#endif diff --git a/ql-application/threadx/interface/custom_app/Makefile b/ql-application/threadx/interface/custom_app/Makefile index 9fd9032..eaa1846 100644 --- a/ql-application/threadx/interface/custom_app/Makefile +++ b/ql-application/threadx/interface/custom_app/Makefile @@ -13,6 +13,7 @@ MAKEFILE_PATH :=$(subst $(strip \),/,$(abspath $(lastword $(MAKEFILE_LIST)))) SRC_FILES+= \ custom_app.c \ lib/cJSON/cJSON.c\ + lib/librws/src/rws_handshake.c\ lib/librws/src/rws_error.c\ lib/librws/src/rws_frame.c\ lib/librws/src/rws_list.c\ @@ -67,6 +68,8 @@ SRC_FILES+= \ http_aofei.c \ net_mgt.c \ ws_talkingq.c \ + talkingq_wss.c \ + talkingq_root_ca.c \ hal_key.c \ audio.c \ hal_led.c \ @@ -78,6 +81,7 @@ SRC_FILES+= \ nfc.c \ DP1312EA.c \ mqtt.c \ + mqtt_connect_diag.c \ vad_det.c \ sleep_wake.c \ battery.c \ diff --git a/ql-application/threadx/interface/custom_app/hal_key.c b/ql-application/threadx/interface/custom_app/hal_key.c index 6402d2e..6861c05 100644 --- a/ql-application/threadx/interface/custom_app/hal_key.c +++ b/ql-application/threadx/interface/custom_app/hal_key.c @@ -126,7 +126,12 @@ static void key_thread_entry(void *parameter) app_set_app_operation(1); } - if(app_get_data_call_net_status()&&get_mqtt_connect_status()==1){ + int mic_pdp = app_get_data_call_net_status(); + int mic_mqtt = get_mqtt_connect_status(); + printf("[NET-GATE] mic pdp=%d mqtt=%d action=%s\r\n", + mic_pdp, mic_mqtt, + !mic_pdp ? "blocked_no_pdp" : (mic_mqtt != 1 ? "blocked_mqtt_offline" : "start_voice")); + if(mic_pdp && mic_mqtt == 1){ if(tts_play_interrupt_func()==-2){ app_play_tips_file(2); } diff --git a/ql-application/threadx/interface/custom_app/inc/mqtt_connect_diag.h b/ql-application/threadx/interface/custom_app/inc/mqtt_connect_diag.h new file mode 100644 index 0000000..1eac631 --- /dev/null +++ b/ql-application/threadx/interface/custom_app/inc/mqtt_connect_diag.h @@ -0,0 +1,9 @@ +#ifndef TALKINGQ_MQTT_CONNECT_DIAG_H +#define TALKINGQ_MQTT_CONNECT_DIAG_H + +#include "MQTTClient.h" + +/* Called by the single MQTT connection worker, before MQTTStartTask(). */ +int talkingq_mqtt_connect_diagnosed(MQTTClient *client, MQTTPacket_connectData *options); + +#endif diff --git a/ql-application/threadx/interface/custom_app/inc/talkingq_wss.h b/ql-application/threadx/interface/custom_app/inc/talkingq_wss.h new file mode 100644 index 0000000..f14556b --- /dev/null +++ b/ql-application/threadx/interface/custom_app/inc/talkingq_wss.h @@ -0,0 +1,20 @@ +#ifndef TALKINGQ_WSS_H +#define TALKINGQ_WSS_H + +#include + +#define TALKINGQ_WSS_URL "wss://banban.api.talkingq.com:443/ws" +#define TALKINGQ_URL_CAPACITY 64 +#define TALKINGQ_HOST_CAPACITY 64 +#define TALKINGQ_PATH_CAPACITY 128 + +extern const char talkingq_root_ca[]; +extern const size_t talkingq_root_ca_size; + +/* Reject cleartext, malformed authorities, invalid ports and oversized URLs. */ +int talkingq_parse_wss_url(const char *url, char *host, size_t host_size, + int *port, char *path, size_t path_size); +/* Only the former built-in endpoints migrate; custom WSS endpoints are kept. */ +int talkingq_is_legacy_ws_url(const char *url); + +#endif diff --git a/ql-application/threadx/interface/custom_app/lib/hal/hal.c b/ql-application/threadx/interface/custom_app/lib/hal/hal.c index 656d4f7..ec98b88 100644 --- a/ql-application/threadx/interface/custom_app/lib/hal/hal.c +++ b/ql-application/threadx/interface/custom_app/lib/hal/hal.c @@ -30,6 +30,7 @@ #include "hal_api.h" #include "build_macro.h" #include "ql_rtc.h" +#include "talkingq_wss.h" #include "ql_cell_locator.h" @@ -979,17 +980,17 @@ int save_talkingq_url(uint8_t *buff, int len) #endif int hal_os_get_talkingq_url(char *pdevice_id) { - char temp_device_id[64]; - memset(temp_device_id, 0, sizeof(temp_device_id)); - hal_kv_get("talkingq_url", temp_device_id, sizeof(temp_device_id)); + char temp_device_id[TALKINGQ_URL_CAPACITY] = {0}; + int saved = hal_kv_get("talkingq_url", temp_device_id, sizeof(temp_device_id)); + temp_device_id[sizeof(temp_device_id) - 1] = 0; //read_talkingq_url(temp_device_id,sizeof(temp_device_id)); - if(strlen(temp_device_id)>0){ + if(saved > 0 && strlen(temp_device_id)>0 && !talkingq_is_legacy_ws_url(temp_device_id)){ strcpy(pdevice_id, temp_device_id); }else{ //strcpy(pdevice_id,"ws://api.talkingq.com:8080"); //strcpy(pdevice_id,"ws://175.24.73.253:80"); - strcpy(pdevice_id,"ws://101.35.224.118:8080"); + strcpy(pdevice_id, TALKINGQ_WSS_URL); return -1; } return 0; diff --git a/ql-application/threadx/interface/custom_app/lib/librws/inc/librws.h b/ql-application/threadx/interface/custom_app/lib/librws/inc/librws.h index 6005cfb..fb647f0 100644 --- a/ql-application/threadx/interface/custom_app/lib/librws/inc/librws.h +++ b/ql-application/threadx/interface/custom_app/lib/librws/inc/librws.h @@ -22,6 +22,7 @@ #ifndef __LIBRWS_H__ #define __LIBRWS_H__ +#include "rws_tls_config.h" #include diff --git a/ql-application/threadx/interface/custom_app/lib/librws/inc/rws_common.h b/ql-application/threadx/interface/custom_app/lib/librws/inc/rws_common.h index fb55d72..391308e 100644 --- a/ql-application/threadx/interface/custom_app/lib/librws/inc/rws_common.h +++ b/ql-application/threadx/interface/custom_app/lib/librws/inc/rws_common.h @@ -23,6 +23,8 @@ #ifndef __RWS_COMMON_H__ #define __RWS_COMMON_H__ 1 +#include "rws_tls_config.h" + #include #include "ql_type.h" #include "ql_rtos.h" diff --git a/ql-application/threadx/interface/custom_app/lib/librws/inc/rws_handshake.h b/ql-application/threadx/interface/custom_app/lib/librws/inc/rws_handshake.h new file mode 100644 index 0000000..8a94765 --- /dev/null +++ b/ql-application/threadx/interface/custom_app/lib/librws/inc/rws_handshake.h @@ -0,0 +1,8 @@ +#ifndef RWS_HANDSHAKE_H +#define RWS_HANDSHAKE_H +#include +#define RWS_HANDSHAKE_MAX 8192 +/* 1: valid upgrade, 0: incomplete, -1: rejected. Never needs a NUL terminator. */ +int rws_check_handshake(const char *data, size_t length, const char *expected_accept, + size_t *header_length, int *http_status); +#endif diff --git a/ql-application/threadx/interface/custom_app/lib/librws/inc/rws_socket.h b/ql-application/threadx/interface/custom_app/lib/librws/inc/rws_socket.h index b9b1c53..ca51d6e 100644 --- a/ql-application/threadx/interface/custom_app/lib/librws/inc/rws_socket.h +++ b/ql-application/threadx/interface/custom_app/lib/librws/inc/rws_socket.h @@ -87,9 +87,11 @@ typedef struct _rws_socket_struct char *host; char *path; + char expected_accept[29]; char *sec_ws_accept; // "Sec-WebSocket-Accept" field from handshake rws_thread work_thread; + rws_bool worker_started; int command; diff --git a/ql-application/threadx/interface/custom_app/lib/librws/inc/rws_tls_config.h b/ql-application/threadx/interface/custom_app/lib/librws/inc/rws_tls_config.h new file mode 100644 index 0000000..fd59757 --- /dev/null +++ b/ql-application/threadx/interface/custom_app/lib/librws/inc/rws_tls_config.h @@ -0,0 +1,5 @@ +#ifndef RWS_TLS_CONFIG_H +#define RWS_TLS_CONFIG_H +/* Shared by public and private headers so every socket layout agrees. */ +#define LIBRWS_USING_MBED_TLS 1 +#endif diff --git a/ql-application/threadx/interface/custom_app/lib/librws/src/rws_handshake.c b/ql-application/threadx/interface/custom_app/lib/librws/src/rws_handshake.c new file mode 100644 index 0000000..98fc2c2 --- /dev/null +++ b/ql-application/threadx/interface/custom_app/lib/librws/src/rws_handshake.c @@ -0,0 +1,79 @@ +#include "rws_handshake.h" +#include + +static int equal_ci(const char *s, size_t n, const char *literal) +{ + size_t i; + if (strlen(literal) != n) return 0; + for (i = 0; i < n; ++i) { + unsigned char c = (unsigned char)s[i]; + if (c >= 'A' && c <= 'Z') c += 'a' - 'A'; + if (c != (unsigned char)literal[i]) return 0; + } + return 1; +} + +static int has_token(const char *s, size_t n, const char *token) +{ + size_t begin = 0, end, next; + while (begin < n) { + for (end = begin; end < n && s[end] != ','; ++end) {} + next = end + 1; + while (begin < end && (s[begin] == ' ' || s[begin] == '\t')) ++begin; + while (end > begin && (s[end-1] == ' ' || s[end-1] == '\t')) --end; + if (equal_ci(s + begin, end - begin, token)) return 1; + begin = next; + } + return 0; +} + +int rws_check_handshake(const char *data, size_t length, const char *expected_accept, + size_t *header_length, int *http_status) +{ + size_t total = 0, i, line, end, colon, first, last; + int accept = 0, upgrade = 0, connection = 0; + *header_length = 0; + *http_status = 0; + if (!data) return length ? -1 : 0; + for (i = 0; i + 3 < length && i + 4 <= RWS_HANDSHAKE_MAX; ++i) { + if (!memcmp(data + i, "\r\n\r\n", 4)) { total = i + 4; break; } + } + if (!total) return length >= RWS_HANDSHAKE_MAX ? -1 : 0; + *header_length = total; + for (i = 0; i < total; ++i) { + unsigned char c = (unsigned char)data[i]; + if (c == 0 || (c < 32 && c != '\r' && c != '\n' && c != '\t')) return -1; + } + for (end = 0; end + 1 < total && memcmp(data + end, "\r\n", 2); ++end) {} + if (end < 12 || memcmp(data, "HTTP/1.1 ", 9) || + (end > 12 && data[12] != ' ')) return -1; + for (i = 9; i < 12; ++i) { + if (data[i] < '0' || data[i] > '9') return -1; + *http_status = *http_status * 10 + data[i] - '0'; + } + if (*http_status != 101) return -1; + line = end + 2; + while (line < total - 2) { + for (end = line; end + 1 < total && memcmp(data + end, "\r\n", 2); ++end) {} + for (colon = line; colon < end && data[colon] != ':'; ++colon) {} + if (colon == end) return -1; + first = colon + 1; + last = end; + while (first < last && (data[first] == ' ' || data[first] == '\t')) ++first; + while (last > first && (data[last-1] == ' ' || data[last-1] == '\t')) --last; + if (equal_ci(data + line, colon - line, "sec-websocket-accept")) { + if (accept || strlen(expected_accept) != last - first || + memcmp(data + first, expected_accept, last - first)) return -1; + accept = 1; + } else if (equal_ci(data + line, colon - line, "upgrade")) { + upgrade |= has_token(data + first, last - first, "websocket"); + } else if (equal_ci(data + line, colon - line, "connection")) { + connection |= has_token(data + first, last - first, "upgrade"); + } else if (equal_ci(data + line, colon - line, "sec-websocket-extensions") || + equal_ci(data + line, colon - line, "sec-websocket-protocol")) { + return -1; /* This client did not request extensions or a subprotocol. */ + } + line = end + 2; + } + return accept && upgrade && connection ? 1 : -1; +} diff --git a/ql-application/threadx/interface/custom_app/lib/librws/src/rws_socketpriv.c b/ql-application/threadx/interface/custom_app/lib/librws/src/rws_socketpriv.c index 57942e4..d8bb566 100644 --- a/ql-application/threadx/interface/custom_app/lib/librws/src/rws_socketpriv.c +++ b/ql-application/threadx/interface/custom_app/lib/librws/src/rws_socketpriv.c @@ -27,6 +27,13 @@ #include #include "sockets.h" #include "ql_rtos.h" +#include +#include "rws_handshake.h" +#ifdef LIBRWS_USING_MBED_TLS +#include "mbedtls/base64.h" +#include "mbedtls/sha1.h" +#include "mbedtls/ssl_internal.h" +#endif const char *k_rws_socket_min_http_ver = "1.1"; @@ -127,86 +134,12 @@ void rws_socket_inform_recvd_frames(_rws_socket *s) } } -void rws_socket_read_handshake_responce_value(const char *str, char **value) -{ - const char *s = NULL; - size_t len = 0; - - while (*str == ':' || *str == ' ') - { - str++; - } - s = str; - while (*s != '\r' && *s != '\n') - { - s++; - len++; - } - if (len > 0) - { - *value = rws_string_copy_len(str, len); - } -} - rws_bool rws_socket_process_handshake_responce(_rws_socket *s) { - const char *str = (const char *)s->received; - const char *sub = NULL; - // float http_ver = -1; - // int http_code = -1; - - rws_error_delete_clean(&s->error); - - // LOG_D("responce herader %s",str); - - sub = strstr(str, "HTTP/"); - if (!sub) - { - LOG_E("herader not find HTTP ERROR"); - return rws_false; - } - - sub += 5; - #if 0 - if (rws_sscanf(sub, "%f %i", &http_ver, &http_code) != 2) - { - LOG_D("responce sub %s",sub); - http_ver = -1; - http_code = -1; - } - #endif - - // "Sec-WebSocket-Accept" - sub = strstr(str, k_rws_socket_sec_websocket_accept); - if (sub) - { - sub += strlen(k_rws_socket_sec_websocket_accept); - rws_socket_read_handshake_responce_value(sub, &s->sec_ws_accept); - } - - // "Sec-WebSocket-Accept" - sub = strstr(str, "sec-websocket-accept"); - if (sub) - { - sub += strlen(k_rws_socket_sec_websocket_accept); - rws_socket_read_handshake_responce_value(sub, &s->sec_ws_accept); - } - - // if (http_code != 101 || !s->sec_ws_accept) - if (!s->sec_ws_accept) - { - #if 0 - s->error = rws_error_new_code_descr(rws_error_code_parse_handshake, - (http_code != 101) ? "HTPP code not found or non 101" : "Accept key not found"); - - LOG_I("responce herader http_code %d",http_code); - if(!s->sec_ws_accept){ - LOG_E("Accept key not found"); - } - #endif - return rws_false; - } - return rws_true; + size_t header_length; + int status; + return rws_check_handshake((const char *)s->received, s->received_len, + s->expected_accept, &header_length, &status) == 1; } static int reliable_send(int sock, const void *data, size_t total_len) { @@ -255,6 +188,27 @@ static int reliable_send(int sock, const void *data, size_t total_len) { return sent_bytes; } +#ifdef LIBRWS_USING_MBED_TLS +static int rws_tls_send_all(_rws_socket *s, const unsigned char *data, size_t size) +{ + size_t sent = 0; + unsigned int started = ql_rtos_get_systicks(); + if (!s->ssl) return -1; + while (sent < size) { + int ret = mbedtls_ssl_write(&s->ssl->ssl_ctx, data + sent, size - sent); + if (ret > 0) { + sent += (size_t)ret; + } else if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { + return -1; + } else { + rws_thread_sleep(5); + } + if (sent < size && (unsigned int)(ql_rtos_get_systicks() - started) >= 1000) return -1; + } + return (int)sent; +} +#endif + // need close socket on error rws_bool rws_socket_send(_rws_socket *s, const void *data, const size_t data_size) { @@ -265,7 +219,7 @@ rws_bool rws_socket_send(_rws_socket *s, const void *data, const size_t data_siz if (s->scheme && strcmp(s->scheme, "wss") == 0) { LOG_D("[T:%.8d, L:%.5d, %*.*s] try send data with tls", ql_rtos_get_systicks(), __LINE__, DBG_FUNCTION_NUM, DBG_FUNCTION_NUM, __FUNCTION__); - sended = mbedtls_ssl_write(&(s->ssl->ssl_ctx), (const unsigned char *)data, (int)data_size); + sended = rws_tls_send_all(s, (const unsigned char *)data, data_size); } else #endif /* LIBRWS_USING_MBED_TLS */ @@ -289,7 +243,7 @@ rws_bool rws_socket_send(_rws_socket *s, const void *data, const size_t data_siz } #endif - if (sended > 0) + if (sended == (int)data_size) { rws_socket_error_cnt = 0; rws_socket_error_staus = 0; @@ -297,6 +251,15 @@ rws_bool rws_socket_send(_rws_socket *s, const void *data, const size_t data_siz } printf("errno:%d\n", errno); +#ifdef LIBRWS_USING_MBED_TLS + if (s->scheme && strcmp(s->scheme, "wss") == 0) { + rws_error_delete_clean(&s->error); + s->error = rws_error_new_code_descr(rws_error_code_read_write_socket, "TLS write failed or timed out"); + rws_socket_close(s); + s->command = COMMAND_INFORM_DISCONNECTED; + return rws_false; + } +#endif rws_socket_error_cnt++; if(rws_socket_error_cnt>3){ rws_socket_error_staus = 1; @@ -345,7 +308,25 @@ rws_bool rws_socket_recv(_rws_socket *s) if (s->scheme && strcmp(s->scheme, "wss") == 0) { // LOG_D("[T:%.8d, L:%.5d, %*.*s] try recv data with tls", ql_rtos_get_systicks(), __LINE__, DBG_FUNCTION_NUM, DBG_FUNCTION_NUM, __FUNCTION__); + if (!s->ssl) { + s->error = rws_error_new_code_descr(rws_error_code_read_write_socket, "TLS context is closed"); + s->command = COMMAND_INFORM_DISCONNECTED; + result = rws_false; + goto _exit; + } len = mbedtls_ssl_read(&(s->ssl->ssl_ctx), (unsigned char *)(s->payload_buff), RWS_RECEIVE_BUFF_SIZE); + if (len == MBEDTLS_ERR_SSL_WANT_READ || len == MBEDTLS_ERR_SSL_WANT_WRITE) { + /* No TLS data yet: let the upgrade loop wait for the next record. */ + error_number = 0; + break; + } + if (len <= 0) { + LOG_E("WSS TLS peer closed or read failed: %d\n", len); + s->error = rws_error_new_code_descr(rws_error_code_read_write_socket, "TLS peer closed or read failed"); + s->command = COMMAND_INFORM_DISCONNECTED; + result = rws_false; + goto _exit; + } } else #endif /* LIBRWS_USING_MBED_TLS */ @@ -385,6 +366,12 @@ rws_bool rws_socket_recv(_rws_socket *s) if (len > 0) { total_len += len; + if (s->command == COMMAND_WAIT_HANDSHAKE_RESPONCE && + s->received_len + (size_t)len > RWS_HANDSHAKE_MAX + RWS_RECEIVE_BUFF_SIZE) { + s->error = rws_error_new_code_descr(rws_error_code_parse_handshake, "WebSocket headers too large"); + result = rws_false; + goto _exit; + } if (s->received_size - s->received_len < len) { // LOG_D("[T:%.8d, L:%.5d, %*.*s] s->received_size = %d, s->received_len = %d", ql_rtos_get_systicks(), __LINE__, DBG_FUNCTION_NUM, DBG_FUNCTION_NUM, __FUNCTION__, s->received_size, s->received_len); @@ -398,6 +385,7 @@ rws_bool rws_socket_recv(_rws_socket *s) } memcpy(received, s->payload_buff, len); s->received_len += len; + if (s->command == COMMAND_WAIT_HANDSHAKE_RESPONCE) break; } else { @@ -1020,54 +1008,32 @@ void rws_socket_idle_send(_rws_socket *s) void rws_socket_wait_handshake_responce(_rws_socket *s) { - int cnt = 0; - // LOG_I("[T:%.8d, L:%.5d, %*.*s] try wait recv handshake responce", ql_rtos_get_systicks(), __LINE__, DBG_FUNCTION_NUM, DBG_FUNCTION_NUM, __FUNCTION__); - - /* Todo */ - while (!rws_socket_recv(s)) - { - // LOG_D("[T:%.8d, L:%.5d, %*.*s] no find handshake responce", ql_rtos_get_systicks(), __LINE__, DBG_FUNCTION_NUM, DBG_FUNCTION_NUM, __FUNCTION__); - - if (s->error) - { - LOG_E("[T:%.8d, L:%.5d, %*.*s] recv responce failed, handshake failed, error = %d", ql_rtos_get_systicks(), __LINE__, DBG_FUNCTION_NUM, DBG_FUNCTION_NUM, __FUNCTION__, s->error); - LOG_I("[T:%.8d, L:%.5d, %*.*s] try inform websocket disconnect", ql_rtos_get_systicks(), __LINE__, DBG_FUNCTION_NUM, DBG_FUNCTION_NUM, __FUNCTION__); - s->command = COMMAND_INFORM_DISCONNECTED; - return; - } - if(cnt++>2){ - s->command = COMMAND_SEND_HANDSHAKE; - return; - } - rws_thread_sleep(1000); + unsigned int started = ql_rtos_get_systicks(); + size_t header_length = 0; + int status = 0, result = 0; + while (result == 0) { + rws_socket_recv(s); + if (s->error) break; + result = rws_check_handshake((const char *)s->received, s->received_len, + s->expected_accept, &header_length, &status); + if (result != 0) break; + if ((unsigned int)(ql_rtos_get_systicks() - started) >= 2000) break; + rws_thread_sleep(10); } - - - if (s->received_len == 0) - { - LOG_D("[T:%.8d, L:%.5d, %*.*s] handshake responce len is empty, len = 0", ql_rtos_get_systicks(), __LINE__, DBG_FUNCTION_NUM, DBG_FUNCTION_NUM, __FUNCTION__); - return; - } - - // LOG_I("recv len %d",s->received_len); - - // LOG_I("[T:%.8d, L:%.5d, %*.*s] try process handshake responce", ql_rtos_get_systicks(), __LINE__, DBG_FUNCTION_NUM, DBG_FUNCTION_NUM, __FUNCTION__); - if (rws_socket_process_handshake_responce(s)) - { - s->received_len = 0; + if (result == 1 && !s->error) { + s->received_len -= header_length; + if (s->received_len) + memmove(s->received, (char *)s->received + header_length, s->received_len); s->is_connected = rws_true; s->command = COMMAND_INFORM_CONNECTED; - - // LOG_D("[T:%.8d, L:%.5d, %*.*s] process handshake responce succeed", ql_rtos_get_systicks(), __LINE__, DBG_FUNCTION_NUM, DBG_FUNCTION_NUM, __FUNCTION__); - LOG_I("[T:%.8d, L:%.5d, %*.*s] try inform websocket connect", ql_rtos_get_systicks(), __LINE__, DBG_FUNCTION_NUM, DBG_FUNCTION_NUM, __FUNCTION__); - } - else - { + LOG_I("WebSocket upgrade verified: HTTP 101\n"); + } else { + LOG_E("WebSocket upgrade failed: HTTP %d (0 means incomplete/invalid headers)\n", status); + if (!s->error) + s->error = rws_error_new_code_descr(rws_error_code_parse_handshake, + "Invalid or timed out WebSocket upgrade"); rws_socket_close(s); s->command = COMMAND_INFORM_DISCONNECTED; - - //LOG_E("[T:%.8d, L:%.5d, %*.*s] process handshake responce failed", ql_rtos_get_systicks(), __LINE__, DBG_FUNCTION_NUM, DBG_FUNCTION_NUM, __FUNCTION__); - LOG_I("[T:%.8d, L:%.5d, %*.*s] try inform websocket disconnect", ql_rtos_get_systicks(), __LINE__, DBG_FUNCTION_NUM, DBG_FUNCTION_NUM, __FUNCTION__); } } @@ -1093,6 +1059,24 @@ void rws_socket_send_handshake(_rws_socket *s) char buff[512]; char *ptr = buff; size_t writed = 0; + char key[25] = "dGhlIHNhbXBsZSBub25jZQ=="; + strcpy(s->expected_accept, "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="); +#ifdef LIBRWS_USING_MBED_TLS + if (s->scheme && !strcmp(s->scheme, "wss")) { + unsigned char nonce[16], digest[20]; + char challenge[61]; + size_t encoded; + if (!s->ssl || mbedtls_ctr_drbg_random(&s->ssl->ctr_drbg, nonce, sizeof(nonce)) || + mbedtls_base64_encode((unsigned char *)key, sizeof(key), &encoded, nonce, sizeof(nonce))) + goto key_error; + strcpy(challenge, key); + strcat(challenge, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); + mbedtls_sha1((const unsigned char *)challenge, strlen(challenge), digest); + if (mbedtls_base64_encode((unsigned char *)s->expected_accept, + sizeof(s->expected_accept), &encoded, digest, sizeof(digest))) + goto key_error; + } +#endif writed = rws_sprintf(ptr, 512, "GET %s HTTP/%s\r\n", s->path, k_rws_socket_min_http_ver); if (s->port == 80) @@ -1114,7 +1098,7 @@ void rws_socket_send_handshake(_rws_socket *s) "Sec-WebSocket-Key: %s\r\n" "Sec-WebSocket-Version: 13\r\n" "\r\n", - "dGhlIHNhbXBsZSBub25jZQ=="); + key); if (rws_socket_send(s, buff, writed)) { @@ -1133,6 +1117,13 @@ void rws_socket_send_handshake(_rws_socket *s) rws_socket_close(s); s->command = COMMAND_INFORM_DISCONNECTED; } + return; +#ifdef LIBRWS_USING_MBED_TLS +key_error: + s->error = rws_error_new_code_descr(rws_error_code_send_handshake, "WebSocket nonce generation failed"); + rws_socket_close(s); + s->command = COMMAND_INFORM_DISCONNECTED; +#endif } struct addrinfo *rws_socket_connect_getaddr_info(_rws_socket *s) @@ -1313,6 +1304,7 @@ void rws_socket_connect_to_host(_rws_socket *s) ret = getsockopt(sock, SOL_SOCKET, SO_ERROR, &sock_error, &optlen); if(ret == 0 && sock_error == 0) { + ret = 1; printf("connect success\r\n"); } else @@ -1359,13 +1351,14 @@ void rws_socket_connect_to_host(_rws_socket *s) setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout, sizeof(timeout)); } #endif - LOG_I("[T:%.8d, L:%.5d, %*.*s] socket break\n", ql_rtos_get_systicks(), __LINE__, DBG_FUNCTION_NUM, DBG_FUNCTION_NUM, __FUNCTION__); + LOG_I("[T:%.8d, L:%.5d, %*.*s] TCP connected; leaving connect loop\n", ql_rtos_get_systicks(), __LINE__, DBG_FUNCTION_NUM, DBG_FUNCTION_NUM, __FUNCTION__); break; } LOG_E("[T:%.8d, L:%.5d, %*.*s] socket connect failed\n", ql_rtos_get_systicks(), __LINE__, DBG_FUNCTION_NUM, DBG_FUNCTION_NUM, __FUNCTION__); RWS_SOCK_CLOSE(sock); + sock = RWS_INVALID_SOCKET; } else { @@ -1380,6 +1373,7 @@ void rws_socket_connect_to_host(_rws_socket *s) } exit: + if (s->socket == RWS_INVALID_SOCKET && sock != RWS_INVALID_SOCKET) RWS_SOCK_CLOSE(sock); freeaddrinfo(result); if (s->socket == RWS_INVALID_SOCKET) @@ -1559,7 +1553,7 @@ static void rws_socket_work_th_func(void *user_object) LOG_D("[T:%.8d, L:%.5d, %*.*s] COMMAND_INFORM_DISCONNECTED\n", ql_rtos_get_systicks(), __LINE__, DBG_FUNCTION_NUM, DBG_FUNCTION_NUM, __FUNCTION__); s->command = COMMAND_END; - rws_socket_send_disconnect(s); + if (s->is_connected) rws_socket_send_disconnect(s); if (s->on_disconnected) { @@ -1619,27 +1613,16 @@ static void rws_socket_work_th_func(void *user_object) rws_bool rws_socket_create_start_work_thread(_rws_socket *s) { rws_error_delete_clean(&s->error); - //s->work_thread = rws_thread_create(&rws_socket_work_th_func, s); - - if (rws_socket_thread_status!=0){ - // rt_thread_delete(rws_work_task); - s->command = COMMAND_END; - // rws_work_task =NULL; - while(rws_socket_thread_status){ - ql_rtos_task_sleep_ms(20); - } - } - - s->command = COMMAND_NONE; - - ql_rtos_task_create(&rws_work_task,1024*4,100,"rws_work", - rws_socket_work_th_func, s); - - if (rws_work_task) - { - s->command = COMMAND_CONNECT_TO_HOST; + while (rws_socket_thread_status) ql_rtos_task_sleep_ms(20); + s->command = COMMAND_CONNECT_TO_HOST; + s->worker_started = rws_true; + rws_work_task = NULL; + /* TLS certificate parsing and crypto need more stack than plain WS. */ + if (ql_rtos_task_create(&rws_work_task, 1024*16, 100, "rws_work", + rws_socket_work_th_func, s) == 0) return rws_true; - } + s->worker_started = rws_false; + s->command = COMMAND_NONE; return rws_false; } @@ -1867,36 +1850,88 @@ void rws_debug(void *ctx, int level, const char *file, int line, const char *str LOG_I("%s", str ? str : NULL); } -// TODO: mbedtls_ssl_set_hostname() should be called. +/* Prefer a fast, widely supported full-handshake group on this MCU. + * Retain all groups enabled by the shared SDK profile as fallbacks. */ +static const mbedtls_ecp_group_id rws_tls_preferred_curves[] = { + MBEDTLS_ECP_DP_CURVE25519, + MBEDTLS_ECP_DP_SECP256R1, + MBEDTLS_ECP_DP_SECP384R1, + MBEDTLS_ECP_DP_SECP521R1, + MBEDTLS_ECP_DP_CURVE448, + MBEDTLS_ECP_DP_BP512R1, + MBEDTLS_ECP_DP_BP384R1, + MBEDTLS_ECP_DP_BP256R1, + MBEDTLS_ECP_DP_SECP224R1, + MBEDTLS_ECP_DP_SECP224K1, + MBEDTLS_ECP_DP_SECP192R1, + MBEDTLS_ECP_DP_SECP192K1, + MBEDTLS_ECP_DP_NONE +}; + +static const char *rws_tls_phase_name(int state) +{ + switch (state) { + case MBEDTLS_SSL_CLIENT_HELLO: return "client hello"; + case MBEDTLS_SSL_SERVER_HELLO: return "server hello"; + case MBEDTLS_SSL_SERVER_CERTIFICATE: return "server certificate"; + case MBEDTLS_SSL_SERVER_KEY_EXCHANGE: return "server key exchange"; + case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE: return "client key exchange"; + case MBEDTLS_SSL_SERVER_FINISHED: return "server finished"; + default: return "other"; + } +} + +static int rws_tls_handshake_timed(mbedtls_ssl_context *ctx) +{ + unsigned int started = ql_rtos_get_systicks(); + unsigned int phase_started = started, call_ticks = 0, retries = 0; + int state = ctx->state, ret = 0; + while (ctx->state != MBEDTLS_SSL_HANDSHAKE_OVER) { + unsigned int before = ql_rtos_get_systicks(); + ret = mbedtls_ssl_handshake_step(ctx); + call_ticks += (unsigned int)(ql_rtos_get_systicks() - before); + if (ret != 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) + break; + if (ret != 0) ++retries; + if (ctx->state != state) { + if (state == MBEDTLS_SSL_SERVER_KEY_EXCHANGE && ctx->handshake) { + mbedtls_ecp_group_id group = ctx->handshake->ecdh_ctx.grp_id; + LOG_I("WSS TLS negotiated ECDHE group: %d (X25519=%d, P256=%d, P384=%d, P521=%d)\n", + (int)group, (int)MBEDTLS_ECP_DP_CURVE25519, + (int)MBEDTLS_ECP_DP_SECP256R1, (int)MBEDTLS_ECP_DP_SECP384R1, + (int)MBEDTLS_ECP_DP_SECP521R1); + } + LOG_I("WSS TLS phase %s (%d): elapsed=%u ms, calls=%u ms, retries=%u\n", + rws_tls_phase_name(state), state, + (unsigned int)(ql_rtos_get_systicks() - phase_started) * 5, + call_ticks * 5, retries); + state = ctx->state; + phase_started = ql_rtos_get_systicks(); + call_ticks = retries = 0; + } + if (ctx->state == MBEDTLS_SSL_HANDSHAKE_OVER) break; + if ((unsigned int)(ql_rtos_get_systicks() - started) >= 4000) { + ret = MBEDTLS_ERR_SSL_TIMEOUT; /* 20 seconds, 5 ms SDK ticks */ + break; + } + if (ret != 0) rws_thread_sleep(10); + } + LOG_I("WSS TLS handshake total=%u ms, state=%d, ret=%d\n", + (unsigned int)(ql_rtos_get_systicks() - started) * 5, ctx->state, ret); + return ret; +} + int rws_ssl_conn(_rws_socket *s) { - int authmode = MBEDTLS_SSL_VERIFY_NONE; - const char *pers = "https"; - int value, ret = 0; + const char *pers = "talkingq-wss"; + const char *stage = "allocate TLS context"; + int ret = -1; uint32_t flags; - _rws_ssl *ssl = NULL; - char portstr[16] = {0}; - - //value = value; + _rws_ssl *ssl; s->ssl = rws_malloc_zero(sizeof(_rws_ssl)); - if (!s->ssl) - { - LOG_I("Memory malloc error."); - ret = -1; - goto exit; - } + if (!s->ssl) goto exit; ssl = s->ssl; - - if (s->server_cert) - authmode = MBEDTLS_SSL_VERIFY_OPTIONAL; - - /* - * Initialize the RNG and the session data - */ -#if defined(MBEDTLS_DEBUG_C) - mbedtls_debug_set_threshold(DEBUG_LEVEL); -#endif mbedtls_net_init(&ssl->net_ctx); mbedtls_ssl_init(&ssl->ssl_ctx); mbedtls_ssl_config_init(&ssl->ssl_conf); @@ -1904,212 +1939,93 @@ int rws_ssl_conn(_rws_socket *s) mbedtls_x509_crt_init(&ssl->clicert); mbedtls_pk_init(&ssl->pkey); mbedtls_ctr_drbg_init(&ssl->ctr_drbg); - - /* - * 0. Initialize the RNG and the session data - */ mbedtls_entropy_init(&ssl->entropy); - if ((value = mbedtls_ctr_drbg_seed(&ssl->ctr_drbg, - mbedtls_entropy_func, - &ssl->entropy, - (const unsigned char *)pers, - strlen(pers))) != 0) - { - LOG_I("mbedtls_ctr_drbg_seed() failed, value:-0x%x.", -value); - ret = -1; + + if (!s->server_cert || s->server_cert_len <= 0) { + LOG_E("WSS requires a trusted root CA\n"); goto exit; } - - /* - * Load the Client certificate - */ - if (s->client_cert && s->client_pk) - { - ret = mbedtls_x509_crt_parse(&ssl->clicert, (const unsigned char *)s->client_cert, s->client_cert_len); - if (ret < 0) - { - LOG_I("Loading cli_cert failed! mbedtls_x509_crt_parse returned -0x%x.", -ret); - goto exit; - } - - ret = mbedtls_pk_parse_key(&ssl->pkey, (const unsigned char *)s->client_pk, s->client_pk_len, NULL, 0); - if (ret != 0) - { - LOG_I("failed! mbedtls_pk_parse_key returned -0x%x.", -ret); - goto exit; - } - } - - /* - * Load the trusted CA - */ - /* cert_len passed in is gotten from sizeof not strlen */ - if (s->server_cert && ((value = mbedtls_x509_crt_parse(&ssl->cacert, - (const unsigned char *)s->server_cert, - s->server_cert_len)) < 0)) - { - LOG_I("mbedtls_x509_crt_parse() failed, value:-0x%x.", -value); - ret = -1; + if (time(NULL) < 1704067200) { + LOG_E("WSS requires valid network/RTC time before certificate verification\n"); goto exit; } - - // rws_socket_set_option(ssl->net_ctx.fd, SO_ERROR, 1); // When an error occurs on a socket, set error variable so_error and notify process - // rws_socket_set_option(ssl->net_ctx.fd, SO_KEEPALIVE, 1); // Periodically test if connection is alive - - // { - // struct timeval timeout; - - // timeout.tv_sec = 1; - // timeout.tv_usec = 0; - // setsockopt(ssl->net_ctx.fd, SOL_SOCKET, SO_SNDTIMEO, (void *)&timeout, sizeof(timeout)); - // setsockopt(ssl->net_ctx.fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout, sizeof(timeout)); - // } - - /* - * Start the connection - */ - rws_sprintf(portstr, 16, "%i", s->port); - if ((ret = mbedtls_net_connect(&ssl->net_ctx, s->host, portstr, MBEDTLS_NET_PROTO_TCP)) != 0) - { - LOG_I("failed! mbedtls_net_connect returned %d, port:%s.", ret, portstr); - goto exit; - } - - s->received_len = 0; - s->socket = ssl->net_ctx.fd; - - /* - * Setup stuff - */ - if ((value = mbedtls_ssl_config_defaults(&ssl->ssl_conf, - MBEDTLS_SSL_IS_CLIENT, - MBEDTLS_SSL_TRANSPORT_STREAM, - MBEDTLS_SSL_PRESET_DEFAULT)) != 0) - { - LOG_I("mbedtls_ssl_config_defaults() failed, value:-0x%x.", -value); - ret = -1; - goto exit; - } - - // TODO: add customerization encryption algorithm - memcpy(&ssl->profile, ssl->ssl_conf.cert_profile, sizeof(mbedtls_x509_crt_profile)); - ssl->profile.allowed_mds = ssl->profile.allowed_mds | MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_MD5); - mbedtls_ssl_conf_cert_profile(&ssl->ssl_conf, &ssl->profile); - - mbedtls_ssl_conf_authmode(&ssl->ssl_conf, authmode); + stage = "seed RNG"; + ret = mbedtls_ctr_drbg_seed(&ssl->ctr_drbg, mbedtls_entropy_func, + &ssl->entropy, (const unsigned char *)pers, strlen(pers)); + if (ret != 0) goto exit; + stage = "parse root CA"; + ret = mbedtls_x509_crt_parse(&ssl->cacert, (const unsigned char *)s->server_cert, + s->server_cert_len); + if (ret != 0) goto exit; + LOG_I("WSS root CA parsed successfully\n"); + stage = "configure TLS"; + ret = mbedtls_ssl_config_defaults(&ssl->ssl_conf, MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); + if (ret != 0) goto exit; + /* Equivalent to mbedtls_ssl_conf_curves(): this SDK does not export its + setter to APP. The shared profile and ABI test cover curve_list. */ + ssl->ssl_conf.curve_list = rws_tls_preferred_curves; + LOG_I("WSS TLS full handshake: prefer X25519, P256, P384, P521\n"); + mbedtls_ssl_conf_authmode(&ssl->ssl_conf, MBEDTLS_SSL_VERIFY_REQUIRED); mbedtls_ssl_conf_ca_chain(&ssl->ssl_conf, &ssl->cacert, NULL); - mbedtls_ssl_conf_max_frag_len(&ssl->ssl_conf, MBEDTLS_SSL_MAX_FRAG_LEN_4096); - - if (s->client_cert && (ret = mbedtls_ssl_conf_own_cert(&ssl->ssl_conf, &ssl->clicert, &ssl->pkey)) != 0) - { - LOG_I(" failed! mbedtls_ssl_conf_own_cert returned %d.", ret); - goto exit; - } - + mbedtls_ssl_conf_min_version(&ssl->ssl_conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); mbedtls_ssl_conf_rng(&ssl->ssl_conf, mbedtls_ctr_drbg_random, &ssl->ctr_drbg); - mbedtls_ssl_conf_dbg(&ssl->ssl_conf, rws_debug, NULL); + ret = mbedtls_ssl_setup(&ssl->ssl_ctx, &ssl->ssl_conf); + if (ret != 0) goto exit; + /* Sets both SNI and the expected certificate hostname. */ + ret = mbedtls_ssl_set_hostname(&ssl->ssl_ctx, s->host); + if (ret != 0) goto exit; - if ((value = mbedtls_ssl_setup(&ssl->ssl_ctx, &ssl->ssl_conf)) != 0) - { - LOG_I("mbedtls_ssl_setup() failed, value:-0x%x.", -value); - ret = -1; + /* Reuse the working PDP profile 1 TCP path. The ASR net_connect API has + a vendor-specific CID/port ABI, unlike upstream mbedTLS. */ + stage = "connect TCP"; + rws_socket_connect_to_host(s); + if (s->socket == RWS_INVALID_SOCKET) { + ret = MBEDTLS_ERR_NET_CONNECT_FAILED; goto exit; } - - if ((ret = mbedtls_ssl_set_hostname(&ssl->ssl_ctx, s->host)) != 0) - { - LOG_I("failed\n! mbedtls_ssl_set_hostname returned %d\n", ret); - goto exit; - } - + ssl->net_ctx.fd = s->socket; +#ifdef MBEDTLS_WITH_ASR + ssl->net_ctx.cid = 1; +#endif + stage = "set nonblocking TCP"; + ret = mbedtls_net_set_nonblock(&ssl->net_ctx); + if (ret != 0) goto exit; mbedtls_ssl_set_bio(&ssl->ssl_ctx, &ssl->net_ctx, mbedtls_net_send, mbedtls_net_recv, NULL); - - /* - * Handshake - */ - while ((ret = mbedtls_ssl_handshake(&ssl->ssl_ctx)) != 0) - { - if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) - { - LOG_I("mbedtls_ssl_handshake() failed, ret:-0x%x.", -ret); - ret = -1; - goto exit; - } - - LOG_I("mbedtls_ssl_handshake() while"); - } - - LOG_I("mbedtls_ssl_handshake() ok"); - - // Todo - // mbedtls_net_set_nonblock(&ssl->net_ctx); - - { - struct timeval timeout; - - timeout.tv_sec = 3; - timeout.tv_usec = 0; - setsockopt(ssl->net_ctx.fd, SOL_SOCKET, SO_SNDTIMEO, (void *)&timeout, sizeof(timeout)); - - timeout.tv_sec = 0; - timeout.tv_usec = 1000; - setsockopt(ssl->net_ctx.fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout, sizeof(timeout)); - } - - /* - * Verify the server certificate - */ - /* In real life, we would have used MBEDTLS_SSL_VERIFY_REQUIRED so that the - * handshake would not succeed if the peer's cert is bad. Even if we used - * MBEDTLS_SSL_VERIFY_OPTIONAL, we would bail out here if ret != 0 */ - if ((flags = mbedtls_ssl_get_verify_result(&ssl->ssl_ctx)) != 0) - { - char vrfy_buf[512]; - LOG_I("svr_cert varification failed. authmode:%d", authmode); - mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", flags); - LOG_I("%s", vrfy_buf); - } - else - { - LOG_I("svr_cert varification ok. authmode:%d", authmode); + stage = "TLS handshake / server certificate"; + ret = rws_tls_handshake_timed(&ssl->ssl_ctx); + if (ret != 0) goto exit; + flags = mbedtls_ssl_get_verify_result(&ssl->ssl_ctx); + if (flags != 0) { + LOG_E("WSS certificate verification failed: 0x%08lx\n", (unsigned long)flags); + ret = MBEDTLS_ERR_X509_CERT_VERIFY_FAILED; + goto exit; } + LOG_I("WSS TLS handshake and certificate/hostname verification passed: %s:%d\n", s->host, s->port); + s->received_len = 0; + s->command = COMMAND_SEND_HANDSHAKE; + return 0; exit: - if (ret != 0) - { -#ifdef MBEDTLS_ERROR_C - char error_buf[100]; - - extern void mbedtls_strerror(int ret, char *buf, size_t buflen); - mbedtls_strerror(ret, error_buf, 100); - LOG_I("Last error was: %d - %s", ret, error_buf); -#endif - LOG_I("ret=%d.", ret); - s->error = rws_error_new_code_descr(rws_error_code_connect_to_host, "Failed connect to host"); - LOG_I("%s: code:%d, error:%s", __FUNCTION__, s->error->code, s->error->description); - s->command = COMMAND_INFORM_DISCONNECTED; - - if (s->ssl) - { - mbedtls_net_free(&s->ssl->net_ctx); - mbedtls_x509_crt_free(&s->ssl->cacert); - mbedtls_x509_crt_free(&s->ssl->clicert); - mbedtls_pk_free(&s->ssl->pkey); - mbedtls_ssl_free(&s->ssl->ssl_ctx); - mbedtls_ssl_config_free(&s->ssl->ssl_conf); - mbedtls_ctr_drbg_free(&s->ssl->ctr_drbg); - mbedtls_entropy_free(&s->ssl->entropy); - - rws_free(s->ssl); - s->ssl = NULL; - } - - s->socket = RWS_INVALID_SOCKET; - } - else - { - s->command = COMMAND_SEND_HANDSHAKE; + LOG_E("WSS TLS connection failed at %s: %d (-0x%04x)\n", stage, ret, (unsigned int)-ret); + rws_error_delete_clean(&s->error); + s->error = rws_error_new_code_descr(rws_error_code_connect_to_host, "TLS connection or certificate verification failed"); + if (s->ssl) { + /* Do not send close_notify for an incomplete handshake. */ + mbedtls_net_free(&s->ssl->net_ctx); + mbedtls_x509_crt_free(&s->ssl->cacert); + mbedtls_x509_crt_free(&s->ssl->clicert); + mbedtls_pk_free(&s->ssl->pkey); + mbedtls_ssl_free(&s->ssl->ssl_ctx); + mbedtls_ssl_config_free(&s->ssl->ssl_conf); + mbedtls_ctr_drbg_free(&s->ssl->ctr_drbg); + mbedtls_entropy_free(&s->ssl->entropy); + rws_free(s->ssl); + s->ssl = NULL; } + s->socket = RWS_INVALID_SOCKET; + s->is_connected = rws_false; + s->command = COMMAND_INFORM_DISCONNECTED; return ret; } diff --git a/ql-application/threadx/interface/custom_app/lib/librws/src/rws_socketpub.c b/ql-application/threadx/interface/custom_app/lib/librws/src/rws_socketpub.c index b2fb20a..91882b7 100644 --- a/ql-application/threadx/interface/custom_app/lib/librws/src/rws_socketpub.c +++ b/ql-application/threadx/interface/custom_app/lib/librws/src/rws_socketpub.c @@ -94,7 +94,7 @@ void rws_socket_disconnect_and_release(rws_socket socket) s->command = COMMAND_DISCONNECT; rws_mutex_unlock(s->work_mutex); } - else if (s->work_thread) + else if (s->worker_started || s->work_thread) { // disconnected in loop s->command = COMMAND_END; @@ -104,7 +104,7 @@ void rws_socket_disconnect_and_release(rws_socket socket) { // not in loop rws_mutex_unlock(s->work_mutex); - // rws_socket_delete(s); + rws_socket_delete(s); }else{ rws_mutex_unlock(s->work_mutex); } @@ -408,7 +408,7 @@ rws_bool rws_socket_is_connected(rws_socket socket) #ifdef LIBRWS_USING_MBED_TLS void rws_socket_set_server_cert(rws_socket socket, const char *server_cert, int server_cert_len) { - LOG_D("[T:%.8d, L:%.5d, %*.*s] cert:\n%s", ql_rtos_get_systicks(), __LINE__, DBG_FUNCTION_NUM, DBG_FUNCTION_NUM, __FUNCTION__, server_cert_len, server_cert ? server_cert : ""); + LOG_D("WSS trust anchor loaded: %d bytes\n", server_cert_len); _rws_socket *s = (_rws_socket *)socket; if (s) diff --git a/ql-application/threadx/interface/custom_app/mqtt.c b/ql-application/threadx/interface/custom_app/mqtt.c index 9efcce3..0d9da6b 100644 --- a/ql-application/threadx/interface/custom_app/mqtt.c +++ b/ql-application/threadx/interface/custom_app/mqtt.c @@ -4,6 +4,7 @@ =================================================================*/ #include "MQTTClient.h" +#include "mqtt_connect_diag.h" #include "ql_data_call.h" #include "ql_application.h" #include "sockets.h" @@ -25,7 +26,7 @@ #define PROFILE_IDX 1 //#define DEFAULT_SERVER_DOMAIN "175.24.73.253" -#define DEFAULT_SERVER_DOMAIN "101.35.224.118" +#define DEFAULT_SERVER_DOMAIN "banban.api.talkingq.com" #define DEFAULT_SERVER_CLIENT_USER "talkingq" #define DEFAULT_SERVER_CLIENT_PASS "talkingq@2026" #define DEFAULT_SERVER_CLIENT_ID "9376265c059e474e92c2e46208ae1dc5" @@ -448,6 +449,8 @@ int app_mqtt_connect() MQTTPacket_connectData connectData = MQTTPacket_connectData_initializer; int mqtt_server_port=DEFAULT_SERVER_PORT; + unsigned int tcp_started; + int tcp_errno; MQTT_CONN_LOCK(); if(mqtt_connect==1){ @@ -462,7 +465,14 @@ int app_mqtt_connect() NetworkInit(&network, NULL, PROFILE_IDX); MQTTClientInit(&client, &network, 30000, sendbuf, sizeof(sendbuf), readbuf, sizeof(readbuf)); char* address = DEFAULT_SERVER_DOMAIN; - if ((rc = NetworkConnect(&network, address, mqtt_server_port)) != 0) + printf("[MQTT-DIAG] TCP begin host=%s port=%d pdp=%d\r\n", + address, mqtt_server_port, app_get_data_call_net_status()); + tcp_started = ql_rtos_get_systicks(); + rc = NetworkConnect(&network, address, mqtt_server_port); + tcp_errno = rc != 0 ? ql_get_soc_errno() : 0; + printf("[MQTT-DIAG] TCP end rc=%d socket=%d elapsed_ms=%u errno_snapshot=%d\r\n", + rc, network.my_socket, (unsigned int)(ql_rtos_get_systicks() - tcp_started) * 5U, tcp_errno); + if (rc != 0) { RLOGE("Return code from network connect is %d", rc); MQTTClientDeinit(&client); @@ -486,7 +496,8 @@ int app_mqtt_connect() connectData.cleansession = 0; connectData.keepAliveInterval = 60; - if ((rc = MQTTConnect(&client, &connectData)) != 0) + printf("[MQTT-DIAG] saved_device_id=%d (registration needed when 0)\r\n", ret == 0); + if ((rc = talkingq_mqtt_connect_diagnosed(&client, &connectData)) != 0) { RLOGE("Return code from MQTT connect is %d", rc); NetworkDisconnect(&network); diff --git a/ql-application/threadx/interface/custom_app/mqtt_connect_diag.c b/ql-application/threadx/interface/custom_app/mqtt_connect_diag.c new file mode 100644 index 0000000..632bd68 --- /dev/null +++ b/ql-application/threadx/interface/custom_app/mqtt_connect_diag.c @@ -0,0 +1,107 @@ +#include +#include +#include "mqtt_connect_diag.h" +#include "sockets.h" + +/* Only installed during synchronous CONNECT. Never dump the CONNECT payload: + * it contains credentials. Keep only the first four incoming CONNACK bytes. */ +static struct { + int (*read)(Network *, unsigned char *, int, int); + int (*write)(Network *, unsigned char *, int, int); + unsigned int read_calls, write_calls, received, sent; + unsigned char prefix[4]; + unsigned int prefix_size; +} mqtt_diag; + +static unsigned int mqtt_diag_elapsed(unsigned int start) +{ + return (unsigned int)(ql_rtos_get_systicks() - start) * 5U; +} + +static int mqtt_diag_read(Network *network, unsigned char *buffer, int size, int timeout) +{ + unsigned int start = ql_rtos_get_systicks(); + int result = mqtt_diag.read(network, buffer, size, timeout); + int socket_error = result <= 0 ? ql_get_soc_errno() : 0; + int i; + ++mqtt_diag.read_calls; + if (result > 0) { + mqtt_diag.received += (unsigned int)result; + for (i = 0; i < result && i < size && mqtt_diag.prefix_size < sizeof(mqtt_diag.prefix); ++i) + mqtt_diag.prefix[mqtt_diag.prefix_size++] = buffer[i]; + } + printf("[MQTT-DIAG] read request=%d rc=%d timeout_ms=%d elapsed_ms=%u errno_snapshot=%d\r\n", + size, result, timeout, mqtt_diag_elapsed(start), socket_error); + return result; +} + +static int mqtt_diag_write(Network *network, unsigned char *buffer, int size, int timeout) +{ + unsigned int start = ql_rtos_get_systicks(); + int result = mqtt_diag.write(network, buffer, size, timeout); + int socket_error = result <= 0 ? ql_get_soc_errno() : 0; + ++mqtt_diag.write_calls; + if (result > 0) mqtt_diag.sent += (unsigned int)result; + printf("[MQTT-DIAG] write request=%d rc=%d timeout_ms=%d elapsed_ms=%u errno_snapshot=%d\r\n", + size, result, timeout, mqtt_diag_elapsed(start), socket_error); + return result; +} + +static const char *mqtt_diag_connack_reason(unsigned char code) +{ + switch (code) { + case 0: return "accepted"; + case 1: return "protocol_version_rejected"; + case 2: return "client_id_rejected"; + case 3: return "server_unavailable"; + case 4: return "bad_username_or_password"; + case 5: return "not_authorized"; + default: return "reserved_code"; + } +} + +int talkingq_mqtt_connect_diagnosed(MQTTClient *client, MQTTPacket_connectData *options) +{ + Network *network = client->ipstack; + MQTTConnackData connack = {255, 255}; + unsigned int start; + int result; + int valid_connack; + memset(&mqtt_diag, 0, sizeof(mqtt_diag)); + mqtt_diag.read = network->mqttread; + mqtt_diag.write = network->mqttwrite; + if (!mqtt_diag.read || !mqtt_diag.write) { + printf("[MQTT-DIAG] missing transport callbacks; calling SDK unchanged\r\n"); + return MQTTConnectWithResults(client, options, &connack); + } + printf("[MQTT-DIAG] CONNECT begin version=%u clean=%u keepalive_s=%u timeout_ms=%u already_connected=%d\r\n", + (unsigned int)options->MQTTVersion, (unsigned int)options->cleansession, + (unsigned int)options->keepAliveInterval, client->command_timeout_ms, client->isconnected); + network->mqttread = mqtt_diag_read; + network->mqttwrite = mqtt_diag_write; + start = ql_rtos_get_systicks(); + result = MQTTConnectWithResults(client, options, &connack); + network->mqttread = mqtt_diag.read; + network->mqttwrite = mqtt_diag.write; + printf("[MQTT-DIAG] CONNECT end rc=%d elapsed_ms=%u write_calls=%u tx_bytes=%u read_calls=%u rx_bytes=%u\r\n", + result, mqtt_diag_elapsed(start), mqtt_diag.write_calls, mqtt_diag.sent, + mqtt_diag.read_calls, mqtt_diag.received); + valid_connack = mqtt_diag.prefix_size == 4 && mqtt_diag.prefix[0] == 0x20 && + mqtt_diag.prefix[1] == 2 && (mqtt_diag.prefix[2] & 0xfe) == 0 && + mqtt_diag.prefix[3] <= 5 && + (mqtt_diag.prefix[3] == 0 || mqtt_diag.prefix[2] == 0); + if (valid_connack) { + printf("[MQTT-DIAG] CONNACK code=%u reason=%s session_present=%u\r\n", + (unsigned int)mqtt_diag.prefix[3], mqtt_diag_connack_reason(mqtt_diag.prefix[3]), + (unsigned int)mqtt_diag.prefix[2]); + } else if (mqtt_diag.received) { + printf("[MQTT-DIAG] no valid initial CONNACK: received_prefix_bytes=%u\r\n", mqtt_diag.prefix_size); + } else { + printf("[MQTT-DIAG] no response bytes returned by SDK read\r\n"); + } + if (result != 0 && !mqtt_diag.write_calls) + printf("[MQTT-DIAG] failed before transport write; inspect client state/CONNECT serialization\r\n"); + /* SDK read maps both EOF and some socket errors to -1. The errno snapshot + * can be stale; do not claim a broker rejection without a valid CONNACK. */ + return result; +} diff --git a/ql-application/threadx/interface/custom_app/talkingq_root_ca.c b/ql-application/threadx/interface/custom_app/talkingq_root_ca.c new file mode 100644 index 0000000..23555ad --- /dev/null +++ b/ql-application/threadx/interface/custom_app/talkingq_root_ca.c @@ -0,0 +1,18 @@ +#include "talkingq_wss.h" + +/* ISRG Root X2; SHA-256 fingerprint and provenance in docs/talkingq_wss.md. */ +const char talkingq_root_ca[] = + "-----BEGIN CERTIFICATE-----\n" + "MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQswCQYDVQQGEwJV\n" + "UzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElT\n" + "UkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVT\n" + "MSkwJwYDVQQKEyBJbnRlcm5ldCBTZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNS\n" + "RyBSb290IFgyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0H\n" + "ttwW+1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9ItgKbppb\n" + "d9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV\n" + "HQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZIzj0EAwMDaAAwZQIwe3lORlCEwkSHRhtF\n" + "cP9Ymd70/aTSVaYgLXTWNLxBo1BfASdWtL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5\n" + "U6VR5CmD1/iQMVtCnwr1/q4AaOeMSQ+2b1tbFfLn\n" + "-----END CERTIFICATE-----\n" +; +const size_t talkingq_root_ca_size = sizeof(talkingq_root_ca); diff --git a/ql-application/threadx/interface/custom_app/talkingq_wss.c b/ql-application/threadx/interface/custom_app/talkingq_wss.c new file mode 100644 index 0000000..25d7bf6 --- /dev/null +++ b/ql-application/threadx/interface/custom_app/talkingq_wss.c @@ -0,0 +1,53 @@ +#include "talkingq_wss.h" +#include + +int talkingq_is_legacy_ws_url(const char *url) +{ + return url && (!strcmp(url, "ws://101.35.224.118:8080") || + !strcmp(url, "ws://101.35.224.118:8080/ws") || + !strcmp(url, "ws://api.talkingq.com:8080") || + !strcmp(url, "ws://175.24.73.253:80")); +} + +int talkingq_parse_wss_url(const char *url, char *host, size_t host_size, + int *port, char *path, size_t path_size) +{ + const char *begin, *end, *colon, *cursor, *resource; + size_t length; + unsigned int value = 0; + if (!url || !host || !port || !path || strncmp(url, "wss://", 6)) + return -1; + begin = url + 6; + end = strchr(begin, '/'); + if (!end) end = begin + strlen(begin); + colon = memchr(begin, ':', (size_t)(end - begin)); + length = (size_t)((colon ? colon : end) - begin); + if (!length || length >= host_size) return -1; + for (cursor = begin; cursor < begin + length; ++cursor) { + char c = *cursor; + if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || c == '.' || c == '-')) return -1; + } + if (colon) { + if (colon + 1 == end) return -1; + for (cursor = colon + 1; cursor < end; ++cursor) { + if (*cursor < '0' || *cursor > '9') return -1; + value = value * 10 + (unsigned int)(*cursor - '0'); + if (value > 65535) return -1; + } + if (!value) return -1; + } else { + value = 443; + } + resource = *end ? end : "/ws"; + if (strlen(resource) >= path_size) return -1; + for (cursor = resource; *cursor; ++cursor) { + if ((unsigned char)*cursor <= 32 || *cursor == '#' || + (unsigned char)*cursor >= 127) return -1; + } + memcpy(host, begin, length); + host[length] = '\0'; + strcpy(path, resource); + *port = (int)value; + return 0; +} diff --git a/ql-application/threadx/interface/custom_app/ws_talkingq.c b/ql-application/threadx/interface/custom_app/ws_talkingq.c index eed21b5..47abe9c 100644 --- a/ql-application/threadx/interface/custom_app/ws_talkingq.c +++ b/ql-application/threadx/interface/custom_app/ws_talkingq.c @@ -3,6 +3,7 @@ #include #include "cJSON.h" #include "app_inc.h" +#include "talkingq_wss.h" #include "ql_rtos.h" #include "ql_application.h" #include "ql_audio.h" @@ -129,6 +130,7 @@ unsigned char get_xiaoice_connected_status(void) static void onopen(rws_socket socket) { + if (socket != app->socket || !app->init) return; wss_connect_counter=0; LOG_D("websocket connected. "); @@ -153,12 +155,14 @@ static void onclose(rws_socket socket) LOG_D("websocket disconnect! "); } - xiaoice_wss_connect_status = 0; - - rws_socket_disconnect_and_release(app->socket); + if (socket != app->socket) return; + xiaoice_wss_connect_status = 0; + app->socket = NULL; + /* The worker owns and releases this socket after the callback. */ RLOGD("onclose end\r\n"); app->init = 0; + if (ws_connect_sem) ql_rtos_semaphore_release(ws_connect_sem); hal_led_b_off(); } @@ -305,8 +309,8 @@ int talkingq_ws_connect() { int result; int ret = -1; - char wss_path[56]={0}; - char ws_talkingq_url[56]={0}; + char wss_path[TALKINGQ_PATH_CAPACITY]={0}; + char ws_talkingq_url[TALKINGQ_URL_CAPACITY]={0}; int port; // char session_id[56]={0}; // char ip_name[56]={0}; @@ -329,40 +333,33 @@ int talkingq_ws_connect() ql_rtos_semaphore_create(&ws_connect_sem, 0); } - sprintf(wss_path,"%s","/ws"); + if (ws_connect_sem) while (ql_rtos_semaphore_wait(ws_connect_sem, 0) == 0) {} hal_os_get_talkingq_url(ws_talkingq_url); printf("ws_talkingq_url %s",ws_talkingq_url); - if(strncmp(ws_talkingq_url,"ws://",5)){ - printf("error ws url %s",ws_talkingq_url); - return -1; - } - - char *testp = strstr(ws_talkingq_url+5,":"); - if(!testp){ - strcpy(talkingq_host,ws_talkingq_url+5); - port = 80; - }else{ - port = atoi(testp+1); - *testp = 0; - strcpy(talkingq_host,ws_talkingq_url+5); - } + if (talkingq_parse_wss_url(ws_talkingq_url, talkingq_host, sizeof(talkingq_host), + &port, wss_path, sizeof(wss_path)) != 0) { + LOG_E("Invalid WSS endpoint; cleartext fallback is disabled\n"); + app->init = 0; + xiaoice_wss_connect_status = 0; + return -1; + } app->socket = rws_socket_create(); if(app->socket == NULL) { - app->init = 0; + app->init = 0; + xiaoice_wss_connect_status = 0; LOG_E("librws socket create failed. "); return (-1); } printf("talkingq host %s , port %d",talkingq_host,port); - //todo wss - //rws_socket_set_url(app->socket, "ws", "hz.api.talkingq.com", 8080, wss_path); - //118.25.13.180:8080 - rws_socket_set_url(app->socket, "ws", talkingq_host, port, wss_path); + /* Server-authenticated TLS; application authentication stays in onopen. */ + rws_socket_set_url(app->socket, "wss", talkingq_host, port, wss_path); + rws_socket_set_server_cert(app->socket, talkingq_root_ca, talkingq_root_ca_size); rws_socket_set_on_connected(app->socket, &onopen); rws_socket_set_on_disconnected(app->socket, &onclose); @@ -374,7 +371,9 @@ int talkingq_ws_connect() ret = rws_socket_connect(app->socket); if(ret == rws_false) { - app->init = 0; + rws_socket_disconnect_and_release(app->socket); + app->socket = NULL; + app->init = 0; LOG_E("rws_socket_connect failed. "); ret = -1; } @@ -383,14 +382,17 @@ int talkingq_ws_connect() ret = -1; LOG_D("try rws_socket_connect. "); if(ws_connect_sem){ - result = ql_rtos_semaphore_wait(ws_connect_sem, 10000); - if(result==0){ + result = ql_rtos_semaphore_wait(ws_connect_sem, 45000); + if(result == 0 && app->init && app->socket && rws_socket_is_connected(app->socket)){ LOG_I("ws connect okay"); wss_connect_counter = 0; ret = 0; }else{ - app->init = 0; - LOG_E("ws connect wait timeout"); + /* Stop the pending worker before allowing a new attempt. */ + if (app->socket) rws_socket_disconnect_and_release(app->socket); + app->socket = NULL; + app->init = 0; + LOG_E("ws connect failed or wait timeout"); wss_connect_counter++; } }else{ @@ -399,7 +401,7 @@ int talkingq_ws_connect() } } - if(app->init == 1){ + if(ret == 0 && app->init == 1){ xiaoice_wss_connect_status = 2; hal_led_b_on(); } diff --git a/ql-config/config/talkingq_mbedtls_config.h b/ql-config/config/talkingq_mbedtls_config.h new file mode 100644 index 0000000..0b0a0f9 --- /dev/null +++ b/ql-config/config/talkingq_mbedtls_config.h @@ -0,0 +1,79 @@ +#ifndef TALKINGQ_MBEDTLS_CONFIG_H +#define TALKINGQ_MBEDTLS_CONFIG_H + +/* Shared by kernel and APP: these options determine public struct layouts. + * Retain the vendor mini profile and add verified ECDSA TLS 1.2 support. */ +#define MBEDTLS_HAVE_ASM +#define MBEDTLS_HAVE_TIME +#define MBEDTLS_HAVE_TIME_DATE +#define MBEDTLS_PLATFORM_TIME_ALT +#define TALKINGQ_TLS_USE_RTC_TIME +#define MBEDTLS_CIPHER_MODE_CBC +#define MBEDTLS_PKCS1_V15 +#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED +#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED +#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED +#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED +#define MBEDTLS_SSL_PROTO_TLS1_1 +#define MBEDTLS_SSL_PROTO_TLS1_2 +#define MBEDTLS_SSL_SERVER_NAME_INDICATION +#define MBEDTLS_SSL_RENEGOTIATION +#define MBEDTLS_SSL_EXPORT_KEYS +#define MBEDTLS_AES_C +#define MBEDTLS_GCM_C +#define MBEDTLS_ASN1_PARSE_C +#define MBEDTLS_ASN1_WRITE_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_CIPHER_C +#define MBEDTLS_CTR_DRBG_C +#define MBEDTLS_DES_C +#define MBEDTLS_ENTROPY_C +#define MBEDTLS_MD_C +#define MBEDTLS_MD5_C +#define MBEDTLS_NET_C +#define MBEDTLS_OID_C +#define MBEDTLS_PK_C +#define MBEDTLS_PK_PARSE_C +#define MBEDTLS_RSA_C +#define MBEDTLS_SHA1_C +#define MBEDTLS_SHA224_C +#define MBEDTLS_SHA256_C +#define MBEDTLS_SHA384_C +#define MBEDTLS_SHA512_C +#define MBEDTLS_SSL_CLI_C +#define MBEDTLS_SSL_TLS_C +#define MBEDTLS_X509_CRT_PARSE_C +#define MBEDTLS_X509_USE_C +#define MBEDTLS_BASE64_C +#define MBEDTLS_CERTS_C +#define MBEDTLS_PEM_PARSE_C +#define MBEDTLS_FS_IO +#define MBEDTLS_NO_PLATFORM_ENTROPY +#define MBEDTLS_ENTROPY_HARDWARE_ALT +#define MBEDTLS_PLATFORM_MEMORY +#define MBEDTLS_PLATFORM_C +#define MBEDTLS_ECP_C +/* Use mbedTLS's fast modular reduction for NIST certificate/ECDHE curves. */ +#define MBEDTLS_ECP_NIST_OPTIM +#define MBEDTLS_ECDH_C +#define MBEDTLS_ECDSA_C +#define MBEDTLS_CHACHAPOLY_C +#define MBEDTLS_CHACHA20_C +#define MBEDTLS_POLY1305_C +#define MBEDTLS_ECP_DP_SECP192R1_ENABLED +#define MBEDTLS_ECP_DP_SECP224R1_ENABLED +#define MBEDTLS_ECP_DP_SECP256R1_ENABLED +#define MBEDTLS_ECP_DP_SECP384R1_ENABLED +#define MBEDTLS_ECP_DP_SECP521R1_ENABLED +#define MBEDTLS_ECP_DP_SECP192K1_ENABLED +#define MBEDTLS_ECP_DP_SECP224K1_ENABLED +#define MBEDTLS_ECP_DP_BP256R1_ENABLED +#define MBEDTLS_ECP_DP_BP384R1_ENABLED +#define MBEDTLS_ECP_DP_BP512R1_ENABLED +#define MBEDTLS_ECP_DP_CURVE25519_ENABLED +#define MBEDTLS_ECP_DP_CURVE448_ENABLED + +/* SDK-specific net context and hardware RNG ABI. */ +#define MBEDTLS_WITH_ASR +#define QUECTEL_MBEDTLS_GEU_RANDOM_SUPPORT +#endif diff --git a/ql-kernel/threadx/common/include/config.h b/ql-kernel/threadx/common/include/config.h index 49ad3d9..942acb8 100644 --- a/ql-kernel/threadx/common/include/config.h +++ b/ql-kernel/threadx/common/include/config.h @@ -4339,86 +4339,7 @@ #define MBEDTLS_PLATFORM_C #endif #else //mini tls config - -/* System support */ -#define MBEDTLS_HAVE_ASM -#define MBEDTLS_HAVE_TIME - -/* mbed TLS feature support */ -#define MBEDTLS_CIPHER_MODE_CBC -#define MBEDTLS_PKCS1_V15 -#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED -#define MBEDTLS_SSL_PROTO_TLS1_1 -#define MBEDTLS_SSL_PROTO_TLS1_2 - -/* mbed TLS modules */ -#define MBEDTLS_AES_C -#define MBEDTLS_ASN1_PARSE_C -#define MBEDTLS_ASN1_WRITE_C -#define MBEDTLS_BIGNUM_C -#define MBEDTLS_CIPHER_C -#define MBEDTLS_CTR_DRBG_C -#define MBEDTLS_DES_C -#define MBEDTLS_ENTROPY_C -#define MBEDTLS_MD_C -#define MBEDTLS_MD5_C -#define MBEDTLS_NET_C -#define MBEDTLS_OID_C -#define MBEDTLS_PK_C -#define MBEDTLS_PK_PARSE_C -#define MBEDTLS_RSA_C -#define MBEDTLS_SHA1_C -#define MBEDTLS_SHA224_C -#define MBEDTLS_SHA256_C -#define MBEDTLS_SHA384_C -#define MBEDTLS_SHA512_C -#define MBEDTLS_SSL_CLI_C -//#define MBEDTLS_SSL_SRV_C -#define MBEDTLS_SSL_TLS_C -#define MBEDTLS_X509_CRT_PARSE_C -#define MBEDTLS_X509_USE_C - -/* For test certificates */ -#define MBEDTLS_BASE64_C -#define MBEDTLS_CERTS_C -#define MBEDTLS_PEM_PARSE_C - -/* For testing with compat.sh */ -#define MBEDTLS_FS_IO - -#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED -#define MBEDTLS_NO_PLATFORM_ENTROPY -#define MBEDTLS_ENTROPY_HARDWARE_ALT - -#define MBEDTLS_SSL_SERVER_NAME_INDICATION - -#define MBEDTLS_SSL_RENEGOTIATION -#define MBEDTLS_SSL_EXPORT_KEYS -#define MBEDTLS_PLATFORM_MEMORY -#define MBEDTLS_PLATFORM_C - -#define MBEDTLS_ECP_C -#define MBEDTLS_ECDH_C -#define MBEDTLS_CHACHAPOLY_C -#define MBEDTLS_CHACHA20_C -#define MBEDTLS_POLY1305_C - -#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED -#define MBEDTLS_ECP_DP_SECP192R1_ENABLED -#define MBEDTLS_ECP_DP_SECP224R1_ENABLED -#define MBEDTLS_ECP_DP_SECP256R1_ENABLED -#define MBEDTLS_ECP_DP_SECP384R1_ENABLED -#define MBEDTLS_ECP_DP_SECP521R1_ENABLED -#define MBEDTLS_ECP_DP_SECP192K1_ENABLED -#define MBEDTLS_ECP_DP_SECP224K1_ENABLED -#define MBEDTLS_ECP_DP_SECP256K1_ENABLED -#define MBEDTLS_ECP_DP_BP256R1_ENABLED -#define MBEDTLS_ECP_DP_BP384R1_ENABLED -#define MBEDTLS_ECP_DP_BP512R1_ENABLED -#define MBEDTLS_ECP_DP_CURVE25519_ENABLED -#define MBEDTLS_ECP_DP_CURVE448_ENABLED - -//#define MBEDTLS_DEBUG_C +#include "../../../../ql-config/config/talkingq_mbedtls_config.h" #endif #if defined(MBEDTLS_USER_CONFIG_FILE) diff --git a/ql-kernel/threadx/common/include/mbedtls/config.h b/ql-kernel/threadx/common/include/mbedtls/config.h index 49ad3d9..7dc7522 100644 --- a/ql-kernel/threadx/common/include/mbedtls/config.h +++ b/ql-kernel/threadx/common/include/mbedtls/config.h @@ -4339,86 +4339,7 @@ #define MBEDTLS_PLATFORM_C #endif #else //mini tls config - -/* System support */ -#define MBEDTLS_HAVE_ASM -#define MBEDTLS_HAVE_TIME - -/* mbed TLS feature support */ -#define MBEDTLS_CIPHER_MODE_CBC -#define MBEDTLS_PKCS1_V15 -#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED -#define MBEDTLS_SSL_PROTO_TLS1_1 -#define MBEDTLS_SSL_PROTO_TLS1_2 - -/* mbed TLS modules */ -#define MBEDTLS_AES_C -#define MBEDTLS_ASN1_PARSE_C -#define MBEDTLS_ASN1_WRITE_C -#define MBEDTLS_BIGNUM_C -#define MBEDTLS_CIPHER_C -#define MBEDTLS_CTR_DRBG_C -#define MBEDTLS_DES_C -#define MBEDTLS_ENTROPY_C -#define MBEDTLS_MD_C -#define MBEDTLS_MD5_C -#define MBEDTLS_NET_C -#define MBEDTLS_OID_C -#define MBEDTLS_PK_C -#define MBEDTLS_PK_PARSE_C -#define MBEDTLS_RSA_C -#define MBEDTLS_SHA1_C -#define MBEDTLS_SHA224_C -#define MBEDTLS_SHA256_C -#define MBEDTLS_SHA384_C -#define MBEDTLS_SHA512_C -#define MBEDTLS_SSL_CLI_C -//#define MBEDTLS_SSL_SRV_C -#define MBEDTLS_SSL_TLS_C -#define MBEDTLS_X509_CRT_PARSE_C -#define MBEDTLS_X509_USE_C - -/* For test certificates */ -#define MBEDTLS_BASE64_C -#define MBEDTLS_CERTS_C -#define MBEDTLS_PEM_PARSE_C - -/* For testing with compat.sh */ -#define MBEDTLS_FS_IO - -#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED -#define MBEDTLS_NO_PLATFORM_ENTROPY -#define MBEDTLS_ENTROPY_HARDWARE_ALT - -#define MBEDTLS_SSL_SERVER_NAME_INDICATION - -#define MBEDTLS_SSL_RENEGOTIATION -#define MBEDTLS_SSL_EXPORT_KEYS -#define MBEDTLS_PLATFORM_MEMORY -#define MBEDTLS_PLATFORM_C - -#define MBEDTLS_ECP_C -#define MBEDTLS_ECDH_C -#define MBEDTLS_CHACHAPOLY_C -#define MBEDTLS_CHACHA20_C -#define MBEDTLS_POLY1305_C - -#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED -#define MBEDTLS_ECP_DP_SECP192R1_ENABLED -#define MBEDTLS_ECP_DP_SECP224R1_ENABLED -#define MBEDTLS_ECP_DP_SECP256R1_ENABLED -#define MBEDTLS_ECP_DP_SECP384R1_ENABLED -#define MBEDTLS_ECP_DP_SECP521R1_ENABLED -#define MBEDTLS_ECP_DP_SECP192K1_ENABLED -#define MBEDTLS_ECP_DP_SECP224K1_ENABLED -#define MBEDTLS_ECP_DP_SECP256K1_ENABLED -#define MBEDTLS_ECP_DP_BP256R1_ENABLED -#define MBEDTLS_ECP_DP_BP384R1_ENABLED -#define MBEDTLS_ECP_DP_BP512R1_ENABLED -#define MBEDTLS_ECP_DP_CURVE25519_ENABLED -#define MBEDTLS_ECP_DP_CURVE448_ENABLED - -//#define MBEDTLS_DEBUG_C +#include "../../../../../ql-config/config/talkingq_mbedtls_config.h" #endif #if defined(MBEDTLS_USER_CONFIG_FILE) diff --git a/ql-kernel/threadx/common/include/mbedtls/ecdsa.h b/ql-kernel/threadx/common/include/mbedtls/ecdsa.h new file mode 100644 index 0000000..34a6b13 --- /dev/null +++ b/ql-kernel/threadx/common/include/mbedtls/ecdsa.h @@ -0,0 +1,612 @@ +/** + * \file ecdsa.h + * + * \brief This file contains ECDSA definitions and functions. + * + * The Elliptic Curve Digital Signature Algorithm (ECDSA) is defined in + * Standards for Efficient Cryptography Group (SECG): + * SEC1 Elliptic Curve Cryptography. + * The use of ECDSA for TLS is defined in RFC-4492: Elliptic Curve + * Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS). + * + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_ECDSA_H +#define MBEDTLS_ECDSA_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbedtls/ecp.h" +#include "mbedtls/md.h" + +/** + * \brief Maximum ECDSA signature size for a given curve bit size + * + * \param bits Curve size in bits + * \return Maximum signature size in bytes + * + * \note This macro returns a compile-time constant if its argument + * is one. It may evaluate its argument multiple times. + */ +/* + * Ecdsa-Sig-Value ::= SEQUENCE { + * r INTEGER, + * s INTEGER + * } + * + * For each of r and s, the value (V) may include an extra initial "0" bit. + */ +#define MBEDTLS_ECDSA_MAX_SIG_LEN(bits) \ + (/*T,L of SEQUENCE*/ ((bits) >= 61 * 8 ? 3 : 2) + \ + /*T,L of r,s*/ 2 * (((bits) >= 127 * 8 ? 3 : 2) + \ + /*V of r,s*/ ((bits) + 8) / 8)) + +/** The maximal size of an ECDSA signature in Bytes. */ +#define MBEDTLS_ECDSA_MAX_LEN MBEDTLS_ECDSA_MAX_SIG_LEN(MBEDTLS_ECP_MAX_BITS) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief The ECDSA context structure. + * + * \warning Performing multiple operations concurrently on the same + * ECDSA context is not supported; objects of this type + * should not be shared between multiple threads. + */ +typedef mbedtls_ecp_keypair mbedtls_ecdsa_context; + +#if defined(MBEDTLS_ECP_RESTARTABLE) + +/** + * \brief Internal restart context for ecdsa_verify() + * + * \note Opaque struct, defined in ecdsa.c + */ +typedef struct mbedtls_ecdsa_restart_ver mbedtls_ecdsa_restart_ver_ctx; + +/** + * \brief Internal restart context for ecdsa_sign() + * + * \note Opaque struct, defined in ecdsa.c + */ +typedef struct mbedtls_ecdsa_restart_sig mbedtls_ecdsa_restart_sig_ctx; + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) +/** + * \brief Internal restart context for ecdsa_sign_det() + * + * \note Opaque struct, defined in ecdsa.c + */ +typedef struct mbedtls_ecdsa_restart_det mbedtls_ecdsa_restart_det_ctx; +#endif + +/** + * \brief General context for resuming ECDSA operations + */ +typedef struct { + mbedtls_ecp_restart_ctx ecp; /*!< base context for ECP restart and + shared administrative info */ + mbedtls_ecdsa_restart_ver_ctx *ver; /*!< ecdsa_verify() sub-context */ + mbedtls_ecdsa_restart_sig_ctx *sig; /*!< ecdsa_sign() sub-context */ +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) + mbedtls_ecdsa_restart_det_ctx *det; /*!< ecdsa_sign_det() sub-context */ +#endif +} mbedtls_ecdsa_restart_ctx; + +#else /* MBEDTLS_ECP_RESTARTABLE */ + +/* Now we can declare functions that take a pointer to that */ +typedef void mbedtls_ecdsa_restart_ctx; + +#endif /* MBEDTLS_ECP_RESTARTABLE */ + +/** + * \brief This function checks whether a given group can be used + * for ECDSA. + * + * \param gid The ECP group ID to check. + * + * \return \c 1 if the group can be used, \c 0 otherwise + */ +int mbedtls_ecdsa_can_do(mbedtls_ecp_group_id gid); + +/** + * \brief This function computes the ECDSA signature of a + * previously-hashed message. + * + * \note The deterministic version implemented in + * mbedtls_ecdsa_sign_det() is usually preferred. + * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated + * as defined in Standards for Efficient Cryptography Group + * (SECG): SEC1 Elliptic Curve Cryptography, section + * 4.1.3, step 5. + * + * \see ecp.h + * + * \param grp The context for the elliptic curve to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param r The MPI context in which to store the first part + * the signature. This must be initialized. + * \param s The MPI context in which to store the second part + * the signature. This must be initialized. + * \param d The private signing key. This must be initialized. + * \param buf The content to be signed. This is usually the hash of + * the original data to be signed. This must be a readable + * buffer of length \p blen Bytes. It may be \c NULL if + * \p blen is zero. + * \param blen The length of \p buf in Bytes. + * \param f_rng The RNG function. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context parameter. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX + * or \c MBEDTLS_MPI_XXX error code on failure. + */ +int mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, + const mbedtls_mpi *d, const unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif +/** + * \brief This function computes the ECDSA signature of a + * previously-hashed message, deterministic version. + * + * For more information, see RFC-6979: Deterministic + * Usage of the Digital Signature Algorithm (DSA) and Elliptic + * Curve Digital Signature Algorithm (ECDSA). + * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * defined in Standards for Efficient Cryptography Group + * (SECG): SEC1 Elliptic Curve Cryptography, section + * 4.1.3, step 5. + * + * \warning Since the output of the internal RNG is always the same for + * the same key and message, this limits the efficiency of + * blinding and leaks information through side channels. For + * secure behavior use mbedtls_ecdsa_sign_det_ext() instead. + * + * (Optimally the blinding is a random value that is different + * on every execution. In this case the blinding is still + * random from the attackers perspective, but is the same on + * each execution. This means that this blinding does not + * prevent attackers from recovering secrets by combining + * several measurement traces, but may prevent some attacks + * that exploit relationships between secret data.) + * + * \see ecp.h + * + * \param grp The context for the elliptic curve to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param r The MPI context in which to store the first part + * the signature. This must be initialized. + * \param s The MPI context in which to store the second part + * the signature. This must be initialized. + * \param d The private signing key. This must be initialized + * and setup, for example through mbedtls_ecp_gen_privkey(). + * \param buf The hashed content to be signed. This must be a readable + * buffer of length \p blen Bytes. It may be \c NULL if + * \p blen is zero. + * \param blen The length of \p buf in Bytes. + * \param md_alg The hash algorithm used to hash the original data. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX + * error code on failure. + */ +int mbedtls_ecdsa_sign_det(mbedtls_ecp_group *grp, mbedtls_mpi *r, + mbedtls_mpi *s, const mbedtls_mpi *d, + const unsigned char *buf, size_t blen, + mbedtls_md_type_t md_alg) MBEDTLS_DEPRECATED; +#undef MBEDTLS_DEPRECATED +#endif /* MBEDTLS_DEPRECATED_REMOVED */ + +/** + * \brief This function computes the ECDSA signature of a + * previously-hashed message, deterministic version. + * + * For more information, see RFC-6979: Deterministic + * Usage of the Digital Signature Algorithm (DSA) and Elliptic + * Curve Digital Signature Algorithm (ECDSA). + * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * defined in Standards for Efficient Cryptography Group + * (SECG): SEC1 Elliptic Curve Cryptography, section + * 4.1.3, step 5. + * + * \see ecp.h + * + * \param grp The context for the elliptic curve to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param r The MPI context in which to store the first part + * the signature. This must be initialized. + * \param s The MPI context in which to store the second part + * the signature. This must be initialized. + * \param d The private signing key. This must be initialized + * and setup, for example through mbedtls_ecp_gen_privkey(). + * \param buf The hashed content to be signed. This must be a readable + * buffer of length \p blen Bytes. It may be \c NULL if + * \p blen is zero. + * \param blen The length of \p buf in Bytes. + * \param md_alg The hash algorithm used to hash the original data. + * \param f_rng_blind The RNG function used for blinding. This must not be + * \c NULL. + * \param p_rng_blind The RNG context to be passed to \p f_rng_blind. This + * may be \c NULL if \p f_rng_blind doesn't need + * a context parameter. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX + * error code on failure. + */ +int mbedtls_ecdsa_sign_det_ext(mbedtls_ecp_group *grp, mbedtls_mpi *r, + mbedtls_mpi *s, const mbedtls_mpi *d, + const unsigned char *buf, size_t blen, + mbedtls_md_type_t md_alg, + int (*f_rng_blind)(void *, unsigned char *, size_t), + void *p_rng_blind); +#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ + +/** + * \brief This function verifies the ECDSA signature of a + * previously-hashed message. + * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * defined in Standards for Efficient Cryptography Group + * (SECG): SEC1 Elliptic Curve Cryptography, section + * 4.1.4, step 3. + * + * \see ecp.h + * + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param buf The hashed content that was signed. This must be a readable + * buffer of length \p blen Bytes. It may be \c NULL if + * \p blen is zero. + * \param blen The length of \p buf in Bytes. + * \param Q The public key to use for verification. This must be + * initialized and setup. + * \param r The first integer of the signature. + * This must be initialized. + * \param s The second integer of the signature. + * This must be initialized. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX + * error code on failure. + */ +int mbedtls_ecdsa_verify(mbedtls_ecp_group *grp, + const unsigned char *buf, size_t blen, + const mbedtls_ecp_point *Q, const mbedtls_mpi *r, + const mbedtls_mpi *s); + +/** + * \brief This function computes the ECDSA signature and writes it + * to a buffer, serialized as defined in RFC-4492: + * Elliptic Curve Cryptography (ECC) Cipher Suites for + * Transport Layer Security (TLS). + * + * \warning It is not thread-safe to use the same context in + * multiple threads. + * + * \note The deterministic version is used if + * #MBEDTLS_ECDSA_DETERMINISTIC is defined. For more + * information, see RFC-6979: Deterministic Usage + * of the Digital Signature Algorithm (DSA) and Elliptic + * Curve Digital Signature Algorithm (ECDSA). + * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * defined in Standards for Efficient Cryptography Group + * (SECG): SEC1 Elliptic Curve Cryptography, section + * 4.1.3, step 5. + * + * \see ecp.h + * + * \param ctx The ECDSA context to use. This must be initialized + * and have a group and private key bound to it, for example + * via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair(). + * \param md_alg The message digest that was used to hash the message. + * \param hash The message hash to be signed. This must be a readable + * buffer of length \p hlen Bytes. + * \param hlen The length of the hash \p hash in Bytes. + * \param sig The buffer to which to write the signature. This must be a + * writable buffer of length at least twice as large as the + * size of the curve used, plus 9. For example, 73 Bytes if + * a 256-bit curve is used. A buffer length of + * #MBEDTLS_ECDSA_MAX_LEN is always safe. + * \param slen The address at which to store the actual length of + * the signature written. Must not be \c NULL. + * \param f_rng The RNG function. This must not be \c NULL if + * #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise, + * it is used only for blinding and may be set to \c NULL, but + * doing so is DEPRECATED. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng is \c NULL or doesn't use a context. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or + * \c MBEDTLS_ERR_ASN1_XXX error code on failure. + */ +int mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context *ctx, + mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t *slen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +/** + * \brief This function computes the ECDSA signature and writes it + * to a buffer, in a restartable way. + * + * \see \c mbedtls_ecdsa_write_signature() + * + * \note This function is like \c mbedtls_ecdsa_write_signature() + * but it can return early and restart according to the limit + * set with \c mbedtls_ecp_set_max_ops() to reduce blocking. + * + * \param ctx The ECDSA context to use. This must be initialized + * and have a group and private key bound to it, for example + * via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair(). + * \param md_alg The message digest that was used to hash the message. + * \param hash The message hash to be signed. This must be a readable + * buffer of length \p hlen Bytes. + * \param hlen The length of the hash \p hash in Bytes. + * \param sig The buffer to which to write the signature. This must be a + * writable buffer of length at least twice as large as the + * size of the curve used, plus 9. For example, 73 Bytes if + * a 256-bit curve is used. A buffer length of + * #MBEDTLS_ECDSA_MAX_LEN is always safe. + * \param slen The address at which to store the actual length of + * the signature written. Must not be \c NULL. + * \param f_rng The RNG function. This must not be \c NULL if + * #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise, + * it is unused and may be set to \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng is \c NULL or doesn't use a context. + * \param rs_ctx The restart context to use. This may be \c NULL to disable + * restarting. If it is not \c NULL, it must point to an + * initialized restart context. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + * \return Another \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or + * \c MBEDTLS_ERR_ASN1_XXX error code on failure. + */ +int mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx, + mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t *slen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + mbedtls_ecdsa_restart_ctx *rs_ctx); + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif +/** + * \brief This function computes an ECDSA signature and writes + * it to a buffer, serialized as defined in RFC-4492: + * Elliptic Curve Cryptography (ECC) Cipher Suites for + * Transport Layer Security (TLS). + * + * The deterministic version is defined in RFC-6979: + * Deterministic Usage of the Digital Signature Algorithm (DSA) + * and Elliptic Curve Digital Signature Algorithm (ECDSA). + * + * \warning It is not thread-safe to use the same context in + * multiple threads. + * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * defined in Standards for Efficient Cryptography Group + * (SECG): SEC1 Elliptic Curve Cryptography, section + * 4.1.3, step 5. + * + * \see ecp.h + * + * \deprecated Superseded by mbedtls_ecdsa_write_signature() in + * Mbed TLS version 2.0 and later. + * + * \param ctx The ECDSA context to use. This must be initialized + * and have a group and private key bound to it, for example + * via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair(). + * \param hash The message hash to be signed. This must be a readable + * buffer of length \p hlen Bytes. + * \param hlen The length of the hash \p hash in Bytes. + * \param sig The buffer to which to write the signature. This must be a + * writable buffer of length at least twice as large as the + * size of the curve used, plus 9. For example, 73 Bytes if + * a 256-bit curve is used. A buffer length of + * #MBEDTLS_ECDSA_MAX_LEN is always safe. + * \param slen The address at which to store the actual length of + * the signature written. Must not be \c NULL. + * \param md_alg The message digest that was used to hash the message. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or + * \c MBEDTLS_ERR_ASN1_XXX error code on failure. + */ +int mbedtls_ecdsa_write_signature_det(mbedtls_ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t *slen, + mbedtls_md_type_t md_alg) MBEDTLS_DEPRECATED; +#undef MBEDTLS_DEPRECATED +#endif /* MBEDTLS_DEPRECATED_REMOVED */ +#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ + +/** + * \brief This function reads and verifies an ECDSA signature. + * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * defined in Standards for Efficient Cryptography Group + * (SECG): SEC1 Elliptic Curve Cryptography, section + * 4.1.4, step 3. + * + * \see ecp.h + * + * \param ctx The ECDSA context to use. This must be initialized + * and have a group and public key bound to it. + * \param hash The message hash that was signed. This must be a readable + * buffer of length \p hlen Bytes. + * \param hlen The size of the hash \p hash. + * \param sig The signature to read and verify. This must be a readable + * buffer of length \p slen Bytes. + * \param slen The size of \p sig in Bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid. + * \return #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid + * signature in \p sig, but its length is less than \p siglen. + * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX + * error code on failure for any other reason. + */ +int mbedtls_ecdsa_read_signature(mbedtls_ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + const unsigned char *sig, size_t slen); + +/** + * \brief This function reads and verifies an ECDSA signature, + * in a restartable way. + * + * \see \c mbedtls_ecdsa_read_signature() + * + * \note This function is like \c mbedtls_ecdsa_read_signature() + * but it can return early and restart according to the limit + * set with \c mbedtls_ecp_set_max_ops() to reduce blocking. + * + * \param ctx The ECDSA context to use. This must be initialized + * and have a group and public key bound to it. + * \param hash The message hash that was signed. This must be a readable + * buffer of length \p hlen Bytes. + * \param hlen The size of the hash \p hash. + * \param sig The signature to read and verify. This must be a readable + * buffer of length \p slen Bytes. + * \param slen The size of \p sig in Bytes. + * \param rs_ctx The restart context to use. This may be \c NULL to disable + * restarting. If it is not \c NULL, it must point to an + * initialized restart context. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid. + * \return #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid + * signature in \p sig, but its length is less than \p siglen. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + * \return Another \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX + * error code on failure for any other reason. + */ +int mbedtls_ecdsa_read_signature_restartable(mbedtls_ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + const unsigned char *sig, size_t slen, + mbedtls_ecdsa_restart_ctx *rs_ctx); + +/** + * \brief This function generates an ECDSA keypair on the given curve. + * + * \see ecp.h + * + * \param ctx The ECDSA context to store the keypair in. + * This must be initialized. + * \param gid The elliptic curve to use. One of the various + * \c MBEDTLS_ECP_DP_XXX macros depending on configuration. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context argument. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX code on failure. + */ +int mbedtls_ecdsa_genkey(mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); + +/** + * \brief This function sets up an ECDSA context from an EC key pair. + * + * \see ecp.h + * + * \param ctx The ECDSA context to setup. This must be initialized. + * \param key The EC key to use. This must be initialized and hold + * a private-public key pair or a public key. In the former + * case, the ECDSA context may be used for signature creation + * and verification after this call. In the latter case, it + * may be used for signature verification. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX code on failure. + */ +int mbedtls_ecdsa_from_keypair(mbedtls_ecdsa_context *ctx, + const mbedtls_ecp_keypair *key); + +/** + * \brief This function initializes an ECDSA context. + * + * \param ctx The ECDSA context to initialize. + * This must not be \c NULL. + */ +void mbedtls_ecdsa_init(mbedtls_ecdsa_context *ctx); + +/** + * \brief This function frees an ECDSA context. + * + * \param ctx The ECDSA context to free. This may be \c NULL, + * in which case this function does nothing. If it + * is not \c NULL, it must be initialized. + */ +void mbedtls_ecdsa_free(mbedtls_ecdsa_context *ctx); + +#if defined(MBEDTLS_ECP_RESTARTABLE) +/** + * \brief Initialize a restart context. + * + * \param ctx The restart context to initialize. + * This must not be \c NULL. + */ +void mbedtls_ecdsa_restart_init(mbedtls_ecdsa_restart_ctx *ctx); + +/** + * \brief Free the components of a restart context. + * + * \param ctx The restart context to free. This may be \c NULL, + * in which case this function does nothing. If it + * is not \c NULL, it must be initialized. + */ +void mbedtls_ecdsa_restart_free(mbedtls_ecdsa_restart_ctx *ctx); +#endif /* MBEDTLS_ECP_RESTARTABLE */ + +#ifdef __cplusplus +} +#endif + +#endif /* ecdsa.h */ diff --git a/ql-kernel/threadx/quec_mbedtls/x509.c b/ql-kernel/threadx/quec_mbedtls/x509.c index 80af12d..bb35ed0 100644 --- a/ql-kernel/threadx/quec_mbedtls/x509.c +++ b/ql-kernel/threadx/quec_mbedtls/x509.c @@ -959,14 +959,16 @@ int mbedtls_x509_key_size_helper(char *buf, size_t buf_size, const char *name) * Set the time structure to the current time. * Return 0 on success, non-zero on failure. */ -#ifdef QUECTEL_MBEDTLS_SUPPORT +#if defined(QUECTEL_MBEDTLS_SUPPORT) && !defined(TALKINGQ_TLS_USE_RTC_TIME) #include "utlTime.h" #include "saremo_RTC.h" extern void GetCurrentCompTime(TIME *con_time); #endif/*QUECTEL_MBEDTLS_SUPPORT*/ static int x509_get_current_time(mbedtls_x509_time *now) { -#ifdef QUECTEL_MBEDTLS_SUPPORT +/* OpenCPU's GetCurrentCompTime is an empty shim. The shared TLS profile uses + * mbedtls_time (SDK RTC) and UTC conversion below instead. */ +#if defined(QUECTEL_MBEDTLS_SUPPORT) && !defined(TALKINGQ_TLS_USE_RTC_TIME) TIME end_time = {0}; GetCurrentCompTime(&end_time); now->year = end_time.year; diff --git a/tools/check_mbedtls_abi.py b/tools/check_mbedtls_abi.py new file mode 100644 index 0000000..b27c605 --- /dev/null +++ b/tools/check_mbedtls_abi.py @@ -0,0 +1,61 @@ +"""Check actual ARMCC kernel / GCC APP TLS layouts and enabled features.""" +import json +import os +from pathlib import Path +import struct +import subprocess + +root = Path(__file__).resolve().parents[1] +output = root / 'artifacts/wss/new-board' +output.mkdir(parents=True, exist_ok=True) +toolchain = root / 'ql-cross-tool/win32/owtoolchain' +gcc = toolchain / 'gcc-arm-none-eabi/bin/arm-none-eabi-gcc.exe' +objcopy = gcc.with_name('arm-none-eabi-objcopy.exe') +armcc = toolchain / 'ARM_Compiler_5/bin/armcc.exe' +types = ['ssl_context', 'ssl_config', 'net_context', 'x509_crt', 'pk_context', + 'entropy_context', 'ctr_drbg_context', 'ecp_group', 'ecp_point', 'mpi', + 'ssl_handshake_params', 'ecdh_context'] +fields = {'ssl_context': ['conf', 'state', 'in_buf', 'out_buf', 'session', 'handshake', 'hostname'], + 'ssl_config': ['ca_chain', 'cert_profile', 'f_rng', 'p_rng', 'curve_list'], + 'net_context': ['fd', 'cid'], 'x509_crt': ['pk', 'sig', 'next'], + 'ssl_handshake_params': ['ecdh_ctx'], 'ecdh_context': ['grp_id']} +labels = ['sizeof(mbedtls_' + t + ')' for t in types] +labels += ['offsetof(mbedtls_' + t + ', ' + f + ')' for t, fs in fields.items() for f in fs] +source = output / 'tls_layout.c' +source.write_text('#include \n#include "mbedtls/ssl_internal.h"\n' + '#include "mbedtls/net_sockets.h"\n#include "mbedtls/entropy.h"\n' + '#include "mbedtls/ctr_drbg.h"\n' + 'const unsigned int talkingq_tls_layout[] = {\n' + ',\n'.join(labels) + '\n};\n') +env = os.environ.copy() +env['ARMLMD_LICENSE_FILE'] = str(toolchain / 'license.dat') +layouts, macros = {}, {} +for target in ['kernel', 'app']: + include = root / ('ql-kernel' if target == 'kernel' else 'ql-application') / 'threadx/common/include' + obj = output / (target + '-tls-layout.o') + flags = ['-I' + str(include), '-DQUECTEL_OPEN_CPU'] + if target == 'kernel': + command = [str(armcc), '--cpu', 'Cortex-R5F', '--fpu=softvfp+vfpv3_d16', + '--gnu', '--thumb', '-c', str(source), '-o', str(obj)] + flags + section = '.constdata' + else: + command = [str(gcc), '-mcpu=cortex-r5', '-mthumb', '-mfloat-abi=softfp', '-mfpu=vfpv3-d16', + '-c', str(source), '-o', str(obj)] + flags + section = '.rodata' + subprocess.run(command, env=env, check=True) + binary = obj.with_suffix('.bin') + subprocess.run([str(objcopy), '-O', 'binary', '-j', section, str(obj), str(binary)], check=True) + data = binary.read_bytes() + assert len(data) == len(labels) * 4, (target, len(data)) + layouts[target] = dict(zip(labels, struct.unpack('<' + 'I' * len(labels), data))) + defines = subprocess.check_output([str(gcc), '-E', '-dM', '-x', 'c', '-include', 'mbedtls/config.h', + 'NUL'] + flags, text=True) + macros[target] = sorted(line for line in defines.splitlines() if line.startswith('#define MBEDTLS_') + or line.startswith('#define QUECTEL_MBEDTLS_')) +assert layouts['kernel'] == layouts['app'], json.dumps(layouts, indent=2) +assert macros['kernel'] == macros['app'], json.dumps({k: sorted(set(macros[k]) - set(macros['app' if k == 'kernel' else 'kernel'])) for k in macros}) +for feature in ['ECDSA_C', 'ECP_NIST_OPTIM', 'KEY_EXCHANGE_ECDHE_ECDSA_ENABLED', 'GCM_C', 'HAVE_TIME_DATE', 'PLATFORM_TIME_ALT']: + assert any(line.startswith('#define MBEDTLS_' + feature + ' ') for line in macros['kernel']) +report = {'result': 'PASS', 'layout': layouts['kernel'], 'features': macros['kernel']} +(output / 'tls-abi.json').write_text(json.dumps(report, indent=2)) +print('PASS: ARMCC kernel / GCC APP TLS sizes, field offsets and feature macros agree') +print(json.dumps(layouts['kernel'], indent=2)) diff --git a/tools/probe_talkingq_wss.ps1 b/tools/probe_talkingq_wss.ps1 new file mode 100644 index 0000000..59e5237 --- /dev/null +++ b/tools/probe_talkingq_wss.ps1 @@ -0,0 +1,59 @@ +param([string]$OutputDir = "$PSScriptRoot/../artifacts/wss", [ValidateSet(443, 8080)][int]$ServerPort = 443) +$ErrorActionPreference = 'Stop' +$serverHost = 'banban.api.talkingq.com' +New-Item -ItemType Directory -Force -Path $OutputDir | Out-Null +$OutputDir = (Resolve-Path -LiteralPath $OutputDir).Path +$tcp = New-Object System.Net.Sockets.TcpClient +$tls = $null +try { + $pending = $tcp.BeginConnect($serverHost, $serverPort, $null, $null) + if (-not $pending.AsyncWaitHandle.WaitOne(15000)) { throw 'TCP connect timeout' } + $tcp.EndConnect($pending) + $tcp.ReceiveTimeout = 15000 + $tcp.SendTimeout = 15000 + # Default SslStream validation checks the trusted chain and server hostname. + $tls = New-Object System.Net.Security.SslStream($tcp.GetStream(), $false) + $tls.ReadTimeout = 15000 + $tls.WriteTimeout = 15000 + $tls.AuthenticateAsClient($serverHost, $null, [System.Security.Authentication.SslProtocols]::Tls12, $false) + $leaf = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($tls.RemoteCertificate) + $chain = New-Object System.Security.Cryptography.X509Certificates.X509Chain + $chain.ChainPolicy.RevocationMode = [System.Security.Cryptography.X509Certificates.X509RevocationMode]::NoCheck + if (-not $chain.Build($leaf)) { throw 'Trusted certificate chain could not be built' } + $certificates = @() + for ($i = 0; $i -lt $chain.ChainElements.Count; $i++) { + $cert = $chain.ChainElements[$i].Certificate + $pem = "-----BEGIN CERTIFICATE-----`n" + [Convert]::ToBase64String($cert.RawData, [Base64FormattingOptions]::InsertLineBreaks).Replace("`r`n", "`n") + "`n-----END CERTIFICATE-----`n" + [IO.File]::WriteAllText((Join-Path $OutputDir "chain-$i.pem"), $pem, [Text.Encoding]::ASCII) + $certificates += [ordered]@{subject=$cert.Subject; issuer=$cert.Issuer; not_before=$cert.NotBefore.ToUniversalTime().ToString('o'); not_after=$cert.NotAfter.ToUniversalTime().ToString('o'); thumbprint=$cert.Thumbprint} + if ($i -eq $chain.ChainElements.Count - 1) { + if ($cert.Subject -ne $cert.Issuer) { throw 'Chain did not terminate at a root CA' } + [IO.File]::WriteAllText((Join-Path $OutputDir 'root-ca.pem'), $pem, [Text.Encoding]::ASCII) + } + } + $nonce = New-Object byte[] 16 + $rng = [Security.Cryptography.RandomNumberGenerator]::Create() + $rng.GetBytes($nonce) + $rng.Dispose() + $key = [Convert]::ToBase64String($nonce) + $request = "GET /ws HTTP/1.1`r`nHost: ${serverHost}:${serverPort}`r`nUpgrade: websocket`r`nConnection: Upgrade`r`nSec-WebSocket-Key: $key`r`nSec-WebSocket-Version: 13`r`n`r`n" + $bytes = [Text.Encoding]::ASCII.GetBytes($request) + $tls.Write($bytes, 0, $bytes.Length) + $response = '' + while (-not $response.EndsWith("`r`n`r`n") -and $response.Length -lt 16384) { + $next = $tls.ReadByte() + if ($next -lt 0) { break } + $response += [char]$next + } + $sha1 = [Security.Cryptography.SHA1]::Create() + $expected = [Convert]::ToBase64String($sha1.ComputeHash([Text.Encoding]::ASCII.GetBytes($key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'))) + $sha1.Dispose() + $accepted = $response -match '^HTTP/1\.1 101 ' -and $response -match ('(?im)^Sec-WebSocket-Accept:\s*' + [regex]::Escape($expected) + '\s*$') + $report = [ordered]@{url="wss://${serverHost}:${serverPort}/ws"; tested_utc=[DateTime]::UtcNow.ToString('o'); tls_protocol=$tls.SslProtocol.ToString(); cipher=$tls.CipherAlgorithm.ToString(); cipher_bits=$tls.CipherStrength; certificate_validation='System trust and hostname validation passed'; certificates=$certificates; websocket_upgrade=$accepted; response_headers=$response; device_auth_sent=$false} + $report | ConvertTo-Json -Depth 6 | Set-Content -Encoding UTF8 -LiteralPath (Join-Path $OutputDir 'server-probe.json') + $report | ConvertTo-Json -Depth 6 + if (-not $accepted) { throw 'WebSocket upgrade did not return a valid HTTP 101 response' } +} finally { + if ($tls) { $tls.Dispose() } + $tcp.Close() +} diff --git a/tools/probe_wss_groups.py b/tools/probe_wss_groups.py new file mode 100644 index 0000000..e6ca96c --- /dev/null +++ b/tools/probe_wss_groups.py @@ -0,0 +1,40 @@ +"""Probe TLS 1.2 full-handshake group negotiation with the firmware root CA.""" +import json +from pathlib import Path +import re +import subprocess + +root = Path(__file__).resolve().parents[1] +source = (root / 'ql-application/threadx/interface/custom_app/talkingq_root_ca.c').read_text() +pem = ''.join(json.loads('"' + value + '"') for value in re.findall(r'"(.*?)"', source) + if 'CERTIFICATE' in value or value.endswith(r'\n')) +output = root / 'artifacts/wss/full-handshake' +output.mkdir(parents=True, exist_ok=True) +ca = output / 'compiled-root.pem' +ca.write_text(pem) +openssl = Path('C:/Program Files/Git/usr/bin/openssl.exe') +groups = { + 'sdk_order': 'P-521:brainpoolP512r1:P-384:brainpoolP384r1:P-256:brainpoolP256r1:P-224:secp224k1:P-192:secp192k1:X25519:X448', + 'x25519_first': 'X25519:P-256:P-384:P-521', + 'p256_first': 'P-256:X25519:P-384:P-521', +} +firmware = (root / 'ql-application/threadx/interface/custom_app/lib/librws/src/rws_socketpriv.c').read_bytes().decode('latin1') +array = re.search(r'rws_tls_preferred_curves\[\]\s*=\s*\{(.*?)\}', firmware, re.S).group(1) +names = {'CURVE25519': 'X25519', 'CURVE448': 'X448', + 'SECP256R1': 'P-256', 'SECP384R1': 'P-384', 'SECP521R1': 'P-521', + 'SECP224R1': 'P-224', 'SECP192R1': 'P-192', + 'SECP224K1': 'secp224k1', 'SECP192K1': 'secp192k1', + 'BP512R1': 'brainpoolP512r1', 'BP384R1': 'brainpoolP384r1', 'BP256R1': 'brainpoolP256r1'} +groups['firmware_policy'] = ':'.join(names[name] for name in re.findall(r'MBEDTLS_ECP_DP_(\w+)', array) if name != 'NONE') +report = {} +for name, group_list in groups.items(): + result = subprocess.run([str(openssl), 's_client', '-connect', 'banban.api.talkingq.com:443', + '-servername', 'banban.api.talkingq.com', '-verify_hostname', 'banban.api.talkingq.com', + '-verify_return_error', '-CAfile', str(ca), '-no-CApath', '-no-CAstore', + '-tls1_2', '-no_ticket', '-groups', group_list, '-brief'], + input='', text=True, capture_output=True, timeout=20) + text = result.stdout + result.stderr + report[name] = {'groups': group_list, 'returncode': result.returncode, 'output': text} + print(name + ':\n' + text, flush=True) + assert result.returncode == 0 and 'Verification: OK' in text, name +(output / 'group-probe.json').write_text(json.dumps(report, indent=2)) diff --git a/tools/probe_wss_root.py b/tools/probe_wss_root.py new file mode 100644 index 0000000..c57ef97 --- /dev/null +++ b/tools/probe_wss_root.py @@ -0,0 +1,36 @@ +import hashlib +import json +import re +import socket +import ssl +from pathlib import Path + +root = Path(__file__).resolve().parents[1] +source = (root / 'ql-application/threadx/interface/custom_app/talkingq_root_ca.c').read_text() +pem = ''.join(json.loads('"' + value + '"') for value in re.findall(r'"(.*?)"', source) if 'CERTIFICATE' in value or value.endswith(r'\n')) +context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) +context.load_verify_locations(cadata=pem) +context.minimum_version = ssl.TLSVersion.TLSv1_2 +context.maximum_version = ssl.TLSVersion.TLSv1_2 +server = 'banban.api.talkingq.com' +report = {'root_sha256': hashlib.sha256(ssl.PEM_cert_to_DER_cert(pem)).hexdigest(), 'trust': 'only the compiled root CA; no OS trust or intermediate download'} +with socket.create_connection((server, 443), timeout=15) as tcp: + with context.wrap_socket(tcp, server_hostname=server) as tls: + report['tls'] = tls.version() + report['cipher'] = tls.cipher() + report['root_only_validation'] = 'PASS' +try: + with socket.create_connection((server, 443), timeout=15) as tcp: + with context.wrap_socket(tcp, server_hostname='wrong.invalid'): + raise AssertionError('wrong hostname accepted') +except ssl.SSLCertVerificationError: + report['wrong_hostname_rejected'] = True +empty = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) +try: + with socket.create_connection((server, 443), timeout=15) as tcp: + with empty.wrap_socket(tcp, server_hostname=server): + raise AssertionError('untrusted CA accepted') +except ssl.SSLCertVerificationError: + report['untrusted_ca_rejected'] = True +(root / 'artifacts/wss/root-only-probe.json').write_text(json.dumps(report, indent=2)) +print(json.dumps(report, indent=2)) diff --git a/tools/test_mbedtls_cert.c b/tools/test_mbedtls_cert.c new file mode 100644 index 0000000..58e9ab0 --- /dev/null +++ b/tools/test_mbedtls_cert.c @@ -0,0 +1,169 @@ +#include +#include +#include +#include +#include +#include +#include "mbedtls/x509_crt.h" +#include "mbedtls/platform_time.h" +#include "mbedtls/gcm.h" +#include "mbedtls/ssl_ciphersuites.h" +#include "mbedtls/ecdh.h" +#include "mbedtls/ctr_drbg.h" +#include "talkingq_wss.h" + +typedef union { size_t bytes; long double align; void *ptr; } alloc_header; +static size_t live_bytes, peak_bytes; +void *mbedtls_calloc(size_t n, size_t size) { + alloc_header *h; + size_t bytes; + if (size && n > (SIZE_MAX - sizeof(*h)) / size) return NULL; + bytes = n * size; + h = (alloc_header *)calloc(1, sizeof(*h) + bytes); + if (!h) return NULL; + h->bytes = bytes; live_bytes += bytes; + if (live_bytes > peak_bytes) peak_bytes = live_bytes; + return h + 1; +} +void mbedtls_free(void *p) { + if (p) { alloc_header *h = (alloc_header *)p - 1; live_bytes -= h->bytes; free(h); } +} +static time_t test_time; +static time_t read_test_time(time_t *p) { if (p) *p = test_time; return test_time; } +mbedtls_time_t (*mbedtls_time)(mbedtls_time_t *) = read_test_time; +void CPUartLogPrintf(const char *format, ...) { (void)format; } +int mbedtls_snprintf(char *buffer, size_t size, const char *format, ...) +{ + int result; + va_list args; + va_start(args, format); + result = vsnprintf(buffer, size, format, args); + va_end(args); + return result; +} + +/* Deterministic entropy is confined to this host benchmark, never firmware. */ +static int test_entropy(void *ctx, unsigned char *out, size_t n) +{ + size_t i; unsigned int *counter = (unsigned int *)ctx; + for (i = 0; i < n; ++i) out[i] = (unsigned char)(++*counter); + return 0; +} + +static void benchmark_ecdh(mbedtls_ecp_group_id id, const char *name) +{ + mbedtls_ecp_group peer, client; + mbedtls_ecp_point peer_q, client_q; + mbedtls_mpi peer_d, client_d, secret, expected; + mbedtls_ctr_drbg_context rng; + unsigned int counter = 0; + clock_t elapsed = 0, started; + size_t base; + int i; + mbedtls_ctr_drbg_init(&rng); + assert(mbedtls_ctr_drbg_seed(&rng, test_entropy, &counter, NULL, 0) == 0); + mbedtls_ecp_group_init(&peer); mbedtls_ecp_point_init(&peer_q); mbedtls_mpi_init(&peer_d); + assert(mbedtls_ecp_group_load(&peer, id) == 0); + assert(mbedtls_ecdh_gen_public(&peer, &peer_d, &peer_q, mbedtls_ctr_drbg_random, &rng) == 0); + base = live_bytes; peak_bytes = base; + for (i = 0; i < 20; ++i) { + mbedtls_ecp_group_init(&client); mbedtls_ecp_point_init(&client_q); + mbedtls_mpi_init(&client_d); mbedtls_mpi_init(&secret); mbedtls_mpi_init(&expected); + assert(mbedtls_ecp_group_load(&client, id) == 0); + started = clock(); + assert(mbedtls_ecdh_gen_public(&client, &client_d, &client_q, mbedtls_ctr_drbg_random, &rng) == 0); + assert(mbedtls_ecdh_compute_shared(&client, &secret, &peer_q, &client_d, mbedtls_ctr_drbg_random, &rng) == 0); + elapsed += clock() - started; + assert(mbedtls_ecdh_compute_shared(&peer, &expected, &client_q, &peer_d, mbedtls_ctr_drbg_random, &rng) == 0); + assert(mbedtls_mpi_cmp_mpi(&secret, &expected) == 0); + mbedtls_mpi_free(&expected); mbedtls_mpi_free(&secret); mbedtls_mpi_free(&client_d); + mbedtls_ecp_point_free(&client_q); mbedtls_ecp_group_free(&client); + assert(live_bytes == base); + } + printf("Host fresh ECDH %s: %.2f ms, extra peak heap %zu bytes (20 runs, includes peer check heap)\n", + name, 1000.0 * elapsed / CLOCKS_PER_SEC / 20, peak_bytes - base); + mbedtls_ecp_group_free(&peer); mbedtls_ecp_point_free(&peer_q); mbedtls_mpi_free(&peer_d); + mbedtls_ctr_drbg_free(&rng); +} + +int main(int argc, char **argv) +{ + mbedtls_x509_crt root, chain; + mbedtls_gcm_context gcm; + uint32_t flags; + int ret, i; + char path[1024]; + char pem[16384]; + FILE *file; + size_t length; + clock_t verify_started; + mbedtls_ecp_group group; + unsigned char key[16] = {0}, iv[12] = {0}, plain[16] = {0}, cipher[16], tag[16]; + const unsigned char expected_cipher[16] = {0x03,0x88,0xda,0xce,0x60,0xb6,0xa3,0x92,0xf3,0x28,0xc2,0xb9,0x71,0xb2,0xfe,0x78}; + const unsigned char expected_tag[16] = {0xab,0x6e,0x47,0xd4,0x2c,0xec,0x13,0xbd,0xf5,0x3a,0x67,0xb2,0x12,0x57,0xbd,0xdf}; + assert(argc == 2); + test_time = time(NULL); + mbedtls_x509_crt_init(&root); + mbedtls_x509_crt_init(&chain); + ret = mbedtls_x509_crt_parse(&root, (const unsigned char *)talkingq_root_ca, talkingq_root_ca_size); + printf("SDK root CA parse: %d (previous device failure: -9774)\n", ret); + assert(ret == 0); + for (i = 0; i < 3; ++i) { + snprintf(path, sizeof(path), "%s/chain-%d.pem", argv[1], i); + file = fopen(path, "rb"); + assert(file != NULL); + length = fread(pem, 1, sizeof(pem)-1, file); + assert(feof(file) && !ferror(file)); + fclose(file); + pem[length] = 0; + ret = mbedtls_x509_crt_parse(&chain, (const unsigned char *)pem, length + 1); + assert(ret == 0); + } + ret = mbedtls_x509_crt_verify(&chain, &root, NULL, "banban.api.talkingq.com", &flags, NULL, NULL, 0); + printf("SDK server chain + hostname verify: %d, flags=0x%08x\n", ret, (unsigned int)flags); + assert(ret == 0 && flags == 0); + verify_started = clock(); + peak_bytes = live_bytes; + for (i = 0; i < 20; ++i) { + ret = mbedtls_x509_crt_verify(&chain, &root, NULL, "banban.api.talkingq.com", &flags, NULL, NULL, 0); + assert(ret == 0 && flags == 0); + } + printf("Host certificate chain verify average: %.2f ms (20 runs)\n", + 1000.0 * (clock() - verify_started) / CLOCKS_PER_SEC / 20); + printf("Host certificate verify peak heap: %zu bytes, ECP window: %d\n", peak_bytes, MBEDTLS_ECP_WINDOW_SIZE); + mbedtls_ecp_group_init(&group); + assert(mbedtls_ecp_group_load(&group, MBEDTLS_ECP_DP_SECP384R1) == 0); +#ifdef MBEDTLS_ECP_NIST_OPTIM + assert(group.modp != NULL); +#else + assert(group.modp == NULL); +#endif + mbedtls_ecp_group_free(&group); + ret = mbedtls_x509_crt_verify(&chain, &root, NULL, "wrong.invalid", &flags, NULL, NULL, 0); + assert(ret != 0 && (flags & MBEDTLS_X509_BADCERT_CN_MISMATCH)); + ret = mbedtls_x509_crt_verify(&chain, NULL, NULL, "banban.api.talkingq.com", &flags, NULL, NULL, 0); + assert(ret != 0 && (flags & MBEDTLS_X509_BADCERT_NOT_TRUSTED)); + test_time = 1900000000; /* 2030: this server certificate is expired. */ + ret = mbedtls_x509_crt_verify(&chain, &root, NULL, "banban.api.talkingq.com", &flags, NULL, NULL, 0); + assert(ret != 0 && (flags & MBEDTLS_X509_BADCERT_EXPIRED)); + test_time = 1700000000; /* 2023: this server certificate is not yet valid. */ + ret = mbedtls_x509_crt_verify(&chain, &root, NULL, "banban.api.talkingq.com", &flags, NULL, NULL, 0); + assert(ret != 0 && (flags & MBEDTLS_X509_BADCERT_FUTURE)); + assert(mbedtls_ssl_ciphersuite_from_id(MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) != NULL); + mbedtls_gcm_init(&gcm); + assert(mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES, key, 128) == 0); + assert(mbedtls_gcm_crypt_and_tag(&gcm, MBEDTLS_GCM_ENCRYPT, 16, iv, 12, NULL, 0, + plain, cipher, 16, tag) == 0); + assert(!memcmp(cipher, expected_cipher, 16) && !memcmp(tag, expected_tag, 16)); + mbedtls_gcm_free(&gcm); + mbedtls_x509_crt_free(&chain); + mbedtls_x509_crt_free(&root); + assert(live_bytes == 0); + benchmark_ecdh(MBEDTLS_ECP_DP_CURVE25519, "X25519"); + benchmark_ecdh(MBEDTLS_ECP_DP_SECP256R1, "P-256"); + benchmark_ecdh(MBEDTLS_ECP_DP_SECP384R1, "P-384"); + benchmark_ecdh(MBEDTLS_ECP_DP_SECP521R1, "P-521"); + assert(live_bytes == 0); + puts("PASS: SDK ECDSA certificate chain, hostname, trust, dates, TLS suite and AES-GCM vector"); + return 0; +} diff --git a/tools/test_mbedtls_cert.py b/tools/test_mbedtls_cert.py new file mode 100644 index 0000000..a388896 --- /dev/null +++ b/tools/test_mbedtls_cert.py @@ -0,0 +1,37 @@ +"""Build the SDK's real crypto/X.509 sources with MSVC and test the server chain. +Run from a Visual Studio developer shell. Chain PEMs come from the WSS probe. +""" +from pathlib import Path +import argparse +import subprocess + +root = Path(__file__).resolve().parents[1] +parser = argparse.ArgumentParser() +parser.add_argument('chain', nargs='?', default=str(root / 'artifacts/wss/retest-443')) +parser.add_argument('--compare-nist', action='store_true') +parser.add_argument('--compare-windows', action='store_true') +args = parser.parse_args() +output = root / 'artifacts/wss/new-board/host-cert' +output.mkdir(parents=True, exist_ok=True) +chain = Path(args.chain).resolve() +sources = '''asn1parse asn1write bignum base64 pem oid pk pkparse pk_wrap rsa rsa_internal +ecp ecp_curves ecdsa md md5 sha1 sha256 sha512 aes des gcm cipher cipher_wrap +chacha20 chachapoly poly1305 constant_time ctr_drbg x509 x509_crt platform_util +ecdh ssl_ciphersuites'''.split() +command = ['cl', '/nologo', '/O2', '/Gy', '/TC', '/D_CRT_SECURE_NO_WARNINGS', + '/DMBEDTLS_CONFIG_FILE="wss_tls_host_config.h"', + '/I' + str(root / 'tools'), '/I' + str(root / 'tools/wss_host_stubs'), + '/I' + str(root / 'ql-kernel/threadx/common/include'), + '/I' + str(root / 'ql-application/threadx/interface/custom_app/inc'), + str(root / 'tools/test_mbedtls_cert.c'), + str(root / 'ql-application/threadx/interface/custom_app/talkingq_root_ca.c')] +command += [str(root / ('ql-kernel/threadx/quec_mbedtls/' + name + '.c')) for name in sources] +variants = ['window4', 'window5', 'window6'] if args.compare_windows else (['baseline', 'nist'] if args.compare_nist else ['nist']) +for variant in variants: + exe = output / ('test_mbedtls_cert_' + variant + '.exe') + flags = ['/DWSS_TEST_DISABLE_NIST_OPTIM'] if variant == 'baseline' else [] + if variant.startswith('window'): + flags += ['/DWSS_TEST_ECP_WINDOW=' + variant[-1]] + subprocess.run(command + flags + ['/Fe' + str(exe), '/link', '/OPT:REF'], cwd=output, check=True) + print('Certificate test variant:', variant, flush=True) + subprocess.run([str(exe), str(chain)], check=True) diff --git a/tools/test_mqtt_diag.py b/tools/test_mqtt_diag.py new file mode 100644 index 0000000..cf2852f --- /dev/null +++ b/tools/test_mqtt_diag.py @@ -0,0 +1,107 @@ +"""Exercise actual MQTT diagnostic callbacks without a broker or credentials.""" +from pathlib import Path +import subprocess + +root = Path(__file__).resolve().parents[1] +output = root / 'artifacts/wss/new-board/mqtt-diag/tests' +output.mkdir(parents=True, exist_ok=True) +(output / 'MQTTClient.h').write_text(r''' +#ifndef TEST_MQTT_CLIENT_H +#define TEST_MQTT_CLIENT_H +typedef struct Network Network; +struct Network { + int (*mqttread)(Network *, unsigned char *, int, int); + int (*mqttwrite)(Network *, unsigned char *, int, int); +}; +typedef struct { Network *ipstack; unsigned int command_timeout_ms; int isconnected; } MQTTClient; +typedef struct { unsigned char MQTTVersion, cleansession; unsigned short keepAliveInterval; } MQTTPacket_connectData; +typedef struct { unsigned char rc, sessionPresent; } MQTTConnackData; +int MQTTConnectWithResults(MQTTClient *, MQTTPacket_connectData *, MQTTConnackData *); +unsigned int ql_rtos_get_systicks(void); +#endif +''') +(output / 'sockets.h').write_text('int ql_get_soc_errno(void);\n') +harness = r''' +#include +#include +#include +#include "mqtt_connect_diag.h" +static unsigned int ticks; +static int mode, offset, writes, reads; +unsigned int ql_rtos_get_systicks(void) { return ticks; } +int ql_get_soc_errno(void) { return 104; } +static int fake_write(Network *n, unsigned char *buf, int size, int timeout) { + (void)n; + assert(timeout == 30000 && size == 19); + assert(memcmp(buf, "PRIVATE_TEST_SECRET", 19) == 0); + ++writes; ticks += 2; + return mode == 2 ? -1 : size; +} +static int fake_read(Network *n, unsigned char *buf, int size, int timeout) { + unsigned char response[] = {0x20, 2, 0, 0}; + (void)n; + assert(timeout == 30000 && (size == 1 || size == 2)); + ++reads; ticks += 3; + if (mode == 3) return -1; + if (mode == 4) return 0; + if (mode == 1) response[3] = 5; + if (mode == 5) response[0] = 0x30; + if (mode == 7) { response[2] = 1; response[3] = 5; } + memcpy(buf, response + offset, size); offset += size; + return size; +} +int MQTTConnectWithResults(MQTTClient *client, MQTTPacket_connectData *options, MQTTConnackData *ack) { + unsigned char packet[] = "PRIVATE_TEST_SECRET"; + unsigned char response[4] = {0}; + int result; + assert(options->MQTTVersion == 3); + assert(ack->rc == 255); + if (mode == 6) return -1; + result = client->ipstack->mqttwrite(client->ipstack, packet, 19, 30000); + if (result != 19) { assert(result == -1); return -1; } + /* SDK reads fixed header, remaining length, then the two-byte body. */ + result = client->ipstack->mqttread(client->ipstack, response, 1, 30000); + if (mode == 3 || mode == 4) { assert(result == (mode == 3 ? -1 : 0)); return -1; } + assert(result == 1); + assert(client->ipstack->mqttread(client->ipstack, response + 1, 1, 30000) == 1); + assert(client->ipstack->mqttread(client->ipstack, response + 2, 2, 30000) == 2); + assert(response[1] == 2); + return mode == 0 ? 0 : (mode == 1 ? 5 : -1); +} +int main(void) { + Network network = {fake_read, fake_write}; + MQTTClient client = {&network, 30000, 0}; + MQTTPacket_connectData options = {3, 0, 60}; + for (mode = 0; mode < 8; ++mode) { + int expected = mode == 0 ? 0 : (mode == 1 ? 5 : -1); + ticks = mode == 0 ? 0xfffffffeU : 0; offset = writes = reads = 0; + printf("CASE %d\n", mode); + assert(talkingq_mqtt_connect_diagnosed(&client, &options) == expected); + assert(network.mqttread == fake_read && network.mqttwrite == fake_write); + assert(writes == (mode == 6 ? 0 : 1)); + if (mode == 6 || mode == 2) assert(reads == 0); + } + return 0; +} +''' +(output / 'test.c').write_text(harness) +include = root / 'ql-application/threadx/interface/custom_app/inc' +source = root / 'ql-application/threadx/interface/custom_app/mqtt_connect_diag.c' +subprocess.run(['cl', '/nologo', '/W4', '/WX', '/TC', '/I' + str(output), '/I' + str(include), + str(source), str(output / 'test.c'), '/Fe' + str(output / 'test.exe')], cwd=output, check=True) +result = subprocess.check_output([str(output / 'test.exe')], text=True) +assert 'PRIVATE_TEST_SECRET' not in result +cases = [part for part in result.split('CASE ')[1:]] +assert len(cases) == 8 +assert 'CONNACK code=0 reason=accepted' in cases[0] and 'elapsed_ms=55' in cases[0] +assert 'CONNACK code=5 reason=not_authorized' in cases[1] +assert 'write request=19 rc=-1' in cases[2] +assert 'read request=1 rc=-1' in cases[3] +assert 'read request=1 rc=0' in cases[4] +assert 'no valid initial CONNACK' in cases[5] +assert 'failed before transport write' in cases[6] +assert 'no valid initial CONNACK' in cases[7] +for case in cases[2:]: + assert '[MQTT-DIAG] CONNACK code=' not in case +(output / 'test-output.log').write_text(result) +print('PASS: transport arguments/return values, callback restoration, split CONNACK, rejection, invalid response, errors, no-I/O failure, tick wrap and credential redaction') diff --git a/tools/test_wss.c b/tools/test_wss.c new file mode 100644 index 0000000..2f68845 --- /dev/null +++ b/tools/test_wss.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include "talkingq_wss.h" +#include "rws_handshake.h" + +static const char accept[] = "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="; +static const char good[] = "HTTP/1.1 101 Switching Protocols\r\n" + "uPgRaDe: WebSocket\r\nConnection: keep-alive, Upgrade\r\n" + "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"; + +int main(void) +{ + char host[64], path[128], data[RWS_HANDSHAKE_MAX + 20]; + int port, status; + size_t i, header; + const char *bad[] = {"ws://example.com/ws", "https://example.com/ws", "wss:///ws", + "wss://user@example.com/ws", "wss://example.com:0/ws", "wss://example.com:65536/ws", + "wss://example.com:-1/ws", "wss://example.com:/ws", "wss://example.com:abc/ws", + "wss://example.com/ws#frag", "wss://example.com/ws\r\nInjected:yes", + "wss://example.com:99999999999999999999999/ws", "wss://example.com/bad path"}; + assert(!talkingq_parse_wss_url(TALKINGQ_WSS_URL, host, sizeof(host), &port, path, sizeof(path))); + assert(!strcmp(host, "banban.api.talkingq.com") && port == 443 && !strcmp(path, "/ws")); + assert(!talkingq_parse_wss_url("wss://example.com", host, sizeof(host), &port, path, sizeof(path))); + assert(port == 443 && !strcmp(path, "/ws")); + assert(!talkingq_parse_wss_url("wss://example.com:8080/ws?x=y", host, sizeof(host), &port, path, sizeof(path))); + assert(port == 8080 && !strcmp(path, "/ws?x=y")); + for (i = 0; i < sizeof(bad)/sizeof(bad[0]); ++i) + assert(talkingq_parse_wss_url(bad[i], host, sizeof(host), &port, path, sizeof(path)) == -1); + assert(talkingq_parse_wss_url(TALKINGQ_WSS_URL, host, 3, &port, path, sizeof(path)) == -1); + assert(talkingq_parse_wss_url(TALKINGQ_WSS_URL, host, sizeof(host), &port, path, 3) == -1); + assert(talkingq_is_legacy_ws_url("ws://101.35.224.118:8080")); + assert(talkingq_is_legacy_ws_url("ws://101.35.224.118:8080/ws")); + assert(!talkingq_is_legacy_ws_url(TALKINGQ_WSS_URL)); + assert(!talkingq_is_legacy_ws_url("ws://custom.example:8080/ws")); + /* Every possible TLS fragment boundary, with no NUL terminator available. */ + for (i = 0; i < sizeof(good)-1; ++i) { + memset(data, 'X', sizeof(data)); + memcpy(data, good, i); + assert(rws_check_handshake(data, i, accept, &header, &status) == 0); + } + memcpy(data, good, sizeof(good)-1); + ((unsigned char *)data)[sizeof(good)-1] = 0x81; data[sizeof(good)] = 0; + assert(rws_check_handshake(data, sizeof(good)+1, accept, &header, &status) == 1); + assert(status == 101 && header == sizeof(good)-1); + assert(rws_check_handshake(data, sizeof(good)-1, "wrong", &header, &status) == -1); + memcpy(data + 9, "404", 3); + assert(rws_check_handshake(data, sizeof(good)-1, accept, &header, &status) == -1 && status == 404); + strcpy(data, "HTTP/1.1 101 OK\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"); + assert(rws_check_handshake(data, strlen(data), accept, &header, &status) == -1); + memcpy(data, good, sizeof(good)); + strcpy(data + sizeof(good)-3, "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"); + assert(rws_check_handshake(data, strlen(data), accept, &header, &status) == -1); + memset(data, 'X', sizeof(data)); + assert(rws_check_handshake(data, sizeof(data), accept, &header, &status) == -1); + puts("PASS: WSS URL policy, legacy migration, fragmented upgrade, status, accept, headers and limits"); + return 0; +} diff --git a/tools/test_wss.cmd b/tools/test_wss.cmd new file mode 100644 index 0000000..8726e17 --- /dev/null +++ b/tools/test_wss.cmd @@ -0,0 +1,17 @@ +@echo off +setlocal +cd /d "%~dp0.." +if not exist artifacts\wss mkdir artifacts\wss +where cl >nul 2>nul +if errorlevel 1 call "C:\Program Files (x86)\Microsoft Visual Studio\18\BuildTools\VC\Auxiliary\Build\vcvars64.bat" >nul +if errorlevel 1 exit /b 1 +cl /nologo /W4 /WX /D_CRT_SECURE_NO_WARNINGS /TC /Iql-application\threadx\interface\custom_app\inc /Iql-application\threadx\interface\custom_app\lib\librws\inc tools\test_wss.c ql-application\threadx\interface\custom_app\talkingq_wss.c ql-application\threadx\interface\custom_app\lib\librws\src\rws_handshake.c /Foartifacts\wss\ /Feartifacts\wss\test_wss.exe +if errorlevel 1 exit /b 1 +artifacts\wss\test_wss.exe +if errorlevel 1 exit /b 1 +ql-cross-tool\win32\owtoolchain\Python\python.exe tools\test_wss_io.py +if errorlevel 1 exit /b 1 +ql-cross-tool\win32\owtoolchain\Python\python.exe tools\test_wss_receive.py +if errorlevel 1 exit /b 1 +ql-cross-tool\win32\owtoolchain\Python\python.exe tools\test_wss_handshake.py +exit /b %errorlevel% diff --git a/tools/test_wss_handshake.py b/tools/test_wss_handshake.py new file mode 100644 index 0000000..0affc45 --- /dev/null +++ b/tools/test_wss_handshake.py @@ -0,0 +1,75 @@ +"""Test the actual timed handshake loop with scripted SDK steps and 5 ms ticks.""" +from pathlib import Path +import subprocess + +root = Path(__file__).resolve().parents[1] +source = (root / 'ql-application/threadx/interface/custom_app/lib/librws/src/rws_socketpriv.c').read_bytes().decode('latin1') +body = source[source.index('static const char *rws_tls_phase_name('):].split('int rws_ssl_conn(', 1)[0] +harness = r''' +#include +#include +#include +#include +#include "mbedtls/ssl_internal.h" +typedef struct { int ret, next_state; unsigned int duration; } step; +static step steps[16]; +static int count, calls, sleeps; +static unsigned int ticks; +static void test_log(const char *fmt, ...) { (void)fmt; } +#define LOG_I test_log +static unsigned int ql_rtos_get_systicks(void) { return ticks; } +static void rws_thread_sleep(unsigned int ms) { ticks += ms / 5; ++sleeps; } +int mbedtls_ssl_handshake_step(mbedtls_ssl_context *ctx) { + step s; + assert(ctx->state != MBEDTLS_SSL_HANDSHAKE_OVER); + if (calls >= count) { ++calls; return MBEDTLS_ERR_SSL_WANT_READ; } + s = steps[calls++]; ticks += s.duration; ctx->state = s.next_state; return s.ret; +} +''' +harness += body +harness += r''' +static void reset(mbedtls_ssl_context *ctx) { + memset(ctx, 0, sizeof(*ctx)); + ctx->state = MBEDTLS_SSL_CLIENT_HELLO; + count = calls = sleeps = 0; ticks = 0; memset(steps, 0, sizeof(steps)); +} +int main(void) { + mbedtls_ssl_context ctx; + mbedtls_ssl_handshake_params handshake = {0}; + reset(&ctx); + steps[0] = (step){0, MBEDTLS_SSL_SERVER_HELLO, 1}; + steps[1] = (step){MBEDTLS_ERR_SSL_WANT_READ, MBEDTLS_SSL_SERVER_HELLO, 0}; + steps[2] = (step){0, MBEDTLS_SSL_SERVER_CERTIFICATE, 2}; + steps[3] = (step){0, MBEDTLS_SSL_CLIENT_KEY_EXCHANGE, 10}; + steps[4] = (step){MBEDTLS_ERR_SSL_WANT_WRITE, MBEDTLS_SSL_CLIENT_KEY_EXCHANGE, 1}; + steps[5] = (step){0, MBEDTLS_SSL_SERVER_FINISHED, 5}; + steps[6] = (step){0, MBEDTLS_SSL_HANDSHAKE_OVER, 1}; count = 7; + assert(rws_tls_handshake_timed(&ctx) == 0 && calls == 7 && sleeps == 2 && ticks == 24); + reset(&ctx); ctx.handshake = &handshake; ctx.state = MBEDTLS_SSL_SERVER_KEY_EXCHANGE; + handshake.ecdh_ctx.grp_id = MBEDTLS_ECP_DP_CURVE25519; + steps[0] = (step){0, MBEDTLS_SSL_CLIENT_KEY_EXCHANGE, 1}; + steps[1] = (step){0, MBEDTLS_SSL_HANDSHAKE_OVER, 1}; count = 2; + assert(rws_tls_handshake_timed(&ctx) == 0 && calls == 2 && sleeps == 0); + reset(&ctx); steps[0] = (step){-99, MBEDTLS_SSL_SERVER_CERTIFICATE, 1}; count = 1; + assert(rws_tls_handshake_timed(&ctx) == -99 && calls == 1 && sleeps == 0); + reset(&ctx); + assert(rws_tls_handshake_timed(&ctx) == MBEDTLS_ERR_SSL_TIMEOUT && ticks == 4000 && calls < 2100); + reset(&ctx); ticks = (unsigned int)-1000; + assert(rws_tls_handshake_timed(&ctx) == MBEDTLS_ERR_SSL_TIMEOUT && calls < 2100); + reset(&ctx); steps[0] = (step){0, MBEDTLS_SSL_SERVER_CERTIFICATE, 4001}; count = 1; + assert(rws_tls_handshake_timed(&ctx) == MBEDTLS_ERR_SSL_TIMEOUT && calls == 1 && sleeps == 0); + reset(&ctx); ctx.state = MBEDTLS_SSL_HANDSHAKE_OVER; + assert(rws_tls_handshake_timed(&ctx) == 0 && calls == 0); + puts("PASS: timed SDK handshake loop: progress, WANT_READ/WRITE, no progress sleeps, fatal, deadline, tick wrap, complete state"); + return 0; +} +''' +output = root / 'artifacts/wss' +output.mkdir(parents=True, exist_ok=True) +cfile = output / 'test_wss_handshake.c' +cfile.write_text(harness, encoding='utf-8') +exe = output / 'test_wss_handshake.exe' +subprocess.run(['cl', '/nologo', '/W4', '/WX', '/TC', str(cfile), + '/I' + str(root / 'ql-application/threadx/common/include'), + '/Fo' + str(output / 'test_wss_handshake.obj'), '/Fe' + str(exe)], check=True) +subprocess.run([str(exe)], check=True) diff --git a/tools/test_wss_io.py b/tools/test_wss_io.py new file mode 100644 index 0000000..1d2f3a1 --- /dev/null +++ b/tools/test_wss_io.py @@ -0,0 +1,80 @@ +"""Compile actual SDK-independent function bodies with scripted TLS/RTOS stubs.""" +from pathlib import Path +import subprocess + +root = Path(__file__).resolve().parents[1] +lib = root / 'ql-application/threadx/interface/custom_app/lib/librws/src' +private = (lib / 'rws_socketpriv.c').read_bytes().decode('latin1') +public = (lib / 'rws_socketpub.c').read_bytes().decode('latin1') +send = private[private.index('static int rws_tls_send_all('):].split('#endif', 1)[0] +cancel = public[public.index('void rws_socket_disconnect_and_release('):].split('rws_bool rws_socket_send_text(', 1)[0] +harness = r''' +#include +#include +#include +#define MBEDTLS_ERR_SSL_WANT_READ -2 +#define MBEDTLS_ERR_SSL_WANT_WRITE -3 +#define COMMAND_NONE 0 +#define COMMAND_DISCONNECT 6 +#define COMMAND_END 9999 +typedef struct {int ssl_ctx;} tls; +typedef struct {tls *ssl; int work_mutex, is_connected, worker_started, work_thread, command;} _rws_socket; +typedef _rws_socket *rws_socket; +static int replies[16], calls, reply_count, expected_offset, freed, locks; +static unsigned int ticks; +static const unsigned char bytes[] = "abcdef"; +static unsigned int ql_rtos_get_systicks(void) { return ticks; } +static void rws_thread_sleep(int ms) { ticks += (unsigned int)ms; } +static int mbedtls_ssl_write(int *ctx, const unsigned char *data, size_t size) { + int ret; + (void)ctx; + assert(data == bytes + expected_offset); + assert(size == 6 - (size_t)expected_offset); + ret = calls < reply_count ? replies[calls] : MBEDTLS_ERR_SSL_WANT_WRITE; + ++calls; + if (ret > 0) expected_offset += ret; + return ret; +} +static void rws_mutex_lock(int mutex) {(void)mutex; ++locks;} +static void rws_mutex_unlock(int mutex) {(void)mutex; --locks;} +static void rws_socket_delete(_rws_socket *s) {(void)s; assert(locks == 0); ++freed;} +''' +harness += send + cancel +harness += r''' +int main(void) { + tls ctx = {0}; + _rws_socket s = {0}; + s.ssl = &ctx; + replies[0] = -2; replies[1] = 2; replies[2] = -3; replies[3] = 4; reply_count = 4; + assert(rws_tls_send_all(&s, bytes, 6) == 6 && calls == 4 && expected_offset == 6); + calls = 0; expected_offset = 0; replies[0] = 2; replies[1] = -99; reply_count = 2; + assert(rws_tls_send_all(&s, bytes, 6) == -1 && calls == 2); + calls = 0; expected_offset = 0; replies[0] = 0; reply_count = 1; + assert(rws_tls_send_all(&s, bytes, 6) == -1 && calls == 1); + calls = 0; expected_offset = 0; reply_count = 0; ticks = 0; + assert(rws_tls_send_all(&s, bytes, 6) == -1 && ticks >= 1000 && calls < 1000); + calls = 0; ticks = (unsigned int)-500; + assert(rws_tls_send_all(&s, bytes, 6) == -1 && calls < 1000); + s.ssl = NULL; calls = 0; + assert(rws_tls_send_all(&s, bytes, 6) == -1 && calls == 0); + s.is_connected = 1; rws_socket_disconnect_and_release(&s); + assert(s.command == COMMAND_DISCONNECT && locks == 0 && !freed); + s.is_connected = 0; s.worker_started = 1; s.command = 1; + rws_socket_disconnect_and_release(&s); + assert(s.command == COMMAND_END && locks == 0 && !freed); + s.worker_started = 0; s.command = COMMAND_NONE; + rws_socket_disconnect_and_release(&s); + assert(freed == 1 && locks == 0); + rws_socket_disconnect_and_release(NULL); + puts("PASS: TLS partial writes, WANT retry, fatal/EOF, timeout, tick wrap, null context, worker cancellation"); + return 0; +} +''' +output = root / 'artifacts/wss' +output.mkdir(parents=True, exist_ok=True) +cfile = output / 'test_wss_io.c' +cfile.write_text(harness, encoding='utf-8') +exe = output / 'test_wss_io.exe' +subprocess.run(['cl', '/nologo', '/W4', '/WX', '/TC', str(cfile), + '/Fo' + str(output / 'test_wss_io.obj'), '/Fe' + str(exe)], check=True) +subprocess.run([str(exe)], check=True) diff --git a/tools/test_wss_receive.py b/tools/test_wss_receive.py new file mode 100644 index 0000000..190cbe2 --- /dev/null +++ b/tools/test_wss_receive.py @@ -0,0 +1,126 @@ +"""Exercise the real receive/upgrade loop with delayed TLS records.""" +from pathlib import Path +import subprocess + +root = Path(__file__).resolve().parents[1] +lib = root / 'ql-application/threadx/interface/custom_app/lib/librws' +source = (lib / 'src/rws_socketpriv.c').read_bytes().decode('latin1') +receive = source[source.index('rws_bool rws_socket_recv('):].split('/* RT-Thread Team add */', 1)[0] +upgrade = source[source.index('void rws_socket_wait_handshake_responce('):].split('void rws_socket_send_disconnect(', 1)[0] +harness = r''' +#include +#include +#include +#include +#include "rws_handshake.h" +#define LIBRWS_USING_MBED_TLS +#define MBEDTLS_ERR_SSL_WANT_READ -2 +#define MBEDTLS_ERR_SSL_WANT_WRITE -3 +#define MBEDTLS_ERR_NET_RECV_FAILED -4 +#define WSAEWOULDBLOCK 11 +#define WSAEINPROGRESS 115 +#define RWS_RECEIVE_BUFF_SIZE 1024 +#define COMMAND_WAIT_HANDSHAKE_RESPONCE 3 +#define COMMAND_INFORM_CONNECTED 4 +#define COMMAND_INFORM_DISCONNECTED 5 +#define rws_error_code_read_write_socket 4 +#define rws_error_code_parse_handshake 5 +#define LOG_E(...) ((void)0) +#define LOG_D(...) ((void)0) +#define LOG_I(...) ((void)0) +typedef int rws_bool; +enum { rws_false, rws_true }; +typedef struct { int ssl_ctx; } tls; +typedef struct { + const char *scheme, *expected_accept; + tls *ssl; + char *payload_buff, *received; + size_t received_size, received_len; + int socket, command, is_connected; + const char *error; +} _rws_socket; +static int replies[16], reply_count, calls, closes; +static size_t offset; +static unsigned int ticks; +static const char response[] = + "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\n" + "Connection: Upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\nDATA"; +static unsigned int ql_rtos_get_systicks(void) { return ticks; } +static void rws_thread_sleep(int ms) { ticks += (unsigned int)ms; } +static void rws_error_delete_clean(const char **e) { *e = NULL; } +static const char *rws_error_new_code_descr(int code, const char *text) { (void)code; return text; } +static void rws_socket_close(_rws_socket *s) { (void)s; ++closes; } +static void rws_socket_resize_received(_rws_socket *s, size_t size) { + s->received = (char *)realloc(s->received, size); + assert(s->received); s->received_size = size; +} +static int recv(int fd, char *buf, int size, int flags) { + (void)fd; (void)buf; (void)size; (void)flags; + assert(0 && "WSS must use TLS receive"); return -1; +} +static int mbedtls_ssl_read(int *ctx, unsigned char *buf, size_t size) { + int ret = calls < reply_count ? replies[calls] : MBEDTLS_ERR_SSL_WANT_READ; + (void)ctx; ++calls; + if (ret > 0) { + assert((size_t)ret <= size && offset + (size_t)ret <= sizeof(response) - 1); + memcpy(buf, response + offset, (size_t)ret); offset += (size_t)ret; + } + return ret; +} +''' +harness += receive + upgrade +harness += r''' +static void reset(_rws_socket *s, tls *ctx) { + free(s->received); memset(s, 0, sizeof(*s)); + s->scheme = "wss"; s->ssl = ctx; + s->expected_accept = "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="; + s->payload_buff = (char *)malloc(RWS_RECEIVE_BUFF_SIZE); assert(s->payload_buff); + s->command = COMMAND_WAIT_HANDSHAKE_RESPONCE; + calls = closes = reply_count = 0; offset = 0; ticks = 0; +} +int main(void) { + tls ctx = {0}; _rws_socket s = {0}; int want; + for (want = -2; want >= -3; --want) { + reset(&s, &ctx); replies[0] = want; reply_count = 1; + assert(!rws_socket_recv(&s)); + assert(!s.error && s.command == COMMAND_WAIT_HANDSHAKE_RESPONCE && closes == 0); + replies[1] = 17; replies[2] = want; replies[3] = (int)sizeof(response) - 1 - 17; + reply_count = 4; + rws_socket_wait_handshake_responce(&s); + assert(s.is_connected && !s.error && s.command == COMMAND_INFORM_CONNECTED); + assert(calls == 4 && closes == 0 && s.received_len == 4); + assert(!memcmp(s.received, "DATA", 4)); free(s.payload_buff); + } + reset(&s, &ctx); + rws_socket_wait_handshake_responce(&s); + assert(!s.is_connected && s.error && closes == 1 && ticks >= 2000 && calls < 300); + free(s.payload_buff); + reset(&s, &ctx); ticks = (unsigned int)-1000; + rws_socket_wait_handshake_responce(&s); + assert(!s.is_connected && s.error && closes == 1 && calls < 300); free(s.payload_buff); + for (want = 0; want >= -99; want -= 99) { + reset(&s, &ctx); replies[0] = want; reply_count = 1; + rws_socket_wait_handshake_responce(&s); + assert(!s.is_connected && s.error && closes == 1 && calls == 1); + assert(s.command == COMMAND_INFORM_DISCONNECTED); free(s.payload_buff); + } + reset(&s, NULL); rws_socket_wait_handshake_responce(&s); + assert(s.error && closes == 1 && calls == 0); free(s.payload_buff); + reset(&s, &ctx); s.expected_accept = "wrong"; + replies[0] = (int)sizeof(response) - 1; reply_count = 1; + rws_socket_wait_handshake_responce(&s); + assert(!s.is_connected && s.error && closes == 1); free(s.payload_buff); + free(s.received); + puts("PASS: actual TLS receive/upgrade loop: WANT_READ/WRITE, split HTTP 101, trailing frame bytes, timeout/wrap, EOF/fatal, null TLS, invalid Accept"); + return 0; +} +''' +output = root / 'artifacts/wss' +output.mkdir(parents=True, exist_ok=True) +cfile = output / 'test_wss_receive.c' +cfile.write_text(harness, encoding='utf-8') +exe = output / 'test_wss_receive.exe' +subprocess.run(['cl', '/nologo', '/W4', '/WX', '/wd4018', '/TC', + '/I' + str(lib / 'inc'), str(cfile), str(lib / 'src/rws_handshake.c'), + '/Fo' + str(output) + '/', '/Fe' + str(exe)], check=True) +subprocess.run([str(exe)], check=True) diff --git a/tools/verify_wss_package.py b/tools/verify_wss_package.py new file mode 100644 index 0000000..f5da85e --- /dev/null +++ b/tools/verify_wss_package.py @@ -0,0 +1,67 @@ +"""Verify the new-board WSS package, including enabled GNSS task entry points.""" +import hashlib +import json +import re +import subprocess +import sys +import zipfile +from pathlib import Path + +root = Path(__file__).resolve().parents[1] +package = Path(sys.argv[1]).resolve() if len(sys.argv) > 1 else root / 'artifacts/wss/new-board/EG800AKCN_11LG-new-board-wss-x25519.zip' +output = package.parent +output.mkdir(parents=True, exist_ok=True) +objdump = root / 'ql-cross-tool/win32/owtoolchain/gcc-arm-none-eabi/bin/arm-none-eabi-objdump.exe' +app = root / 'ql-application/threadx/build/app.elf' +symbols = subprocess.check_output([str(objdump.with_name('arm-none-eabi-nm.exe')), str(app)], text=True) +required = ['talkingq_parse_wss_url', 'talkingq_root_ca', 'rws_check_handshake', 'rws_ssl_conn', + 'mbedtls_ssl_set_hostname', 'mbedtls_ssl_get_verify_result', 'mbedtls_ssl_conf_authmode', + 'mbedtls_ctr_drbg_random', 'mbedtls_sha1', 'mbedtls_base64_encode', 'mbedtls_ssl_handshake_step', + 'rws_tls_preferred_curves'] +for symbol in required: + assert re.search(r'\b' + symbol + r'$', symbols, re.M), 'Missing linked symbol: ' + symbol +kernel_symbols = subprocess.check_output([str(objdump.with_name('arm-none-eabi-nm.exe')), + str(root / 'ql-kernel/threadx/build/kernel.axf')], text=True) +kernel_required = ['ecdsa_verify_restartable', 'mbedtls_ecdsa_read_signature', + 'mbedtls_gcm_crypt_and_tag', 'mbedtls_x509_time_is_future', + 'mbedtls_x509_time_is_past', 'mbedtls_platform_gmtime_r', 'mbedtls_time', + 'ecp_mod_p256', 'ecp_mod_p384', 'ecp_mod_p521'] +for symbol in kernel_required: + assert re.search(r'\b' + symbol + r'$', kernel_symbols, re.M), 'Missing kernel capability: ' + symbol +clock_body = subprocess.check_output([str(objdump), '-d', '--disassemble=x509_get_current_time', + str(root / 'ql-kernel/threadx/build/kernel.axf')], text=True) +assert '' in clock_body and '' not in clock_body +(output / 'x509-clock.disasm.txt').write_text(clock_body) +report = {'package': package.name, 'sha256': hashlib.sha256(package.read_bytes()).hexdigest(), + 'board': 'new board with GNSS enabled', + 'linked_symbols': required, 'kernel_symbols': kernel_required, + 'hardware_test': 'New-board package awaits device testing; legacy board verified X25519 full handshake at 1455 ms on 2026-09-16', + 'backend': '2026-09-16 11:32 CST: WSS 443 /ws HTTP 101; 8080 plaintext WS'} +with zipfile.ZipFile(package) as archive: + assert archive.testzip() is None, 'ZIP CRC failure' + for name, source in {'cp.bin': 'ql-kernel/threadx/build/release_kernel.bin', + 'customer_app.bin': 'ql-application/threadx/build/app.bin'}.items(): + data = archive.read(name) + assert data == (root / source).read_bytes(), 'Stale image: ' + name + report[name] = {'bytes': len(data), 'sha256': hashlib.sha256(data).hexdigest()} + assert b'wss://banban.api.talkingq.com:443/ws' in archive.read('customer_app.bin') + assert b'WSS TLS handshake total=' in archive.read('customer_app.bin') + assert b'WSS TLS full handshake: prefer X25519' in archive.read('customer_app.bin') + assert b'Legacy board:' not in archive.read('customer_app.bin') + assert b'Legacy board:' not in archive.read('cp.bin') + assert b'gnss_Task_Ref' in archive.read('customer_app.bin') + report['download_manifest'] = json.loads(archive.read('download.json')) +task_create_address = int(re.search(r'^([0-9a-fA-F]+) T ql_rtos_task_create$', symbols, re.M).group(1), 16) +for symbol, binary, expected in [ + ('quec_get_gnssid_task', root / 'ql-kernel/threadx/build/kernel.axf', ''), + ('app_gnss_init', app, '0x%08x' % (task_create_address | 1)), + ('set_gnss_mode', app, 'strb')]: + body = subprocess.check_output([str(objdump), '-d', '--disassemble=' + symbol, str(binary)], text=True) + assert '<' + symbol + '>:' in body and expected in body, 'GNSS entry point disabled or unexpected code: ' + symbol + (output / (symbol + '.disasm.txt')).write_text(body) +for symbol, table in [('quec_get_ocname_by_gnss_task', kernel_symbols), ('quec_gnss_test', symbols)]: + assert re.search(r'\b' + symbol + r'$', table, re.M), 'Missing GNSS worker: ' + symbol +report['verification'] = 'PASS: ZIP CRC, current APP/kernel identity, GNSS task creation, WSS URL, ECDSA/GCM/RTC/NIST kernel symbols and handshake timing logs' +(output / 'verification.json').write_text(json.dumps(report, indent=2)) +print(report['verification']) +print('SHA256:', report['sha256']) diff --git a/tools/wss_host_stubs/UART.h b/tools/wss_host_stubs/UART.h new file mode 100644 index 0000000..9b4635c --- /dev/null +++ b/tools/wss_host_stubs/UART.h @@ -0,0 +1 @@ +void CPUartLogPrintf(const char *format, ...); diff --git a/tools/wss_tls_host_config.h b/tools/wss_tls_host_config.h new file mode 100644 index 0000000..b462c53 --- /dev/null +++ b/tools/wss_tls_host_config.h @@ -0,0 +1,14 @@ +/* Host adapter: crypto/X.509 features are the firmware's shared profile. + * Only CPU assembly and the OS allocator/clock implementation differ. */ +#include "../ql-config/config/talkingq_mbedtls_config.h" +#ifdef WSS_TEST_DISABLE_NIST_OPTIM +#undef MBEDTLS_ECP_NIST_OPTIM +#endif +#ifdef WSS_TEST_ECP_WINDOW +#undef MBEDTLS_ECP_WINDOW_SIZE +#define MBEDTLS_ECP_WINDOW_SIZE WSS_TEST_ECP_WINDOW +#endif +#undef MBEDTLS_HAVE_ASM +#undef MBEDTLS_FS_IO +#define QUECTEL_MBEDTLS_SUPPORT +#include "mbedtls/check_config.h"