chiark / gitweb /
Misc sha32 fixes.
authorDan Sheppard <dan.sheppard.circle@gmail.com>
Fri, 11 Apr 2025 09:23:58 +0000 (10:23 +0100)
committerDan Sheppard <dan.sheppard.circle@gmail.com>
Fri, 11 Apr 2025 09:23:58 +0000 (10:23 +0100)
TODO [new file with mode: 0644]
sha2.c
test_sha2.c

diff --git a/TODO b/TODO
new file mode 100644 (file)
index 0000000..d098b5c
--- /dev/null
+++ b/TODO
@@ -0,0 +1,3 @@
+* "Eventually" inserts
+* Replication
+* Strict locking
diff --git a/sha2.c b/sha2.c
index 9a084ae159b48d1a91d59234c992c6ebd378f2b2..e956672c7224effbd841c35e3da9c57c88c5c224 100644 (file)
--- a/sha2.c
+++ b/sha2.c
@@ -1,6 +1,7 @@
-#include <assert.h>
+#include <stdio.h>
 #include <stdint.h>
 #include <string.h>
+#include "sha2.h"
 
 uint64_t sha256_h_init[8] = {
     0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
@@ -81,8 +82,6 @@ uint64_t sha512_k[80] = {
     0x5fcb6fab3ad6faec, 0x6c44198c4a475817
 };
 
-#define SHA2_MAX_BLOCK_LENGTH 128
-
 static inline int min(int a,int b) { return a<b?a:b; }
 
 static inline uint32_t rot32(uint32_t v, int amt) {
@@ -126,31 +125,6 @@ static inline int be_unpack(uint64_t in, uint8_t **out, int n_in, int n_out,
 #define FLAG_HALFWORD 1  /* Curse you, 512-224 */
 #define FLAG_HMAC     2
 
-struct sha2_variety_t {
-    uint64_t *iv;
-    int bits,words_out;
-    int v_flags;
-};
-
-struct sha2_ctx_t {
-    int variety_idx;
-    struct sha2_variety_t *variety;
-    uint64_t h64[8];
-    uint8_t pending[SHA2_MAX_BLOCK_LENGTH];
-    int pending_len;
-    uint64_t length;
-    int flags;
-    uint8_t k_prime[SHA2_MAX_BLOCK_LENGTH]; /* For HMAC */
-};
-
-#define SHA2_VARIETY_224 0
-#define SHA2_VARIETY_256 1
-#define SHA2_VARIETY_384 2
-#define SHA2_VARIETY_512 3
-#define SHA2_VARIETY_512_256 4
-#define SHA2_VARIETY_512_224 5
-#define SHA2_VARIETY_END 6
-
 struct sha2_variety_t sha2_variety_def[SHA2_VARIETY_END] = {
     {sha224_h_init,32,7,0},  /* SHA224 */
     {sha256_h_init,32,8,0},  /* SHA256 */
@@ -275,25 +249,22 @@ void sha2_more(struct sha2_ctx_t *ctx, uint8_t *data, int len) {
 }
 
 static int sha2_finish_main(struct sha2_ctx_t *ctx, uint8_t *out, int maxlen) {
-    int i,space_bytes,half_here,space_needed,len_bytes,len_offset,
-        block_size,bits,len;
+    int i, half_here, space_needed, len_len, block_size,bits,len;
     signed int pad_length;
-    uint8_t terminal[128],*len_pos;
+    uint8_t terminal[SHA2_MAX_BLOCK_LENGTH*2],*len_pos;
 
     bits = ctx->variety->bits;
     block_size = 2*bits;
-    len_bytes = bits/4; /* 32 => 8; 64 => 16 */
-    space_bytes = block_size - ctx->pending_len;
-    space_needed = 1 + len_bytes;
-    pad_length = space_bytes - space_needed;
-    if(pad_length<0) {
+    len_len = bits/4; /* Length of length field: 32bit => 8by; 64bit => 16by */
+    space_needed = 1 + len_len; /* Need room for 0x80 and the length field */
+    pad_length = block_size - ctx->pending_len - space_needed;
+    if(pad_length<0) { /* Oops, add a block */
         pad_length += block_size;
     }
-    memset(terminal,0,128);
+    memset(terminal,0,SHA2_MAX_BLOCK_LENGTH*2);
     terminal[0] = 0x80;
-    len_offset = 1 + pad_length;
-    len_pos = terminal+len_offset;
-    be_unpack(ctx->length*8,&len_pos,len_bytes,len_bytes,NULL);
+    len_pos = terminal + pad_length + 1; /* gets clobbered by be_unpack */
+    be_unpack(ctx->length*8,&len_pos,len_len,len_len,NULL);
     sha2_more(ctx,terminal,space_needed + pad_length);
     len = 0;
     for(i=0;i<ctx->variety->words_out;i++) {
@@ -342,7 +313,6 @@ static void derive_key(uint8_t *out, int sha2_variety, uint8_t *key, int key_len
         sha2_finish(&ctx,out,SHA2_MAX_BLOCK_LENGTH);
     } else {
         memcpy(out,key,key_len);
-        memset(out+key_len,0,block_size-key_len);
     }
 }
 
index d3ce17c5bb2678590ff866b5fab794e9c6bbdafe..7c7167da4879055bfe4d9dea5bd8821eac681723 100644 (file)
@@ -65,10 +65,26 @@ static void test_trunc() {
     printf("ok test-trunc\n");
 }
 
+#define MAX_LEN 1000
+static void test_lengths() { /* Only useful with valgrind */
+    struct sha2_ctx_t ctx;
+    uint8_t text[MAX_LEN],out[SHA2_MAX_DIGEST_SIZE];
+    int len;
+
+    memset(text,42,MAX_LEN);
+    for(len=0;len<1000;len++) {
+        sha2_init(&ctx,SHA2_VARIETY_512);
+        sha2_more(&ctx,text,len);
+        sha2_finish(&ctx,out,SHA2_MAX_DIGEST_SIZE);
+    }
+}
+
+
 int main() {
     char *dog = "The quick brown fox jumps over the lazy dog";
     char *k = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
 
+    printf("Run me under valgrind too!\n");
     compare("empty-512",SHA2_VARIETY_512,"","cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e",NULL);
     compare("empty-384",SHA2_VARIETY_384,"","38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b",NULL);
     compare("empty-256",SHA2_VARIETY_256,"","e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",NULL);
@@ -81,6 +97,7 @@ int main() {
     compare("dog-224",SHA2_VARIETY_224,dog,"730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525",NULL);
     compare("hmac-512",SHA2_VARIETY_512,dog,"2a31d580d74d604de3dce055477d0a5633411adeafa044e10a2c6cfee6e38df49ed336cb53e3e7fa6bbbf3f107a3067296560be3deb09afcaff9cb98d2169433",k);
     compare("hmac-224",SHA2_VARIETY_224,dog,"610d38da56e06cf7d15bdf1ad83e250ae77ada28b5648036bba614ee",k);
+    test_lengths();
     test_trunc();
     return 0;
 }