diff options
author | Franklin Wei <me@fwei.tk> | 2018-06-04 21:37:57 -0400 |
---|---|---|
committer | Franklin Wei <me@fwei.tk> | 2018-06-04 21:37:57 -0400 |
commit | 040a9bab4cafb4dd6ec44485a5c421d99a00cffe (patch) | |
tree | dd0f95ae3d2f6215c0b5380046c8a1d675e3c52e /crypto.c | |
parent | 35d085feee188ef5b6910fe67222fb297c5c6ea6 (diff) | |
download | csaa-040a9bab4cafb4dd6ec44485a5c421d99a00cffe.zip csaa-040a9bab4cafb4dd6ec44485a5c421d99a00cffe.tar.gz csaa-040a9bab4cafb4dd6ec44485a5c421d99a00cffe.tar.bz2 csaa-040a9bab4cafb4dd6ec44485a5c421d99a00cffe.tar.xz |
Restructure; test file creation
sp_test() now shows a bare minimum example of creating a file. Further
improvements are definitely needed.
Diffstat (limited to '')
-rw-r--r-- | crypto.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/crypto.c b/crypto.c new file mode 100644 index 0000000..6039b7f --- /dev/null +++ b/crypto.c @@ -0,0 +1,117 @@ +#include "crypto.h" + +#include <string.h> + +#include <openssl/hmac.h> +#include <openssl/sha.h> + +/* return true iff [b, bprime] encloses a */ +bool encloses(int b, int bprime, int a) +{ + return (b < a && a < bprime) || (bprime <= b && b < a) || (a < bprime && bprime <= b); +} + +hash_t hash_node(const struct iomt_node *node) +{ + return sha256(node, sizeof(*node)); +} + +hash_t hmac_sha256(const void *data, size_t datalen, const void *key, size_t keylen) +{ + hash_t h; + HMAC(EVP_sha256(), key, keylen, data, datalen, h.hash, NULL); + return h; +} + +hash_t sha256(const void *data, size_t datalen) +{ + hash_t h; + SHA256(data, datalen, h.hash); + return h; +} + +bool is_zero(hash_t u) +{ + /* constant-time comparison */ + volatile char c = 0; + for(int i = 0; i < 32; ++i) + c |= u.hash[i]; + + return c == 0; +} + +void dump_hash(hash_t u) +{ + for(int i = 0; i < 32; ++i) + printf("%02x", u.hash[i]); + printf("\n"); +} + +bool hash_equals(hash_t a, hash_t b) +{ + return !memcmp(a.hash, b.hash, 32); +} + +hash_t hash_xor(hash_t a, hash_t b) +{ + for(int i = 0; i < 32; ++i) + a.hash[i] ^= b.hash[i]; + return a; +} + +/* NOTE: we fail to distinguish between intermediate and leaf + * nodes, making a second-preimage attack possible */ +/* order: 0: u is left, v is right, 1: u is right, v is left */ +hash_t merkle_parent(hash_t u, hash_t v, int order) +{ + if(is_zero(u)) + return v; + if(is_zero(v)) + return u; + + /* append and hash */ + SHA256_CTX ctx; + hash_t h; + + SHA256_Init(&ctx); + + if(order != 0) + SHA256_Update(&ctx, v.hash, 32); + + SHA256_Update(&ctx, u.hash, 32); + + if(order == 0) + SHA256_Update(&ctx, v.hash, 32); + + SHA256_Final(h.hash, &ctx); + + return h; +} + +/* Calculate the root of a Merkle tree given the leaf node v, and n + * complementary nodes, ordered from the closest node (the sibling + * leaf node at the bottom of the tree) to most distant (the opposite + * half of the tree). orders[i] represents whether each complementarty + * node is a left or right child, which is necessary to compute the + * proper hash value at each stage. This is the f_bt() algorithm + * described in Mohanty et al. */ + +/* orders: 0 indiciates that the complementary node is LEFT child, 1: + * node is RIGHT child */ +hash_t merkle_compute(hash_t node, const hash_t *comp, const int *orders, size_t n) +{ + hash_t parent = node; + for(size_t i = 0; i < n; ++i) + parent = merkle_parent(comp[i], parent, orders[i]); + + return parent; +} + +/* convert the first 8 bytes (little endian) to a 64-bit int */ +uint64_t hash_to_u64(hash_t h) +{ + uint64_t ret = 0; + for(int i = 0; i < 8; ++i) + ret |= h.hash[i] << (i * 8); + return ret; +} |