chiark / gitweb /
hbcrypto hash-{init,update,final} for incremental hashing
[chiark-tcl.git] / crypto / hash.c
1 /*
2  * crypto - Tcl bindings for parts of the `nettle' crypto library
3  * Copyright 2006 Ian Jackson
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18  * 02110-1301, USA.
19  */
20
21
22 #include "chiark_tcl_crypto.h"
23
24 typedef struct {
25   int ix;
26   const HashAlgInfo *alg;
27   Byte d[1];
28 } HashState;
29
30 int cht_do_hbcrypto_hash(ClientData cd, Tcl_Interp *ip, const HashAlgInfo *alg,
31                    HBytes_Value message, HBytes_Value *result) {
32   Byte *dest;
33
34   dest= cht_hb_arrayspace(result,alg->hashsize);
35   alg->oneshot(dest, cht_hb_data(&message), cht_hb_len(&message));
36   return TCL_OK;
37 }
38
39 int cht_do_hbcrypto_hash_init(ClientData cd, Tcl_Interp *ip,
40                               const HashAlgInfo *alg, void **state_r) {
41   HashState *state= TALLOC(sizeof(*state) + alg->statesize - 1);
42   state->ix= -1;
43   state->alg= alg;
44   alg->init(state->d);
45   *state_r= state;
46   return TCL_OK;
47 }
48
49 int cht_do_hbcrypto_hash_update(ClientData cd, Tcl_Interp *ip,
50                                 void *state_v, HBytes_Value data) {
51   HashState *state= state_v;
52   state->alg->update(&state->d, cht_hb_data(&data), cht_hb_len(&data));
53   return TCL_OK;
54 }
55
56 int cht_do_hbcrypto_hash_final(ClientData cd, Tcl_Interp *ip,
57                                void *state_v, HBytes_Value *result) {
58   HashState *state= state_v;
59   Byte *digest;
60
61   digest= cht_hb_arrayspace(result,state->alg->hashsize);
62   state->alg->final(&state->d, digest);
63   return cht_do_hbcrypto_hash_discard(cd,ip,state_v);
64 }
65
66 int cht_do_hbcrypto_hash_discard(ClientData cd, Tcl_Interp *ip,
67                                  void *state_v) {
68   cht_tabledataid_disposing(ip,state_v,&cht_hash_states);
69   free(state_v);
70   return TCL_OK;
71 }
72
73 int cht_do_hbcrypto_hash_clonestate(ClientData cd, Tcl_Interp *ip,
74                                     void *old_v, void **new_r) {
75   HashState *old= old_v;
76   int len= sizeof(*old) + old->alg->statesize - 1;
77   void *new_v= TALLOC(len);
78   memcpy(new_v, old, len);
79   ((HashState*)new_v)->ix= -1;
80   *new_r= new_v;
81   return TCL_OK;
82 }
83
84
85 static void destroy_idtabcb(Tcl_Interp *ip, void *state_v) {
86   free(state_v);
87 }
88
89 const IdDataSpec cht_hash_states= {
90   "hashstate", "hashstate-table", destroy_idtabcb
91 };