c - 我不知道什么可能被窃听

标签 c undefined keccak

所以我正在尝试编写自己的“keccaksum”程序,除了运行

for i in {1..50}; do ./keccaksum 256 test.o; done

输出

4d4cc035e544cd4837b45550094dd3c419e380af3b0c74109c00053c7ed82040  test.o

大部分时间

b19d21947b7228da366b4d26f232b87e21999ff1a220c37c9bed6553260068c0  test.o

有时。

这里的相关函数是

void printsum(const char *_fname, FILE *_f, size_t size){   
    uint64_t state[25];
    uint8_t *hash = malloc(size * sizeof(uint8_t));
    uint8_t buf[25];
    uint8_t tmp[144];
    register int i, rsize, rsizew;
    register size_t j;

    rsize = 200 - 2 * size;
    rsizew = rsize / 8;

    //Clear the state
    memset(state, 0, sizeof(state));

    while(1) {
        //read up to rsize bytes, then do work
        j = fread(buf, 1, rsize, _f);

        //check some stuff
        if(feof(_f)){
            break;
        } else if(ferror(_f)){
            fprintf(stderr, "Error when reading %s.\n", _fname);
            goto fin;
        } else {
            //First few blocks (i.e. not last block)
            for(i = 0; i < rsizew; i++)
                state[i] ^= ((uint64_t *)buf)[i];
            keccakf(state, KECCAK_ROUNDS);
        }
    }

    //Last block + padding
    memcpy(tmp, buf, j);
    tmp[j++] = 1;
    memset(tmp + j, 0, rsize - j);
    tmp[rsize - 1] |= 0x80;

    for(i = 0; i < rsizew; i++)
        state[i] ^= ((uint64_t *)tmp)[i];
    keccakf(state, KECCAK_ROUNDS);

    //copy hash
    memcpy(hash, state, size);

    //print
    for(i = 0; i < size; i++) printf("%02x", hash[i]);
    printf("  %s\n", _fname);

fin:    
    if(_f != stdin) fclose(_f);
    free(hash);
}

这让我相信这段代码的某些部分是未定义的,而且我不知道什么可能是未定义的。

最佳答案

首先替换这个:

if(feof(_f)){
        break;
    } else if(ferror(_f)){
        fprintf(stderr, "Error when reading %s.\n", _fname);
        goto fin;
    } else {
        for(i = 0; .....

这样:

if ( j < rsize )
    break;

for (i = 0; .......

如果您关心要显示哪条错误消息,可以在循环后检查ferror

接下来,这可能会导致未定义的行为,具体取决于系统的对齐要求:

state[i] ^= ((uint64_t *)buf)[i];

为了安全起见,您可以将其替换为:

{
    uint64_t temp;
    memcpy(&temp, buf + i * sizeof temp, sizeof temp);
    state[i] ^= temp;
}

但是,如果您的系统是小端,我不清楚这是否是 keccak 算法的正确行为;如果 size 不是 8 的精确倍数,这是否正确。

对于size的某些值可能会出现各种其他错误。您没有指定哪些 size 值导致了问题,这让事情变得很困难。如果您更新帖子以显示完整的程序,这将非常有帮助。 (即其他人可以不加修改地编译以重现问题的东西)。与此同时:

如果大小 > 100 那么这将变得困惑。

对于 size 的较小值,这是缓冲区溢出:

uint8_t tmp[144];
memcpy(tmp, buf, j);
tmp[j++] = 1;
memset(tmp + j, 0, rsize - j);
tmp[rsize - 1] |= 0x80;

因为rsize可能高达200,这会溢出tmp。另外,考虑一下在 j == 0 的情况下是否要执行此 block 。

在这行memcpy(hash, state, size);奇怪的是,你操作的字节数是rsizew * 8,但是你操作的字节数副本是大小,这些一般不会相同。

在您发布完整程序后,我将更新我的帖子,以考虑使用中的 size 的实际值。

注意。这应该是 SHA-3 吗?

关于c - 我不知道什么可能被窃听,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23987074/

相关文章:

c - STM32Cube - 项目未构建(所选处理器不支持 Thumb 模式)

bsearch() c 上的比较函数

c - 如何将C程序代码转换成char[]?

ruby - 未定义方法 `-' 对于 nil :NilClass (NoMethodError)

javascript - forEach 在 Array 构造函数创建的未定义数组上

php - 密码散列 : Keccak or not

c - 将数组内的十六进制值显示到标准输出,并将输入与这些十六进制值进行比较

javascript - 按具有未定义值的多个条件对对象数组进行排序

node.js - 安装松露时出现 npm 错误 "Keccak bindings compilation fail."

unit-testing - Keccak (SHA-3) 示例哈希(测试向量)是否可用?