Я понятия не имею, что может быть прослушано
Поэтому я пытаюсь написать свою собственную программу "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);
}
Это заставляет меня поверить, что некоторая часть этого кода не определена, и я понятия не имею, что может быть неопределенным.
1 ответ
Прежде всего замените это:
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
вызывают проблему. Было бы очень полезно, если вы обновите свой пост, чтобы показать полную программу. (то есть то, что кто-то другой может скомпилировать без изменений, чтобы воспроизвести проблему). В это время:
Если 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
,
В этой строке memcpy(hash, state, size);
странно, что количество байтов, с которыми вы работаете, rsizew * 8
, но количество байтов, которые вы копируете size
, они не будут одинаковыми в целом.
Я обновлю свой пост после того, как вы опубликуете полную программу, чтобы учесть фактические значения size
в использовании.
NB. Это должен быть SHA-3?