mirror of
https://github.com/stasenso/sha256_c_client.git
synced 2026-06-26 21:32:42 +03:00
Initial SHA256 test harness
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
build/*
|
||||||
|
!build/Debug/
|
||||||
|
build/Debug/*
|
||||||
|
!build/Debug/*.exe
|
||||||
|
!build/Debug/*.dll
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.20)
|
||||||
|
project(sha256_client_c LANGUAGES C)
|
||||||
|
|
||||||
|
if(NOT WIN32)
|
||||||
|
message(FATAL_ERROR "This sample is intended for Win64 (DLL import).")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_executable(sha256_client
|
||||||
|
src/main.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(sha256_client PRIVATE
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(sha256_client PRIVATE
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/dll/sha-256.lib
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_command(TARGET sha256_client POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/dll/sha-256.dll
|
||||||
|
$<TARGET_FILE_DIR:sha256_client>/sha-256.dll
|
||||||
|
)
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,48 @@
|
|||||||
|
#ifndef SHA256_SHA_H
|
||||||
|
#define SHA256_SHA_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#ifdef SHA256_EXPORTS
|
||||||
|
#define SHA256_API __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define SHA256_API __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define SHA256_API
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef uint32_t sha256_digest_t[8];
|
||||||
|
|
||||||
|
SHA256_API int TestHello(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns NULL (0) on success according to assembly comments.
|
||||||
|
* data_addr - pointer to current data chunk.
|
||||||
|
* full_size - total message/file size in bytes.
|
||||||
|
* current_size - current chunk size in bytes.
|
||||||
|
* digest - 32-byte state/result buffer (8 x uint32_t).
|
||||||
|
* is_last_chunk - 1 if this is the last chunk, otherwise 0.
|
||||||
|
*/
|
||||||
|
SHA256_API void *Sha256(
|
||||||
|
const void *data_addr,
|
||||||
|
uint64_t full_size,
|
||||||
|
uint64_t current_size,
|
||||||
|
sha256_digest_t digest,
|
||||||
|
uint64_t is_last_chunk
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Initializes digest and internal K constants. */
|
||||||
|
SHA256_API void Sha256Init(sha256_digest_t digest);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SHA256_SHA_H */
|
||||||
+95
@@ -0,0 +1,95 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "sha.h"
|
||||||
|
|
||||||
|
static void print_digest_words(const sha256_digest_t digest) {
|
||||||
|
for (int i = 0; i < 8; ++i) {
|
||||||
|
printf("%08x", digest[i]);
|
||||||
|
}
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
char path[4096] = {0};
|
||||||
|
sha256_digest_t digest = {0};
|
||||||
|
|
||||||
|
if (fgets(path, (int)sizeof(path), stdin) == NULL) {
|
||||||
|
fprintf(stderr, "Failed to read file path from stdin\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
path[strcspn(path, "\r\n")] = '\0';
|
||||||
|
if (path[0] == '\0') {
|
||||||
|
fprintf(stderr, "Empty file path\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *fp = fopen(path, "rb");
|
||||||
|
if (fp == NULL) {
|
||||||
|
fprintf(stderr, "Failed to open file: %s\n", path);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_fseeki64(fp, 0, SEEK_END) != 0) {
|
||||||
|
fprintf(stderr, "Failed to seek file end: %s\n", path);
|
||||||
|
fclose(fp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const long long file_size_ll = _ftelli64(fp);
|
||||||
|
if (file_size_ll < 0) {
|
||||||
|
fprintf(stderr, "Failed to get file size: %s\n", path);
|
||||||
|
fclose(fp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_fseeki64(fp, 0, SEEK_SET) != 0) {
|
||||||
|
fprintf(stderr, "Failed to seek file start: %s\n", path);
|
||||||
|
fclose(fp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint64_t full_size = (uint64_t)file_size_ll;
|
||||||
|
size_t alloc_size = (size_t)full_size;
|
||||||
|
if ((uint64_t)alloc_size != full_size) {
|
||||||
|
fprintf(stderr, "File is too large for this client: %s\n", path);
|
||||||
|
fclose(fp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (alloc_size == 0) {
|
||||||
|
alloc_size = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *data = (unsigned char *)malloc(alloc_size);
|
||||||
|
if (data == NULL) {
|
||||||
|
fprintf(stderr, "Out of memory while reading: %s\n", path);
|
||||||
|
fclose(fp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (full_size > 0) {
|
||||||
|
const size_t read_size = fread(data, 1, (size_t)full_size, fp);
|
||||||
|
if (read_size != (size_t)full_size) {
|
||||||
|
fprintf(stderr, "Failed to read file: %s\n", path);
|
||||||
|
free(data);
|
||||||
|
fclose(fp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
void *rc = Sha256(data, full_size, full_size, digest, 1);
|
||||||
|
free(data);
|
||||||
|
if (rc != 0) {
|
||||||
|
fprintf(stderr, "Sha256 failed, rc=%p\n", rc);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Digest (library word order): ");
|
||||||
|
print_digest_words(digest);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user