mirror of
https://github.com/open-quantum-safe/liboqs.git
synced 2025-10-04 00:02:01 -04:00
* Add SPDX-License-Identifier in src/common * Add SPDX-License-Identifier in FrodoKEM * Add SPDX-License-Identifier in SIKE * Add SPDX-License-Identifier in BIKE * Add SPDX-License-Identifier in OQS headers * Add SPDX-License-Identifier in files generated during copy-from-pqclean * Add SPDX-License-Identifier in Picnic * Add SPDX-License-Identifier in qTesla * Add SPDX-License-Identifier in CMake files * Update license info in README * Add SPDX-License-Identifier in scripts * Add SPDX-License-Info to CMakeLists * Add SPDX-License-Info in tests * Add SPDX-License-Info to various files * Prettyprint * Add test for SPDX-License-Identifier headers * Updated license identifiers for CPU extension detection code. * Use conjunction for SPDX in file with two licenses Co-authored-by: xvzcf <xvzcf@users.noreply.github.com>
241 lines
6.3 KiB
C
241 lines
6.3 KiB
C
// SPDX-License-Identifier: MIT
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include <oqs/aes.h>
|
|
#include <oqs/sha2.h>
|
|
#include <oqs/sha3.h>
|
|
|
|
#include "system_info.c"
|
|
|
|
#define BUFFER_SIZE 10000
|
|
|
|
static int read_stdin(uint8_t **msg, size_t *msg_len) {
|
|
*msg = malloc(BUFFER_SIZE);
|
|
if (*msg == NULL) {
|
|
return -1;
|
|
}
|
|
uint8_t *msg_next_read = *msg;
|
|
ssize_t bytes_read;
|
|
*msg_len = 0;
|
|
while (1) {
|
|
bytes_read = read(0, msg_next_read, BUFFER_SIZE);
|
|
if (bytes_read == -1) {
|
|
return -1;
|
|
}
|
|
*msg_len += (size_t)bytes_read;
|
|
if (bytes_read < BUFFER_SIZE) {
|
|
break;
|
|
} else {
|
|
uint8_t *msgprime = malloc(*msg_len + BUFFER_SIZE);
|
|
if (msgprime == NULL) {
|
|
return -1;
|
|
}
|
|
memcpy(msgprime, *msg, *msg_len);
|
|
free(*msg);
|
|
*msg = msgprime;
|
|
msg_next_read = &((*msg)[*msg_len]);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static void print_hex(uint8_t *s, size_t l) {
|
|
for (size_t i = 0; i < l; i++) {
|
|
printf("%02x", s[i]);
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
static int do_sha256(void) {
|
|
// read message from stdin
|
|
uint8_t *msg;
|
|
size_t msg_len;
|
|
if (read_stdin(&msg, &msg_len) != 0) {
|
|
fprintf(stderr, "ERROR: malloc failure\n");
|
|
return -1;
|
|
}
|
|
// run main SHA-256 API
|
|
uint8_t output[32];
|
|
OQS_SHA2_sha256(output, msg, msg_len);
|
|
// run incremental SHA-256 API
|
|
uint8_t output_inc[32];
|
|
OQS_SHA2_sha256_ctx state;
|
|
OQS_SHA2_sha256_inc_init(&state);
|
|
// clone state
|
|
OQS_SHA2_sha256_ctx state2;
|
|
OQS_SHA2_sha256_inc_ctx_clone(&state2, &state);
|
|
// hash with first state
|
|
if (msg_len > 64) {
|
|
OQS_SHA2_sha256_inc_blocks(&state, msg, 1);
|
|
OQS_SHA2_sha256_inc_finalize(output_inc, &state, &msg[64], msg_len - 64);
|
|
} else {
|
|
OQS_SHA2_sha256_inc_finalize(output_inc, &state, msg, msg_len);
|
|
}
|
|
if (memcmp(output, output_inc, 32) != 0) {
|
|
fprintf(stderr, "ERROR: Incremental API does not match main API\n");
|
|
free(msg);
|
|
return -2;
|
|
}
|
|
// hash with second state
|
|
if (msg_len > 64) {
|
|
OQS_SHA2_sha256_inc_blocks(&state2, msg, 1);
|
|
OQS_SHA2_sha256_inc_finalize(output_inc, &state2, &msg[64], msg_len - 64);
|
|
} else {
|
|
OQS_SHA2_sha256_inc_finalize(output_inc, &state2, msg, msg_len);
|
|
}
|
|
if (memcmp(output, output_inc, 32) != 0) {
|
|
fprintf(stderr, "ERROR: Incremental API with cloned state does not match main API\n");
|
|
free(msg);
|
|
return -3;
|
|
}
|
|
print_hex(output, 32);
|
|
free(msg);
|
|
return 0;
|
|
}
|
|
|
|
static int do_sha384(void) {
|
|
// read message from stdin
|
|
uint8_t *msg;
|
|
size_t msg_len;
|
|
if (read_stdin(&msg, &msg_len) != 0) {
|
|
fprintf(stderr, "ERROR: malloc failure\n");
|
|
return -1;
|
|
}
|
|
// run main SHA-384 API
|
|
uint8_t output[48];
|
|
OQS_SHA2_sha384(output, msg, msg_len);
|
|
// run incremental SHA-384 API
|
|
uint8_t output_inc[48];
|
|
OQS_SHA2_sha384_ctx state;
|
|
OQS_SHA2_sha384_inc_init(&state);
|
|
// clone state
|
|
OQS_SHA2_sha384_ctx state2;
|
|
OQS_SHA2_sha384_inc_ctx_clone(&state2, &state);
|
|
// hash with first state
|
|
if (msg_len > 64) {
|
|
OQS_SHA2_sha384_inc_blocks(&state, msg, 1);
|
|
OQS_SHA2_sha384_inc_finalize(output_inc, &state, &msg[64], msg_len - 64);
|
|
} else {
|
|
OQS_SHA2_sha384_inc_finalize(output_inc, &state, msg, msg_len);
|
|
}
|
|
if (memcmp(output, output_inc, 48) != 0) {
|
|
fprintf(stderr, "ERROR: Incremental API does not match main API\n");
|
|
free(msg);
|
|
return -2;
|
|
}
|
|
// hash with second state
|
|
if (msg_len > 64) {
|
|
OQS_SHA2_sha384_inc_blocks(&state2, msg, 1);
|
|
OQS_SHA2_sha384_inc_finalize(output_inc, &state2, &msg[64], msg_len - 64);
|
|
} else {
|
|
OQS_SHA2_sha384_inc_finalize(output_inc, &state2, msg, msg_len);
|
|
}
|
|
if (memcmp(output, output_inc, 48) != 0) {
|
|
fprintf(stderr, "ERROR: Incremental API with cloned state does not match main API\n");
|
|
free(msg);
|
|
return -3;
|
|
}
|
|
print_hex(output, 48);
|
|
free(msg);
|
|
return 0;
|
|
}
|
|
|
|
static int do_sha512(void) {
|
|
// read message from stdin
|
|
uint8_t *msg;
|
|
size_t msg_len;
|
|
if (read_stdin(&msg, &msg_len) != 0) {
|
|
fprintf(stderr, "ERROR: malloc failure\n");
|
|
return -1;
|
|
}
|
|
// run main SHA-512 API
|
|
uint8_t output[64];
|
|
OQS_SHA2_sha512(output, msg, msg_len);
|
|
// run incremental SHA-512 API
|
|
uint8_t output_inc[64];
|
|
OQS_SHA2_sha512_ctx state;
|
|
OQS_SHA2_sha512_inc_init(&state);
|
|
// clone state
|
|
OQS_SHA2_sha512_ctx state2;
|
|
OQS_SHA2_sha512_inc_ctx_clone(&state2, &state);
|
|
// hash with first state
|
|
if (msg_len > 64) {
|
|
OQS_SHA2_sha512_inc_blocks(&state, msg, 1);
|
|
OQS_SHA2_sha512_inc_finalize(output_inc, &state, &msg[64], msg_len - 64);
|
|
} else {
|
|
OQS_SHA2_sha512_inc_finalize(output_inc, &state, msg, msg_len);
|
|
}
|
|
if (memcmp(output, output_inc, 64) != 0) {
|
|
fprintf(stderr, "ERROR: Incremental API does not match main API\n");
|
|
free(msg);
|
|
return -2;
|
|
}
|
|
// hash with second state
|
|
if (msg_len > 64) {
|
|
OQS_SHA2_sha512_inc_blocks(&state2, msg, 1);
|
|
OQS_SHA2_sha512_inc_finalize(output_inc, &state2, &msg[64], msg_len - 64);
|
|
} else {
|
|
OQS_SHA2_sha512_inc_finalize(output_inc, &state2, msg, msg_len);
|
|
}
|
|
if (memcmp(output, output_inc, 64) != 0) {
|
|
fprintf(stderr, "ERROR: Incremental API with cloned state does not match main API\n");
|
|
free(msg);
|
|
return -3;
|
|
}
|
|
print_hex(output, 64);
|
|
free(msg);
|
|
return 0;
|
|
}
|
|
|
|
static int do_arbitrary_hash(void (*hash)(uint8_t *, const uint8_t *, size_t), size_t hash_len) {
|
|
// read message from stdin
|
|
uint8_t *msg;
|
|
size_t msg_len;
|
|
if (read_stdin(&msg, &msg_len) != 0) {
|
|
fprintf(stderr, "ERROR: malloc failure\n");
|
|
return -1;
|
|
}
|
|
// run main SHA-256 API
|
|
uint8_t *output = malloc(hash_len);
|
|
hash(output, msg, msg_len);
|
|
print_hex(output, hash_len);
|
|
free(output);
|
|
free(msg);
|
|
return 0;
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
if (argc != 2) {
|
|
fprintf(stderr, "Usage: test_hash algname\n");
|
|
fprintf(stderr, " algname: sha256, sha384, sha512, sha256inc, sha384inc, sha512inc\n");
|
|
fprintf(stderr, " test_hash reads input from stdin and outputs hash value as hex string to stdout");
|
|
printf("\n");
|
|
print_system_info();
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
char *hash_alg = argv[1];
|
|
|
|
if (strcmp(hash_alg, "sha256inc") == 0) {
|
|
return do_sha256();
|
|
} else if (strcmp(hash_alg, "sha384inc") == 0) {
|
|
return do_sha384();
|
|
} else if (strcmp(hash_alg, "sha512inc") == 0) {
|
|
return do_sha512();
|
|
} else if (strcmp(hash_alg, "sha256") == 0) {
|
|
return do_arbitrary_hash(&OQS_SHA2_sha256, 32);
|
|
} else if (strcmp(hash_alg, "sha384") == 0) {
|
|
return do_arbitrary_hash(&OQS_SHA2_sha384, 48);
|
|
} else if (strcmp(hash_alg, "sha512") == 0) {
|
|
return do_arbitrary_hash(&OQS_SHA2_sha512, 64);
|
|
} else {
|
|
fprintf(stderr, "ERROR: Test not implemented\n");
|
|
return EXIT_FAILURE;
|
|
}
|
|
}
|