chiark / gitweb /
hbcrypto hash-{init,update,final} for incremental hashing
authorian <ian>
Wed, 10 Jan 2007 22:34:54 +0000 (22:34 +0000)
committerian <ian>
Wed, 10 Jan 2007 22:34:54 +0000 (22:34 +0000)
crypto/Makefile
crypto/crypto.c
crypto/crypto.h
crypto/crypto.tct
crypto/hash.c [new file with mode: 0644]
crypto/hook.c
debian/changelog

index dfdf719..2fb7bd3 100644 (file)
@@ -19,7 +19,7 @@
 
 BASE_DIR =     ../base
 EXTBASE =      crypto
-CFILES =       algtables bcmode crypto hook
+CFILES =       algtables bcmode crypto hook hash
 OTHER_TCTS =   ../hbytes/hbytes-base.tct
 OTHER_EXTS =   hbytes/hbytes
 LDLIBS +=      -lnettle
index ee89f0e..a926def 100644 (file)
@@ -147,15 +147,6 @@ int cht_do_padmethodinfo_pkcs5(ClientData cd, Tcl_Interp *ip, int *ok) {
   return TCL_OK;
 }
 
-int cht_do_hbcrypto_hash(ClientData cd, Tcl_Interp *ip, const HashAlgInfo *alg,
-                  HBytes_Value message, HBytes_Value *result) {
-  Byte *dest;
-
-  dest= cht_hb_arrayspace(result,alg->hashsize);
-  alg->oneshot(dest, cht_hb_data(&message), cht_hb_len(&message));
-  return TCL_OK;
-}
-
 #define OBJ_CIPHKEY(o) ((CiphKeyValue*)(o)->internalRep.otherValuePtr)
 
 typedef struct {
index b2a7bc8..ce98da1 100644 (file)
@@ -99,6 +99,7 @@ typedef struct {
                     const void *sch);
 } BlockCipherModeInfo;
 
+extern const IdDataSpec cht_hash_states;
 extern const BlockCipherModeInfo cht_blockciphermodeinfo_entries[];
 
 #include "crypto+tcmdif.h"
index 1f0a254..b983af5 100644 (file)
@@ -35,6 +35,20 @@ Table hbcrypto HBCrypto_SubCommand
                alg     enum(HashAlgInfo/, "hash alg")
                message hb
                =>      hb
+       hash-init
+               alg     enum(HashAlgInfo/, "hash alg")
+               =>      iddata(&cht_hash_states)
+       hash-update
+               stateh  iddata(&cht_hash_states)
+               message hb
+       hash-final
+               stateh  iddata(&cht_hash_states)
+               =>      hb
+       hash-discard
+               stateh  iddata(&cht_hash_states)
+       hash-clonestate
+               stateh  iddata(&cht_hash_states)
+               =>      iddata(&cht_hash_states)
        hmac
                alg     enum(HashAlgInfo/, "hash alg for hmac")
                message hb
diff --git a/crypto/hash.c b/crypto/hash.c
new file mode 100644 (file)
index 0000000..7c53b01
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * crypto - Tcl bindings for parts of the `nettle' crypto library
+ * Copyright 2006 Ian Jackson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+
+#include "chiark_tcl_crypto.h"
+
+typedef struct {
+  int ix;
+  const HashAlgInfo *alg;
+  Byte d[1];
+} HashState;
+
+int cht_do_hbcrypto_hash(ClientData cd, Tcl_Interp *ip, const HashAlgInfo *alg,
+                  HBytes_Value message, HBytes_Value *result) {
+  Byte *dest;
+
+  dest= cht_hb_arrayspace(result,alg->hashsize);
+  alg->oneshot(dest, cht_hb_data(&message), cht_hb_len(&message));
+  return TCL_OK;
+}
+
+int cht_do_hbcrypto_hash_init(ClientData cd, Tcl_Interp *ip,
+                             const HashAlgInfo *alg, void **state_r) {
+  HashState *state= TALLOC(sizeof(*state) + alg->statesize - 1);
+  state->ix= -1;
+  state->alg= alg;
+  alg->init(state->d);
+  *state_r= state;
+  return TCL_OK;
+}
+
+int cht_do_hbcrypto_hash_update(ClientData cd, Tcl_Interp *ip,
+                               void *state_v, HBytes_Value data) {
+  HashState *state= state_v;
+  state->alg->update(&state->d, cht_hb_data(&data), cht_hb_len(&data));
+  return TCL_OK;
+}
+
+int cht_do_hbcrypto_hash_final(ClientData cd, Tcl_Interp *ip,
+                              void *state_v, HBytes_Value *result) {
+  HashState *state= state_v;
+  Byte *digest;
+
+  digest= cht_hb_arrayspace(result,state->alg->hashsize);
+  state->alg->final(&state->d, digest);
+  return cht_do_hbcrypto_hash_discard(cd,ip,state_v);
+}
+
+int cht_do_hbcrypto_hash_discard(ClientData cd, Tcl_Interp *ip,
+                                void *state_v) {
+  cht_tabledataid_disposing(ip,state_v,&cht_hash_states);
+  free(state_v);
+  return TCL_OK;
+}
+
+int cht_do_hbcrypto_hash_clonestate(ClientData cd, Tcl_Interp *ip,
+                                   void *old_v, void **new_r) {
+  HashState *old= old_v;
+  int len= sizeof(*old) + old->alg->statesize - 1;
+  void *new_v= TALLOC(len);
+  memcpy(new_v, old, len);
+  ((HashState*)new_v)->ix= -1;
+  *new_r= new_v;
+  return TCL_OK;
+}
+
+
+static void destroy_idtabcb(Tcl_Interp *ip, void *state_v) {
+  free(state_v);
+}
+
+const IdDataSpec cht_hash_states= {
+  "hashstate", "hashstate-table", destroy_idtabcb
+};
index 8b0a984..4604e01 100644 (file)
@@ -22,5 +22,5 @@
 #include "chiark_tcl_crypto.h"
 
 CHT_INIT(crypto,
-        CHTI_OTHER(hbytes)  CHTI_TYPE(cht_blockcipherkey_type),
+        CHTI_OTHER(hbytes) CHTI_TYPE(cht_blockcipherkey_type),
         CHTI_COMMANDS(cht_hbcryptotoplevel_entries))
index 8f73e75..644a3c5 100644 (file)
@@ -1,5 +1,8 @@
 chiark-tcl (1.0.2) unstable; urgency=low
 
+  New features:
+  * hbcrypto hash-{init,update,final} etc. for incremental hashing.
+
   Bugfixes:
   * Do not adns_cancel in the middle of adns_forallqueries.
   * cdb: When cdbwr update writerecord fails, try to recover the