chiark / gitweb /
75ce6c816bf0f86f95fb3ded4d91c2f88cfb7702
[chiark-tcl.git] / hbytes / hbytes.h
1 /*
2  */
3 /*
4  *  hbytes raw2h BINARY                          => hex
5  *  hbytes h2raw HEX                             => binary
6  *
7  *  hbytes prepend VAR [VALUE ...]         = set VAR [concat VALUE ... $VAR]
8  *  hbytes append VAR [VALUE ...]          = set VAR [concat $VAR VALUE ...]
9  *  hbytes concat VAR [VALUE ...]          = set VAR [concat VALUE ...]
10  *  hbytes unprepend VAR PREFIXLENGTH            => prefix (removed from VAR)
11  *  hbytes unappend VAR SUFFIXLENGTH             => suffix (removed from VAR)
12  *  hbytes chopto VAR NEWVARLENGTH               => suffix (removed from VAR)
13  *                                                  (too short? error)
14  *
15  *  hbytes pkcs5 pa|ua VAR ALG                   => worked?  (always 1 for p)
16  *  hbytes pkcs5 pn|un VAR BLOCKSIZE             => worked?  (always 1 for p)
17  *  hbytes blockcipher d|e VAR ALG MODE [IV]     => IV
18  *
19  *  hbytes hash ALG MESSAGE                      => hash
20  *  hbytes hmac ALG MESSAGE KEY [MACLENGTH]      => mac
21  *
22  * Refs: HMAC: RFC2104
23  */
24
25 #ifndef HBYTES_H
26 #define HBYTES_H
27
28 #include <assert.h>
29 #include <stdlib.h>
30
31 #include <tcl.h>
32
33 typedef unsigned char Byte;
34
35 /* from hbytes.c */
36
37 /* Internal representation details: */
38 #define HBYTES_ISEMPTY(hb)    (!(hb)->begin_complex && !(hb)->end_0)
39 #define HBYTES_ISSENTINEL(hb) (!(hb)->begin_complex && (hb)->end_0)
40 #define HBYTES_ISSIMPLE(hb)   ((hb)->begin_complex && (hb)->end_0)
41 #define HBYTES_ISCOMPLEX(hb)  ((hb)->begin_complex && !(hb)->end_0)
42
43 typedef struct {
44   void *begin_complex, *end_0;
45 } HBytes_Value; /* overlays internalRep */
46
47 typedef struct {
48   Byte *dstart; /* always allocated dynamically */
49   int prespace, len, avail;
50   /*        
51    * | SPARE      | USED  | SPARE |
52    * |<-prespace->|<-len->|       |
53    * |            |<----avail---->|
54    *              ^start
55    */
56 } HBytes_ComplexValue; /* pointed to from internalRep.otherValuePtr */
57
58 /* Public interfaces: */
59
60 extern Tcl_ObjType hbytes_type;
61
62 int hbytes_len(const HBytes_Value *v);
63 Byte *hbytes_data(const HBytes_Value *v); /* caller may then modify data! */
64 int hbytes_issentinel(const HBytes_Value *v);
65
66 Byte *hbytes_prepend(HBytes_Value *upd, int el);
67 Byte *hbytes_append(HBytes_Value *upd, int el);
68   /* return value is where to put the data */
69
70 const Byte *hbytes_unprepend(HBytes_Value *upd, int rl);
71 const Byte *hbytes_unappend(HBytes_Value *upd, int rl);
72   /* return value points to the removed data, which remains valid
73    * until next op on the HBytes_Value.  If original value is
74    * shorter than rl or negative, returns 0 and does nothing. */
75
76 void hbytes_empty(HBytes_Value *returns);
77 void hbytes_sentinel(HBytes_Value *returns);
78 void hbytes_array(HBytes_Value *returns, const Byte *array, int l);
79 Byte *hbytes_arrayspace(HBytes_Value *returns, int l);
80 void hbytes_free(HBytes_Value *frees);
81   /* _empty, _sentinel and _array do not free or read the old value;
82    * _free it first if needed.  _free leaves it garbage, so you
83    * have to call _empty to reuse it.  _arrayspace doesn't fill
84    * the array; you get a pointer and must fill it with data
85    * yourself. */
86
87 /* The value made by hbytes_sentinel should not be passed to
88  * anything except HBYTES_IS..., and hbytes_free. */
89
90 /* from hook.c */
91
92 int staticerr(Tcl_Interp *ip, const char *m);
93 void objfreeir(Tcl_Obj *o);
94
95 /* from parse.c */
96
97 typedef struct {
98   HBytes_Value *hb;
99   Tcl_Obj *obj, *var;
100 } HBytes_Var;
101
102 void fini_hbv(Tcl_Interp *ip, int rc, HBytes_Var *agg);
103
104 /* from chop.c */
105
106 /* from enum.c */
107
108 extern Tcl_ObjType enum_nearlytype;
109 extern Tcl_ObjType enum1_nearlytype;
110
111 const void *enum_lookup_cached_func(Tcl_Interp *ip, Tcl_Obj *o,
112                                     const void *firstentry, size_t entrysize,
113                                     const char *what);
114 #define enum_lookup_cached(ip,o,table,what)                     \
115     (enum_lookup_cached_func((ip),(o),                          \
116                              sizeof((table)[0]),&(table)[0],    \
117                              (what)))
118   /* table should be a pointer to an array of structs of size
119    * entrysize, the first member of which should be a const char*.
120    * The table should finish with a null const char *.
121    * On error, 0 is returned and the ip->result will have been
122    * set to the error message.
123    */
124
125 int enum1_lookup_cached_func(Tcl_Interp *ip, Tcl_Obj *o,
126                              const char *opts, const char *what);
127   /* -1 => error */
128
129 /* from crypto.c */
130
131 void memxor(Byte *dest, const Byte *src, int l);
132
133 /* from hash.c */
134
135 typedef struct {
136   int blocksize, hashsize;
137 } HashAlgInfo;
138
139 /* from blockciph.c */
140
141 typedef struct {
142   void (*make_schedule)(void *schedule, const Byte *key, int keylen);
143   void (*crypt)(const void *schedule, const void *in, void *out);
144      /* in and out may be the same, but if they aren't they may not overlap */
145      /* in and out for crypt will have been through block_byteswap */
146 } BlockCipherDirectionInfo;
147
148 typedef struct {
149   const char *name;
150   int blocksize, schedule_size, key_min, key_max;
151   void (*byteswap)(Byte *block);
152   BlockCipherDirectionInfo encrypt, decrypt;
153 } BlockCipherAlgInfo;
154
155 extern const BlockCipherAlgInfo blockcipheralginfos[];
156
157 /* from bcmode.c */
158
159 typedef struct {
160   const char *name;
161   int iv_blocks, buf_blocks;
162   const char *(*encrypt)(Byte *data, int blocks,
163                          const Byte *iv, Byte *buf,
164                          const BlockCipherAlgInfo *alg, int encr,
165                          int blocksize, const void *sch);
166   const char *(*decrypt)(Byte *data, int blocks,
167                          const Byte *iv, Byte *buf,
168                          const BlockCipherAlgInfo *alg, int encr,
169                          int blocksize, const void *sch);
170     /* in each case, *iv is provided, but may be modified */
171 } BlockCipherModeInfo;
172
173 extern const BlockCipherModeInfo blockciphermodeinfos[];
174
175 /* useful macros */
176
177 #define OBJ_HBYTES(o) ((HBytes_Value*)&(o)->internalRep.twoPtrValue)
178
179 #define TALLOC(s) ((void*)Tcl_Alloc((s)))
180 #define TFREE(f) (Tcl_Free((void*)(f)))
181
182 #endif /*HBYTES_H*/