Skip to content

Commit

Permalink
Merge pull request #12 from rafael-santiago/inc-hash-emu
Browse files Browse the repository at this point in the history
Emulate incremental hashing
  • Loading branch information
rafael-santiago authored Sep 6, 2022
2 parents 837e9b2 + 7783e19 commit 8232bce
Show file tree
Hide file tree
Showing 19 changed files with 1,068 additions and 3 deletions.
48 changes: 48 additions & 0 deletions doc/MANUAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ presented here can be built with the command ``hefesto --mk-samples``.
- [HMACs](#hmacs)
- [Poly1305](#poly1305)
- [SipHash](#siphash)
- [Incremental input reading](#incremental-input-reading)
- [Asymmetric stuff](#asymmetric-stuff)
- [The Diffie-Hellman-Merkle key exchange](#the-diffie-hellman-merkle-key-exchange)
- [RSA](#rsa)
Expand Down Expand Up @@ -1750,6 +1751,53 @@ change and you do not have to mind about free the old address (because it was fr

[Back](#contents)

### Incremental input reading

``Kryptos`` does not implement incremental hashing as another libraries. Now you need to have
every bytes that you want to hash in memory. Anyway, it is possible to emulate the incremental
idea. By combining ``kryptos_hash_init``, ``kryptos_hash_update`` and ``kryptos_hash_finalize``.
Take a look:

```c
/*
* Copyright (C) 2022 by Rafael Santiago
*
* This is a free software. You can redistribute it and/or modify under
* the terms of the GNU General Public License version 2.
*
*/
#include <kryptos.h>
#include <stdlib.h>
#include <stdio.h>

int main(void) {
kryptos_task_ctx t, *ktask = &t;
kryptos_u8_t *alpha = (kryptos_u8_t *)"abcdefghijklmnopqrstuvwxyz";
kryptos_hash_init(sha3_512, ktask);
while (*alpha != 0) {
kryptos_hash_update(ktask, alpha, 2);
alpha += 2;
}
kryptos_hash_finalize(ktask, 1);
printf("SHA3-512 hex result = %s\n", ktask->out);
kryptos_task_free(ktask, KRYPTOS_TASK_OUT);
return EXIT_SUCCESS;
}
```
So it is just about informing ``kryptos`` what hash primitive you are intending to use through ``kryptos_hash_init``.
After that to pass the incremental input bytes by specifying how many byte there are currently into this buffer by
using ``kryptos_hash_update``. Once all bytes passed it is just about calling ``kryptos_hash_finalize``.
The second parameter of macro ``kryptos_hash_finalize`` is about hexadecimal output requesting. When a binary output
is wanted just pass zero on it.
For hash primitives that support variable size hashes and/or keyed hashing, you must configure those parameters
before calling the finalization macro. I meant set ``out_size`` and/or ``key`` and ``key_size`` fields from the
related task context.
[Back](#contents)
## Asymmetric stuff
Until now the ``Diffie-Hellman-Merkle`` key exchange scheme and the algorithms ``RSA`` and ``Elgamal`` are available.
Expand Down
10 changes: 8 additions & 2 deletions doc/todo.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
(A) Try to give support to GMP on multiprecision stuff when asked by the user. +Improvement
(B) Implement a way of using incremental hashing without screwing up
the general straightforward, non-acrobatic current way of hashing data. +NewFeature,+HashFunction,+Improvement
(B) Implement OCB mode of operation. +NewFeature,+BlockCipher,+AuthEnc
x (B) Implement samples for kryptos_hash_init, kryptos_hash_update and kryptos_hash_finalize. +NewFeature,+Sample101
x (A) Document kryptos_hash_init, kryptos_hash_update and kryptos_hash_finalize macros. +NewFeature,+Documentation
x (B) Implement a way of automating incremental hashing unit tests for all available hash functions by using its
standard test vectors. +Tests,+Completeness
x (B) Implement realloc behavior checking test. +Tests,+Completeness
x (B) Verifiy is the library is emulating the standard realloc behavior into Windows Kernel based code. +Question
x (B) Implement a way of using incremental hashing without screwing up
the general straightforward, non-acrobatic current way of hashing data. +NewFeature,+HashFunction,+Improvement
x (A) Enable TWOFISH/128-192-256 HMAC, they were implemented but are not running [user and kernel]. +Tests,+Completeness
x (A) Document BLAKE3 support features. +Documentation
x (A) Enable BLAKE3 kernel tests. +Tests
Expand Down
11 changes: 11 additions & 0 deletions src/kryptos.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@
#include <kryptos_blake2.h>
#include <kryptos_blake3.h>

#include <kryptos_hash_common.h>

#include <kryptos_djb2.h>

#include <kryptos_base64.h>
Expand Down Expand Up @@ -668,4 +670,13 @@ kryptos_ ## label_name:\
(ktask)->mirror_p = NULL;\
}

#define kryptos_hash_init(hname, ktask) {\
kryptos_task_init_as_null(ktask);\
(ktask)->arg[0] = (void *)kryptos_ ## hname ## _hash;\
}

#define kryptos_hash_update(ktask, in, in_size) kryptos_hash_do_update(&(ktask), (in), (in_size))

#define kryptos_hash_finalize(ktask, hex) kryptos_hash_do_finalize(&(ktask), (hex))

#endif // KRYPTOS_KRYPTOS_H
68 changes: 68 additions & 0 deletions src/kryptos_hash_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*
*/
#include <kryptos_hash_common.h>
#include <kryptos_memory.h>
#ifndef KRYPTOS_KERNEL_MODE
# include <string.h>
#endif
Expand Down Expand Up @@ -86,3 +87,70 @@ void kryptos_hash_ld_u8buf_as_u64_blocks(kryptos_u8_t *buffer, const size_t buff
input[i] = input[i] << 8 | buffer[b];
}
}

void kryptos_hash_do_update(kryptos_task_ctx **ktask, const kryptos_u8_t *input, const size_t input_size) {
kryptos_u8_t *in = NULL;
size_t in_size = 0;

if (ktask == NULL || input == NULL || (*ktask)->arg[0] == NULL) {
if (ktask != NULL) {
(*ktask)->result = kKryptosInvalidParams;
(*ktask)->result_verbose = "Invalid parameters.";
}
return;
}

in = (*ktask)->in;
in_size = (*ktask)->in_size + input_size;

if (in == NULL) {
in = (kryptos_u8_t *)kryptos_newseg(in_size);
} else {
in = (kryptos_u8_t *)kryptos_realloc(in, in_size);
}

if (in == NULL) {
(*ktask)->result = kKryptosProcessError;
(*ktask)->result_verbose = "No memory to (re)alloc task input buffer.";
return;
}

memcpy(in + (*ktask)->in_size, input, input_size);

(*ktask)->in = in;
(*ktask)->in_size = in_size;
(*ktask)->result = kKryptosSuccess;
in = NULL;
in_size = 0;
}

void kryptos_hash_do_finalize(kryptos_task_ctx **ktask, const int to_hex) {
kryptos_hash_func h = NULL;
int input_is_null = 0;

if (ktask == NULL || (*ktask)->arg[0] == NULL) {
if (ktask != NULL) {
(*ktask)->result = kKryptosInvalidParams;
(*ktask)->result_verbose = "Null hash function.";
}
return;
}

input_is_null = ((*ktask)->in == NULL && (*ktask)->in_size == 0);
if (input_is_null) {
(*ktask)->in = (kryptos_u8_t *)"";
}

h = (kryptos_hash_func)(*ktask)->arg[0];
h(ktask, to_hex);
(*ktask)->arg[0] = (void *)h;

if (!input_is_null && (*ktask)->result == kKryptosSuccess) {
kryptos_freeseg((*ktask)->in, (*ktask)->in_size);
}

(*ktask)->in = NULL;
(*ktask)->in_size = 0;

input_is_null = 0;
}
3 changes: 3 additions & 0 deletions src/kryptos_hash_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ void kryptos_hash_ld_u8buf_as_u64_blocks(kryptos_u8_t *buffer, const size_t buff
kryptos_u64_t *input, const size_t input_nr,
const size_t *block_index_decision_table);

void kryptos_hash_do_update(kryptos_task_ctx **ktask, const kryptos_u8_t *input, const size_t input_size);

void kryptos_hash_do_finalize(kryptos_task_ctx **ktask, const int to_hex);

#ifdef __cplusplus
}
Expand Down
2 changes: 1 addition & 1 deletion src/samples/.ivk
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--forgefiles=Arc4Sample.hsl,BlowfishSample.hsl,SerpentSample.hsl,FealSample.hsl,HashSample.hsl,DiffieHellmanMerkleSample.hsl,RsaSample.hsl,ElgamalSample.hsl,DsaSample.hsl,EncodingSample.hsl,PemSample.hsl,FortunaSample.hsl,AesSample.hsl,KdfSample.hsl,BcryptSample.hsl,Poly1305Sample.hsl,SipHashSample.hsl,FiveAesFinalistsSample.hsl,OtpSample.hsl --Arc4Sample-projects=arc4-sample,arc4-c99-sample --BlowfishSample-projects=blowfish-ecb-sample,blowfish-ecb-c99-sample --SerpentSample-projects=serpent-cbc-c99-sample --FealSample-projects=feal-cbc-c99-sample --HashSample-projects=bare-bone-hash-sample,hash-macro-sample,hmac-sample,blake2b-keyed-hash-sample,blake2n-sample,blake3-sample --DiffieHellmanMerkleSample-projects=std-dh-sample,mod-dh-sample,dh-domain-params-sample,dh-domain-params-verify-sample,dh-domain-params-load-sample,ecdh-sample --RsaSample-projects=rsa-mk-key-pair-sample,rsa-schoolbook-sample,rsa-schoolbook-c99-sample,rsa-oaep-c99-sample,rsa-sign-sample,rsa-sign-c99-sample,rsa-emsa-pss-sign-c99-sample --ElgamalSample-projects=elgamal-mk-key-pair-sample,elgamal-schoolbook-c99-sample,elgamal-oaep-c99-sample --DsaSample-projects=dsa-mk-key-pair-sample,dsa-sign-c99-sample,ecdsa-mk-key-pair-sample,ecdsa-sign-c99-sample --EncodingSample-projects=base64-sample,base64-dsl-sample,uuencode-dsl-sample,huffman-sample --PemSample-projects=pem-buffer-put-data-sample,pem-buffer-get-data-sample,pem-buffer-get-mp-data-sample --FortunaSample-projects=fortuna-sample --AesSample-projects=aes-ctr-c99-sample,aes-gcm-c99-sample --KdfSample-projects=hkdf-sample,pbkdf2-sample,argon2-sample --BcryptSample-projects=bcrypt-sample --Poly1305Sample-projects=poly1305-c99-sample,poly1305-bare-bone-sample --SipHashSample-projects=siphash-sum-sample,siphash-as-mac-c99-sample --FiveAesFinalistsSample-projects=5-aes-finalists-sample --OtpSample-projects=hotp-c99-sample,totp-c99-sample --obj-output-dir=o --bin-output-dir=../../samples/ --includes=.. --libraries=../../lib --ldflags=-lkryptos --cflags=-DKRYPTOS_MITIGATE_TIMING_ATTACKS=1,-DKRYPTOS_ENSURE_MEMSET_CLEANUPS=1,-DKRYPTOS_DATA_WIPING_WHEN_FREEING_MEMORY=1
--forgefiles=Arc4Sample.hsl,BlowfishSample.hsl,SerpentSample.hsl,FealSample.hsl,HashSample.hsl,DiffieHellmanMerkleSample.hsl,RsaSample.hsl,ElgamalSample.hsl,DsaSample.hsl,EncodingSample.hsl,PemSample.hsl,FortunaSample.hsl,AesSample.hsl,KdfSample.hsl,BcryptSample.hsl,Poly1305Sample.hsl,SipHashSample.hsl,FiveAesFinalistsSample.hsl,OtpSample.hsl --Arc4Sample-projects=arc4-sample,arc4-c99-sample --BlowfishSample-projects=blowfish-ecb-sample,blowfish-ecb-c99-sample --SerpentSample-projects=serpent-cbc-c99-sample --FealSample-projects=feal-cbc-c99-sample --HashSample-projects=bare-bone-hash-sample,hash-macro-sample,hmac-sample,blake2b-keyed-hash-sample,blake2n-sample,blake3-sample,hash-inc-input-sample --DiffieHellmanMerkleSample-projects=std-dh-sample,mod-dh-sample,dh-domain-params-sample,dh-domain-params-verify-sample,dh-domain-params-load-sample,ecdh-sample --RsaSample-projects=rsa-mk-key-pair-sample,rsa-schoolbook-sample,rsa-schoolbook-c99-sample,rsa-oaep-c99-sample,rsa-sign-sample,rsa-sign-c99-sample,rsa-emsa-pss-sign-c99-sample --ElgamalSample-projects=elgamal-mk-key-pair-sample,elgamal-schoolbook-c99-sample,elgamal-oaep-c99-sample --DsaSample-projects=dsa-mk-key-pair-sample,dsa-sign-c99-sample,ecdsa-mk-key-pair-sample,ecdsa-sign-c99-sample --EncodingSample-projects=base64-sample,base64-dsl-sample,uuencode-dsl-sample,huffman-sample --PemSample-projects=pem-buffer-put-data-sample,pem-buffer-get-data-sample,pem-buffer-get-mp-data-sample --FortunaSample-projects=fortuna-sample --AesSample-projects=aes-ctr-c99-sample,aes-gcm-c99-sample --KdfSample-projects=hkdf-sample,pbkdf2-sample,argon2-sample --BcryptSample-projects=bcrypt-sample --Poly1305Sample-projects=poly1305-c99-sample,poly1305-bare-bone-sample --SipHashSample-projects=siphash-sum-sample,siphash-as-mac-c99-sample --FiveAesFinalistsSample-projects=5-aes-finalists-sample --OtpSample-projects=hotp-c99-sample,totp-c99-sample --obj-output-dir=o --bin-output-dir=../../samples/ --includes=.. --libraries=../../lib --ldflags=-lkryptos --cflags=-DKRYPTOS_MITIGATE_TIMING_ATTACKS=1,-DKRYPTOS_ENSURE_MEMSET_CLEANUPS=1,-DKRYPTOS_DATA_WIPING_WHEN_FREEING_MEMORY=1
40 changes: 40 additions & 0 deletions src/samples/HashSample.hsl
Original file line number Diff line number Diff line change
Expand Up @@ -256,3 +256,43 @@ blake3-sample.epilogue() {
hefesto.project.abort(1);
}
}

project hash-inc-input-sample : toolset $toolset_name : $src, $inc, $cflags, $lib, $ldflags, $appname;

hash-inc-input-sample.preloading() {
$toolset_name = get_app_toolset();
}

hash-inc-input-sample.prologue() {
$src.clear();
$inc.clear();
$cflags.clear();
$lib.clear();
$ldflags.clear();
$appname = "hash-inc-input-sample";
if (hefesto.sys.os_name() == "windows") {
$appname = $appname + ".exe";
}
$src.add_item("hash-inc-input-sample.c");
$inc = hefesto.sys.get_option("includes");
$cflags = hefesto.sys.get_option("cflags");
if ((hefesto.sys.os_name() == "netbsd" || hefesto.sys.os_name() == "windows" || hefesto.sys.os_name() == "sunos") &&
$cflags.index_of("-DNO_KRYPTOS_C99_SUPPORT") == -1) {
# INFO(Rafael): Let's enable c99 capabilities by default.
$cflags.add_item("-std=c99");
}
$lib = hefesto.sys.get_option("libraries");
$ldflags = hefesto.sys.get_option("ldflags");
if ($toolset_name.match("^msvc")) {
setup_sample_msvc_flags($cflags, $ldflags);
} else if (hefesto.sys.os_name() == "windows") {
$ldflags.add_item("-lbcrypt");
}
}

hash-inc-input-sample.epilogue() {
if (hefesto.sys.last_forge_result() != 0) {
hefesto.sys.echo("~~~ ERROR\n");
hefesto.project.abort(1);
}
}
24 changes: 24 additions & 0 deletions src/samples/hash-inc-input-sample.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright (C) 2022 by Rafael Santiago
*
* This is a free software. You can redistribute it and/or modify under
* the terms of the GNU General Public License version 2.
*
*/
#include <kryptos.h>
#include <stdlib.h>
#include <stdio.h>

int main(void) {
kryptos_task_ctx t, *ktask = &t;
kryptos_u8_t *alpha = (kryptos_u8_t *)"abcdefghijklmnopqrstuvwxyz";
kryptos_hash_init(sha3_512, ktask);
while (*alpha != 0) {
kryptos_hash_update(ktask, alpha, 2);
alpha += 2;
}
kryptos_hash_finalize(ktask, 1);
printf("SHA3-512 hex result = %s\n", ktask->out);
kryptos_task_free(ktask, KRYPTOS_TASK_OUT);
return EXIT_SUCCESS;
}
17 changes: 17 additions & 0 deletions src/tests/generic_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -1540,6 +1540,23 @@ CUTE_TEST_CASE(kryptos_memory_tests)
kryptos_allow_ram_swap();
CUTE_TEST_CASE_END

CUTE_TEST_CASE(kryptos_realloc_tests)
char *data = NULL;
data = kryptos_newseg(3);
CUTE_ASSERT(data != NULL);
memcpy(data, "abc", 3);
CUTE_ASSERT(memcmp(data, "abc", 3) == 0);
data = kryptos_realloc(data, 4);
CUTE_ASSERT(data != NULL);
CUTE_ASSERT(memcmp(data, "abc", 3) == 0);
data[3] = 'd';
CUTE_ASSERT(memcmp(data, "abcd", 4) == 0);
data = kryptos_realloc(data, 2);
CUTE_ASSERT(data != NULL);
CUTE_ASSERT(memcmp(data, "ab", 2) == 0);
kryptos_freeseg(data, 2);
CUTE_TEST_CASE_END

CUTE_TEST_CASE(kryptos_gcm_gf_mul_tests)
kryptos_u32_t x[4] = { 0x66E94BD4, 0xEF8A2C3B, 0x884CFA59, 0xCA342B2E };
kryptos_u32_t y[4] = { 0x0388DACE, 0x60B6A392, 0xF328C2B9, 0x71B2FE78 };
Expand Down
2 changes: 2 additions & 0 deletions src/tests/generic_tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,6 @@ CUTE_DECLARE_TEST_CASE(kryptos_u64_rev_tests);

CUTE_DECLARE_TEST_CASE(kryptos_u8_ptr_to_hex_tests);

CUTE_DECLARE_TEST_CASE(kryptos_realloc_tests);

#endif
Loading

0 comments on commit 8232bce

Please sign in to comment.