From: ian Date: Wed, 10 Jan 2007 22:34:54 +0000 (+0000) Subject: hbcrypto hash-{init,update,final} for incremental hashing X-Git-Tag: debian/1.1.1~25 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-tcl.git;a=commitdiff_plain;h=0248879bebf13933d9133d5ac75bb4d1b2af21b1;ds=sidebyside hbcrypto hash-{init,update,final} for incremental hashing --- diff --git a/crypto/Makefile b/crypto/Makefile index dfdf719..2fb7bd3 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -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 diff --git a/crypto/crypto.c b/crypto/crypto.c index ee89f0e..a926def 100644 --- a/crypto/crypto.c +++ b/crypto/crypto.c @@ -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 { diff --git a/crypto/crypto.h b/crypto/crypto.h index b2a7bc8..ce98da1 100644 --- a/crypto/crypto.h +++ b/crypto/crypto.h @@ -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" diff --git a/crypto/crypto.tct b/crypto/crypto.tct index 1f0a254..b983af5 100644 --- a/crypto/crypto.tct +++ b/crypto/crypto.tct @@ -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 index 0000000..7c53b01 --- /dev/null +++ b/crypto/hash.c @@ -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 +}; diff --git a/crypto/hook.c b/crypto/hook.c index 8b0a984..4604e01 100644 --- a/crypto/hook.c +++ b/crypto/hook.c @@ -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)) diff --git a/debian/changelog b/debian/changelog index 8f73e75..644a3c5 100644 --- a/debian/changelog +++ b/debian/changelog @@ -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