chiark / gitweb /
Multiarch: Move .so's to triplet paths, and declare M-A: same.
[chiark-tcl.git] / crypto / hash.c
1 /*
2  * crypto - Tcl bindings for parts of the `nettle' crypto library
3  * Copyright 2006-2012 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, see <http://www.gnu.org/licenses/>.
17  */
18
19
20 #include "chiark_tcl_crypto.h"
21
22 typedef struct {
23   int ix;
24   const HashAlgInfo *alg;
25   Byte d[1];
26 } HashState;
27
28 int cht_do_hbcrypto_hash(ClientData cd, Tcl_Interp *ip, const HashAlgInfo *alg,
29                    HBytes_Value message, HBytes_Value *result) {
30   Byte *dest;
31
32   dest= cht_hb_arrayspace(result,alg->hashsize);
33   alg->oneshot(dest, cht_hb_data(&message), cht_hb_len(&message));
34   return TCL_OK;
35 }
36
37 int cht_do_hbcrypto_hash_init(ClientData cd, Tcl_Interp *ip,
38                               const HashAlgInfo *alg, void **state_r) {
39   HashState *state= TALLOC(sizeof(*state) + alg->statesize - 1);
40   state->ix= -1;
41   state->alg= alg;
42   alg->init(state->d);
43   *state_r= state;
44   return TCL_OK;
45 }
46
47 int cht_do_hbcrypto_hash_update(ClientData cd, Tcl_Interp *ip,
48                                 void *state_v, HBytes_Value data) {
49   HashState *state= state_v;
50   state->alg->update(&state->d, cht_hb_data(&data), cht_hb_len(&data));
51   return TCL_OK;
52 }
53
54 int cht_do_hbcrypto_hash_final(ClientData cd, Tcl_Interp *ip,
55                                void *state_v, HBytes_Value *result) {
56   HashState *state= state_v;
57   Byte *digest;
58
59   digest= cht_hb_arrayspace(result,state->alg->hashsize);
60   state->alg->final(&state->d, digest);
61   return cht_do_hbcrypto_hash_discard(cd,ip,state_v);
62 }
63
64 int cht_do_hbcrypto_hash_discard(ClientData cd, Tcl_Interp *ip,
65                                  void *state_v) {
66   cht_tabledataid_disposing(ip,state_v,&cht_hash_states);
67   free(state_v);
68   return TCL_OK;
69 }
70
71 int cht_do_hbcrypto_hash_clonestate(ClientData cd, Tcl_Interp *ip,
72                                     void *old_v, void **new_r) {
73   HashState *old= old_v;
74   int len= sizeof(*old) + old->alg->statesize - 1;
75   void *new_v= TALLOC(len);
76   memcpy(new_v, old, len);
77   ((HashState*)new_v)->ix= -1;
78   *new_r= new_v;
79   return TCL_OK;
80 }
81
82
83 static void destroy_idtabcb(Tcl_Interp *ip, void *state_v) {
84   free(state_v);
85 }
86
87 const IdDataSpec cht_hash_states= {
88   "hashstate", "hashstate-table", destroy_idtabcb
89 };