LXR | KVM | PM | Time | Interrupt | Systems Performance | Bootup Optimization

Linux Crypto(9):tcrypt进行Crypto测试

 通过/proc/crypto获取当前内核支持的Crypto算法,然后通过tcrypt模块进行测试。

1 配置tcrypt

Cryptographic API (CRYPTO [=y])
  ->Crypto core or helper
    ->Testing module

不能打开CRYPTO_MANAGER_DISABLE_TESTS选项。

2 tcrypt初始化

tcrypt_mod_init
  ->do_test
    ->tcrypt_test
      ->alg_test
    ->test_cipher_speed
    ->test_acipher_speed
    ->test_aead_speed
    ->test_mb_aead_speed
    ->test_hash_speed
    ->test_ahash_speed
    ->test_mb_skcipher_speed

为了打印更多参考消息,在tcrypt.c和testmgr.c的头部添加#define DEBUG。

3 tcrypt模块参数

tcrypt模块参数如下:
参数类型默认值作用描述示例用法
alg string 指定算法名称
直接定义要测试的加密算法
alg="cbc(aes)"
alg="sha256"
type uint 0 算法类型分类
定义测试的算法类别

type=skcipher
type=aead

上述字符对应的算法类型值,位于include/linux/crypto.h。

mask uint 0 测试模式掩码
位掩码控制测试类型
mask=1 (仅加密)
mask=5 (1+4)
mode int 0 预定义测试模式
使用编号选择预设测试套件
mode=200 (AES-CBC)
mode=318 (SHA256)
sec uint 0 测试持续时间
速度测试的运行时间(秒)
sec=2 (2秒测试)
sec=0 (单次)
num_mb uint 8 多缓冲区数量
并行测试的缓冲区数量
num_mb=16 (16个并行缓冲区)
klen uint 0 密钥长度(比特)
指定测试密钥长度
klen=256 (AES-256)

4 使用tcrypt进行Crypto测试

修改tcrypt.c,支持对单个算法进行测试:

static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
{
        int i;
        int ret = 0;

        switch (m) {
        case 0:
                if (alg) {
                        if (!crypto_has_alg(alg, type,
                                            mask ?: CRYPTO_ALG_TYPE_MASK))
                                ret = -ENOENT;
                        else
                                ret = min(ret, tcrypt_test(alg));
                        break;
                }

                for (i = 1; i < 200; i++)
                        ret = min(ret, do_test(NULL, 0, 0, i, num_mb));
                break;

算法类型列表:

#define CRYPTO_ALG_TYPE_MASK            0x0000000f
#define CRYPTO_ALG_TYPE_CIPHER          0x00000001
#define CRYPTO_ALG_TYPE_COMPRESS        0x00000002
#define CRYPTO_ALG_TYPE_AEAD            0x00000003
#define CRYPTO_ALG_TYPE_SKCIPHER        0x00000005
#define CRYPTO_ALG_TYPE_AKCIPHER        0x00000006
#define CRYPTO_ALG_TYPE_SIG             0x00000007
#define CRYPTO_ALG_TYPE_KPP             0x00000008
#define CRYPTO_ALG_TYPE_ACOMPRESS       0x0000000a
#define CRYPTO_ALG_TYPE_SCOMPRESS       0x0000000b
#define CRYPTO_ALG_TYPE_RNG             0x0000000c
#define CRYPTO_ALG_TYPE_HASH            0x0000000e
#define CRYPTO_ALG_TYPE_SHASH           0x0000000e
#define CRYPTO_ALG_TYPE_AHASH           0x0000000f

编写脚本对支持的算法进行测试:

#!/bin/sh

# 设置测试持续时间(秒)
TEST_SEC=1
OUTPUT_FILE="crypto_test_results.txt"

# 清空结果文件
echo "Crypto Algorithm Test Results" > $OUTPUT_FILE
echo "=============================" >> $OUTPUT_FILE
echo "Timestamp: $(date)" >> $OUTPUT_FILE
echo >> $OUTPUT_FILE

# 算法类型到整数值的映射函数
map_alg_type() {
    case "$1" in
        "cipher")    echo 1 ;;
        "compress")  echo 2 ;;
        "aead")      echo 3 ;;
        "skcipher") echo 5 ;;
        "akcipher") echo 6 ;;
        "sig")       echo 7 ;;
        "kpp")       echo 8 ;;
        "acompress") echo 10 ;;
        "scompress") echo 11 ;;
        "rng")       echo 12 ;;
        "hash")      echo 14 ;;
        "shash")     echo 14 ;;
        "ahash")     echo 15 ;;
        *)           echo 0 ;;  # 未知类型
    esac
}

# 更可靠的方法获取算法列表
ALGORITHMS=$(awk -F':' '
BEGIN {
    # 初始化变量
    current_name = ""
    current_type = ""
    in_record = 0
}

# 当遇到算法名称时
/^name/ {
    # 提取算法名称(去掉多余空格)
    gsub(/^[ \t]+|[ \t]+$/, "", $2);
    current_name = $2
    in_record = 1
}

# 当遇到算法类型时
/^type/ {
    # 提取算法类型(去掉多余空格)
    gsub(/^[ \t]+|[ \t]+$/, "", $2);
    current_type = $2
}

# 当记录结束时(空行)
/^$/ {
    if (in_record && current_name != "" && current_type != "") {
        print current_type ":" current_name
    }
    # 重置变量
    current_name = ""
    current_type = ""
    in_record = 0
}

END {
    # 处理最后一个记录
    if (in_record && current_name != "" && current_type != "") {
        print current_type ":" current_name
    }
}' /proc/crypto)

# 检查是否成功获取算法列表
if [ -z "$ALGORITHMS" ]; then
    echo "错误:无法从 /proc/crypto 获取算法列表"
    echo "请尝试手动查看 /proc/crypto 内容:"
    cat /proc/crypto
    exit 1
fi

# 测试计数器
TOTAL=$(echo "$ALGORITHMS" | wc -l)
COUNT=0
PASSED=0
FAILED=0

# 创建临时文件来存储算法列表
TMPFILE=$(mktemp) || { echo "创建临时文件失败"; exit 1; }
echo "$ALGORITHMS" > "$TMPFILE"

# 遍历所有算法
while IFS=: read -r alg_type_str alg_name; do
    COUNT=$((COUNT+1))

    # 转换为整数值
    alg_type_value=$(map_alg_type "$alg_type_str")

    # 准备测试
    echo "[$COUNT/$TOTAL] 测试 $alg_type_str($alg_type_value): $alg_name"
    dmesg -c > /dev/null # 清除内核日志

    # 加载tcrypt进行测试
    modprobe tcrypt type=$alg_type_value alg="$alg_name" sec=$TEST_SEC 2>/dev/null
    # 获取测试结果
    TEST_RESULT=$(dmesg | grep -A 5 "tcrypt")

    if echo "$TEST_RESULT" | grep -q "passed"; then
        STATUS="通过"
        PASSED=$((PASSED+1))
    else
        STATUS="失败"
        FAILED=$((FAILED+1))
    fi

    # 记录结果
    echo "测试 $COUNT: $alg_type_str/$alg_name (type=$alg_type_value) - $STATUS" >> $OUTPUT_FILE
    echo "$TEST_RESULT" >> $OUTPUT_FILE
    echo "----------------------------------------" >> $OUTPUT_FILE


    # 卸载tcrypt
    rmmod tcrypt 2>/dev/null
    sleep 0.5
done < "$TMPFILE"

# 删除临时文件
rm -f "$TMPFILE"

# 生成摘要报告
echo >> $OUTPUT_FILE
echo "测试摘要" >> $OUTPUT_FILE
echo "------------" >> $OUTPUT_FILE
echo "总算法数: $TOTAL" >> $OUTPUT_FILE
echo "已测试: $((PASSED + FAILED))" >> $OUTPUT_FILE
echo "通过: $PASSED" >> $OUTPUT_FILE
echo "失败: $FAILED" >> $OUTPUT_FILE
echo "跳过: $((TOTAL - PASSED - FAILED))" >> $OUTPUT_FILE

echo
echo "测试完成。结果保存在 $OUTPUT_FILE"

 

posted on 2025-07-28 23:59  ArnoldLu  阅读(125)  评论(0)    收藏  举报

导航