Files
STM32F4-Base/test/host/sha256/sha256_test.c
T
wandering1 d1e6bb4ba7 W5波+N-19收口:FTP鉴权落地、Trap25三连定案修复(N-30)、N-20/N-23/N-26
N-19 FTP 鉴权:
- lftpd_auth(USER/PASS 状态机 + 连续5次失败锁60s)+ SHA-256
  (user||pwd) 口令哈希;config.ini [ftp] 段 user/pwd_hash/write,
  出厂 admin/admin 在用有启动告警;lftpd_log.c 删除并入 lftpd_auth
- ftp_cfg 配置读写;台架 ftp_auth_bench.py 13/13

N-30 / Trap 25(CH395F_Trap_Records.md 四次定案全记录):
- 修复1 closed-with-data accept:客户端发完正常 FIN 后芯片按
  FUN_PARA(0x09) §5.52② 保留 Socket+RX 缓冲,旧代码把 CLOSED 一律
  relisten 自毁缓冲 → STOR 必挂 425;改为接受"已关但可读"连接排空
- 修复2 丢 CONNECT 中断探针 net_lost_connect_probe + last_peer_port
  幽灵甄别(拆链窗口握手完成但中断丢失,双信源去抖补 accept)
- 修复3 send_list/send_nlst 批量单发:背靠背 ~60B 小段毒化芯片 TX
  (芯片报 SEND_OK 但对端全丢),整份目录一次性写入
- 证伪存档:固定沉降/Socket 轮换冷却/listen 门控(台架 v7 矩阵)
- 台架工具 test/board/ch395f_reuse_bench.{c,h} + host 脚本存档
  (不注册编译;实验分支 n30-chip-bench 保留)

N-20:Error_Handler 死循环降级(记录+复位路径)
N-23:scripts/check_registration.py 双端注册反向校验(pre-commit)
N-26:GD5F NAND 直 DMA 调用方缓冲窗口断言

验证:BUILD_OK 0/0;ftp_regression 连跑 4 轮 11/11(修复前
LIST#4/#7 100% 挂、STOR#2 曾 100% 425);ftp_auth_bench 13/13;
@test 启动标记 PASS;ci_local L0+L0.5 全过;doc-links 通过。
登记簿 N-30 已销项。
2026-10-11 18:50:24 +08:00

193 lines
6.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 模块名称:SHA-256 主机侧单元测试
* 模块功能:在 PC 上对 App/util/sha256.c 做离线验证(FIPS 180-4 标准向量 +
* 流式等价 + sha256_hex_eq 边界)。
*
* 被测对象:真实源文件 ../../../App/util/sha256.c(以 #include 原样纳入,
* 保证测的是生产代码而非副本;本模块零平台依赖,无需任何桩)。
*
* 为什么要主机侧单测(而不是只靠台架):
* sha256 是 FTP pwd_hash 校验(N-19)的地基——哈希算错的后果是
* "正确口令被拒 / 错误口令放行"这类静默语义错误,板端只看到 530/230,
* 看不出哪一步坏;标准向量在主机侧毫秒级钉死。
*
* 覆盖点:
* TC-SH-001 FIPS 180-4 向量:空串
* TC-SH-002 FIPS 180-4 向量:"abc"
* TC-SH-003 FIPS 180-4 向量:56 字节(补位跨分组边界)
* TC-SH-004 FIPS 180-4 向量:1,000,000 × 'a'(流式,长度字段进第二分组)
* TC-SH-005 流式任意切分与一次性计算等价(逐字节喂入)
* TC-SH-006 hex_eq:小写匹配 / 大写匹配
* TC-SH-007 hex_eq:内容不等 / 非法字符 / 长度 63/65 / NULL → 全 0
* TC-SH-008 默认口令哈希钉值:SHA256("adminadmin") = FTP_CFG_DEF_HASH 同源值
*
* 通过:全部 TC PASS(main 返回 0)。
* 入口:int main(void),返回 0=PASS / 1=FAIL(由 run 脚本判读)。
*
* 创建日期:2026-10-11
*/
#include <stdio.h>
#include <string.h>
/* 生产源文件原样纳入(零平台依赖,直接编) */
#include "sha256.c"
/* ===================== 断言框架 ===================== */
static int s_total;
static int s_passed;
static int s_failed;
#define CHECK(cond, name) do { \
s_total++; \
if (cond) { s_passed++; printf(" PASS %s\n", name); } \
else { s_failed++; printf(" FAIL %s (line %d)\n", name, __LINE__); } \
} while (0)
/* 摘要 → hex 小写串(仅测试用,允许栈上 sprintf) */
static void digest_to_hex(const uint8_t d[SHA256_DIGEST_SIZE], char out[65])
{
static const char hexd[] = "0123456789abcdef";
for (int i = 0; i < 32; i++) {
out[2 * i] = hexd[(d[i] >> 4) & 0xF];
out[2 * i + 1] = hexd[d[i] & 0xF];
}
out[64] = '\0';
}
static int hex_eq_vector(const uint8_t d[SHA256_DIGEST_SIZE], const char *want)
{
char got[65];
digest_to_hex(d, got);
return strcmp(got, want) == 0;
}
/* ===================== TC-SH-001..004:标准向量 ===================== */
static void tc_vectors(void)
{
uint8_t d[SHA256_DIGEST_SIZE];
sha256_calc("", 0u, d);
CHECK(hex_eq_vector(d, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"),
"TC-SH-001 空串向量");
sha256_calc("abc", 3u, d);
CHECK(hex_eq_vector(d, "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"),
"TC-SH-002 \"abc\" 向量");
sha256_calc("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56u, d);
CHECK(hex_eq_vector(d, "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"),
"TC-SH-003 56 字节向量(补位跨分组)");
{
sha256_ctx_t ctx;
sha256_init(&ctx);
for (int i = 0; i < 1000000; i++) {
sha256_update(&ctx, "a", 1u);
}
sha256_final(&ctx, d);
}
CHECK(hex_eq_vector(d, "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"),
"TC-SH-004 1e6 × 'a' 向量(流式)");
}
/* ===================== TC-SH-005:流式等价 ===================== */
static void tc_stream_equiv(void)
{
static const char msg[] = "the quick brown fox jumps over the lazy dog";
uint8_t d1[SHA256_DIGEST_SIZE];
uint8_t d2[SHA256_DIGEST_SIZE];
sha256_ctx_t ctx;
sha256_calc(msg, strlen(msg), d1);
sha256_init(&ctx);
for (size_t i = 0; i < strlen(msg); i++) {
sha256_update(&ctx, &msg[i], 1u);
}
sha256_final(&ctx, d2);
CHECK(memcmp(d1, d2, sizeof(d1)) == 0, "TC-SH-005 逐字节喂入与一次性等价");
}
/* ===================== TC-SH-006..007:hex_eq ===================== */
static void tc_hex_eq(void)
{
uint8_t d[SHA256_DIGEST_SIZE];
char lower[65];
char upper[65];
char shortv[65];
char longv[66];
sha256_calc("adminadmin", 10u, d);
digest_to_hex(d, lower);
for (int i = 0; i < 64; i++) {
upper[i] = (char)((lower[i] >= 'a') ? (lower[i] - 32) : lower[i]);
}
upper[64] = '\0';
CHECK(sha256_hex_eq(d, lower) == 1, "TC-SH-006a 小写 hex 匹配");
CHECK(sha256_hex_eq(d, upper) == 1, "TC-SH-006b 大写 hex 匹配(大小写不敏感)");
lower[63] = (char)((lower[63] == '0') ? '1' : '0');
CHECK(sha256_hex_eq(d, lower) == 0, "TC-SH-007a 内容不等 → 0");
lower[63] = (char)((lower[63] == '0') ? '1' : '0'); /* 还原 */
{
char bad[65];
memcpy(bad, lower, 64);
bad[64] = '\0';
bad[10] = 'g';
CHECK(sha256_hex_eq(d, bad) == 0, "TC-SH-007b 非法 hex 字符 → 0");
}
memcpy(shortv, lower, 63);
shortv[63] = '\0';
CHECK(sha256_hex_eq(d, shortv) == 0, "TC-SH-007c 长度 63 → 0");
memcpy(longv, lower, 64);
longv[64] = 'a';
longv[65] = '\0';
CHECK(sha256_hex_eq(d, longv) == 0, "TC-SH-007d 长度 65 → 0");
CHECK(sha256_hex_eq(d, NULL) == 0, "TC-SH-007e NULL → 0");
}
/* ===================== TC-SH-008:默认口令哈希钉值 ===================== */
static void tc_default_hash(void)
{
uint8_t d[SHA256_DIGEST_SIZE];
/* 与 ftp_cfg.h FTP_CFG_DEF_HASH 同源钉值(两处若漂移本测试立刻红) */
sha256_calc("adminadmin", 10u, d);
CHECK(sha256_hex_eq(d, "d82494f05d6917ba02f7aaa29689ccb444bb73f20380876cb05d1f37537b7892") == 1,
"TC-SH-008 SHA256(\"adminadmin\") = 出厂默认 pwd_hash");
}
/* ===================== main ===================== */
int main(void)
{
printf("=== SHA-256 Tests ===\n");
printf("-- FIPS 180-4 vectors --\n");
tc_vectors();
printf("-- streaming equivalence --\n");
tc_stream_equiv();
printf("-- hex_eq --\n");
tc_hex_eq();
printf("-- default password hash --\n");
tc_default_hash();
printf("\n=== SHA-256 Tests: %d/%d PASSED (failed=%d) ===\n",
s_passed, s_total, s_failed);
return (s_failed == 0) ? 0 : 1;
}