X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-tcl.git;a=blobdiff_plain;f=base%2Fchiark-tcl.h;h=951ae12ee3e5d28889ceacab9bb84dcf15ef89a3;hp=f136758fdfe8be32f4d29235cbf45297588887c1;hb=d23a32272b954579fe15c78d6ea605e087d0a512;hpb=49c3802afe7339871a8387c90de3e5ff798d66b1 diff --git a/base/chiark-tcl.h b/base/chiark-tcl.h index f136758..951ae12 100644 --- a/base/chiark-tcl.h +++ b/base/chiark-tcl.h @@ -4,9 +4,10 @@ * hbytes raw2h BINARY => hex * hbytes h2raw HEX => binary * - * hbytes prefix VAR [VALUE ...] = set VAR [concat VALUE ... $VAR] - * hbytes append VAR [VALUE ...] = set VAR [concat $VAR VALUE ...] - * hbytes concat VAR [VALUE ...] = set VAR [concat VALUE ...] + * hbytes length VALUE => count + * hbytes prepend VAR [VALUE ...] = set VAR [concat VALUE ... $VAR] + * hbytes append VAR [VALUE ...] = set VAR [concat $VAR VALUE ...] + * hbytes concat VAR [VALUE ...] = set VAR [concat VALUE ...] * hbytes unprepend VAR PREFIXLENGTH => prefix (removed from VAR) * hbytes unappend VAR SUFFIXLENGTH => suffix (removed from VAR) * hbytes chopto VAR NEWVARLENGTH => suffix (removed from VAR) @@ -14,7 +15,7 @@ * * hbytes pkcs5 pa|ua VAR ALG => worked? (always 1 for p) * hbytes pkcs5 pn|un VAR BLOCKSIZE => worked? (always 1 for p) - * hbytes blockcipher d|e VAR ALG MODE [IV] => IV + * hbytes blockcipher d|e VAR ALG KEY MODE [IV] => IV * * hbytes hash ALG MESSAGE => hash * hbytes hmac ALG MESSAGE KEY [MACLENGTH] => mac @@ -27,6 +28,12 @@ #include #include +#include +#include +#include +#include +#include +#include #include @@ -34,27 +41,112 @@ typedef unsigned char Byte; /* from hbytes.c */ +int Hbytes_Init(Tcl_Interp *ip); /* called by Tcl's "load" */ + +/* Internal representation details: */ +#define HBYTES_ISEMPTY(hb) (!(hb)->begin_complex && !(hb)->end_0) +#define HBYTES_ISSENTINEL(hb) (!(hb)->begin_complex && (hb)->end_0) +#define HBYTES_ISSIMPLE(hb) ((hb)->begin_complex && (hb)->end_0) +#define HBYTES_ISCOMPLEX(hb) ((hb)->begin_complex && !(hb)->end_0) + typedef struct { - Byte *start, *end; /* always allocated dynamically */ + void *begin_complex, *end_0; } HBytes_Value; /* overlays internalRep */ +typedef struct { + Byte *dstart; /* always allocated dynamically */ + int prespace, len, avail; + /* + * | SPARE | USED | SPARE | + * |<-prespace->|<-len->| | + * | |<----avail---->| + * ^start + */ +} HBytes_ComplexValue; /* pointed to from internalRep.otherValuePtr */ + +/* Public interfaces: */ + extern Tcl_ObjType hbytes_type; +int hbytes_len(const HBytes_Value *v); +Byte *hbytes_data(const HBytes_Value *v); /* caller may then modify data! */ +int hbytes_issentinel(const HBytes_Value *v); + +Byte *hbytes_prepend(HBytes_Value *upd, int el); +Byte *hbytes_append(HBytes_Value *upd, int el); + /* return value is where to put the data */ + +const Byte *hbytes_unprepend(HBytes_Value *upd, int rl); +const Byte *hbytes_unappend(HBytes_Value *upd, int rl); + /* return value points to the removed data, which remains valid + * until next op on the HBytes_Value. If original value is + * shorter than rl or negative, returns 0 and does nothing. */ + +void hbytes_empty(HBytes_Value *returns); +void hbytes_sentinel(HBytes_Value *returns); +void hbytes_array(HBytes_Value *returns, const Byte *array, int l); +Byte *hbytes_arrayspace(HBytes_Value *returns, int l); +void hbytes_free(const HBytes_Value *frees); + /* _empty, _sentinel and _array do not free or read the old value; + * _free it first if needed. _free leaves it garbage, so you + * have to call _empty to reuse it. _arrayspace doesn't fill + * the array; you get a pointer and must fill it with data + * yourself. */ + +/* The value made by hbytes_sentinel should not be passed to + * anything except HBYTES_IS..., and hbytes_free. */ + +/* from sockaddr.c */ + +typedef struct { + Byte *begin, *end; +} SockAddr_Value; + +extern Tcl_ObjType sockaddr_type; + +void sockaddr_clear(SockAddr_Value*); +void sockaddr_create(SockAddr_Value*, const struct sockaddr *addr, int len); +int sockaddr_len(const SockAddr_Value*); +const struct sockaddr *sockaddr_addr(const SockAddr_Value*); +void sockaddr_free(const SockAddr_Value*); + +/* from dgram.c */ + +extern Tcl_ObjType sockid_type; + +/* from hook.c */ + int staticerr(Tcl_Interp *ip, const char *m); +int posixerr(Tcl_Interp *ip, int errnoval, const char *m); void objfreeir(Tcl_Obj *o); +int get_urandom(Tcl_Interp *ip, Byte *buffer, int l); + +void obj_updatestr_array(Tcl_Obj *o, const Byte *array, int l); +void obj_updatestr_array_prefix(Tcl_Obj *o, const Byte *byte, + int l, const char *prefix); + +/* from parse.c */ + +typedef struct { + HBytes_Value *hb; + Tcl_Obj *obj, *var; +} HBytes_Var; -Tcl_Obj *hbytes_set(Tcl_Obj *overwrite, const Byte *array, int l); +void fini_hbv(Tcl_Interp *ip, int rc, HBytes_Var *agg); + +/* from chop.c */ /* from enum.c */ extern Tcl_ObjType enum_nearlytype; +extern Tcl_ObjType enum1_nearlytype; const void *enum_lookup_cached_func(Tcl_Interp *ip, Tcl_Obj *o, - size_t entrysize, const void *firstentry, + const void *firstentry, size_t entrysize, const char *what); #define enum_lookup_cached(ip,o,table,what) \ (enum_lookup_cached_func((ip),(o), \ - sizeof((table)[0]),&(table)[0], \ + &(table)[0],sizeof((table)[0]), \ (what))) /* table should be a pointer to an array of structs of size * entrysize, the first member of which should be a const char*. @@ -63,10 +155,76 @@ const void *enum_lookup_cached_func(Tcl_Interp *ip, Tcl_Obj *o, * set to the error message. */ +int enum1_lookup_cached_func(Tcl_Interp *ip, Tcl_Obj *o, + const char *opts, const char *what); + /* -1 => error */ + +/* from crypto.c */ + +void memxor(Byte *dest, const Byte *src, int l); + +typedef struct { + const char *name; + int pad, use_algname; +} PadMethod; + +Tcl_ObjType blockcipherkey_type; + +/* from algtables.c */ + +typedef struct { + const char *name; + int hashsize, blocksize, statesize; + void (*init)(void *state); + void (*update)(void *state, const Byte *data, int len); + void (*final)(void *state, Byte *digest); + void (*oneshot)(Byte *digest, const Byte *data, int len); +} HashAlgInfo; + +extern const HashAlgInfo hashalginfos[]; + +typedef struct { + void (*make_schedule)(void *schedule, const Byte *key, int keylen); + void (*crypt)(const void *schedule, const void *in, void *out); + /* in and out may be the same, but if they aren't they may not overlap */ + /* in and out for crypt will have been through block_byteswap */ +} BlockCipherDirectionInfo; + +typedef struct { + const char *name; + int blocksize, schedule_size, key_min, key_max; + void (*byteswap)(Byte *block); + BlockCipherDirectionInfo encrypt, decrypt; +} BlockCipherAlgInfo; + +extern const BlockCipherAlgInfo blockcipheralginfos[]; + +/* from bcmode.c */ + +typedef struct { + const char *name; + int iv_blocks, buf_blocks; + const char *(*encrypt)(Byte *data, int blocks, + const Byte *iv, Byte *buf, + const BlockCipherAlgInfo *alg, int encr, + int blocksize, const void *sch); + const char *(*decrypt)(Byte *data, int blocks, + const Byte *iv, Byte *buf, + const BlockCipherAlgInfo *alg, int encr, + int blocksize, const void *sch); + /* in each case, *iv is provided, but may be modified */ +} BlockCipherModeInfo; + +extern const BlockCipherModeInfo blockciphermodeinfos[]; + +/* from misc.c */ + +int setnonblock(int fd, int isnonblock); + /* useful macros */ -#define HBYTES(o) ((HBytes_Value*)&(o)->internalRep.twoPtrValue) -#define HBYTES_LEN(o) (HBYTES((o))->end - HBYTES((o))->start) +#define OBJ_HBYTES(o) ((HBytes_Value*)&(o)->internalRep.twoPtrValue) +#define OBJ_SOCKADDR(o) ((SockAddr_Value*)&(o)->internalRep.twoPtrValue) #define TALLOC(s) ((void*)Tcl_Alloc((s))) #define TFREE(f) (Tcl_Free((void*)(f)))