X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-tcl.git;a=blobdiff_plain;f=hbytes%2Fhbytes.h;h=ac19c8f9cd941f2ac1aa95fcd2a7daee442e601a;hp=ee69928237e7202581091154da3bbe9e41d3cfb4;hb=ac8c0b3b18075ae4273779544eda01c09cfb5145;hpb=2cf1bfc63e73a424f9f3899c204025a8346b38e0 diff --git a/hbytes/hbytes.h b/hbytes/hbytes.h index ee69928..ac19c8f 100644 --- a/hbytes/hbytes.h +++ b/hbytes/hbytes.h @@ -4,6 +4,7 @@ * hbytes raw2h BINARY => hex * hbytes h2raw HEX => binary * + * 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 ...] @@ -12,9 +13,47 @@ * hbytes chopto VAR NEWVARLENGTH => suffix (removed from VAR) * (too short? error) * + * hbytes range VALUE START SIZE => substring (or error) + * hbytes overwrite VAR START VALUE + * hbytes trimleft VALUE removes any leading 0 octets + * hbytes repeat VALUE COUNT => COUNT copies of VALUE + * + * hbytes clockincrement VAR INTEGER adds INTEGER to VAR mod 256^|VAR| + * INTEGER must be -255 .. 255 + * => carry (-255 to 255, + * and -1,0,1 if VAR not empty) + * + * hbytes h2ulong HEX => ulong (HEX len must be 4) + * hbytes ulong2h UL => hex + * + * ulong ul2bitfields VALUE [SIZE TYPE [TYPE-ARG...] ...] => 0/1 + * ulong bitfields2ul BASE [SIZE TYPE [TYPE-ARG...] ...] => ULONG + * goes from left (MSbit) to right (LSbit) where + * SIZE is size in bits + * TYPE [TYPE-ARGS...] is as below + * zero + * ignore + * fixed ULONG-VALUE + * uint VARNAME/VALUE (VARNAME if ul2bitfields; + * ulong VARNAME/VALUE VALUE if bitfields2ul) + * + * ulong ul2int ULONG => INT can fail if >INT_MAX + * ulong int2ul INT => ULONG can fail if <0 + * + * hbytes shift l|r ULONG BITS fails if BITS >32 + * hbytes mask A B => A & B + * + * hbytes compare A B + * => -2 A is lexically earlier than B and not a prefix of B (A 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 blockcipher mac MSG ALG KEY MODE IV => final block * * hbytes hash ALG MESSAGE => hash * hbytes hmac ALG MESSAGE KEY [MACLENGTH] => mac @@ -27,6 +66,13 @@ #include #include +#include +#include +#include +#include +#include +#include +#include #include @@ -34,6 +80,8 @@ 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) @@ -77,7 +125,7 @@ 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(HBytes_Value *frees); +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 @@ -87,10 +135,40 @@ void hbytes_free(HBytes_Value *frees); /* 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 dgramsockid_type; +typedef struct DgramSocket *DgramSockID; + /* 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); + +void obj_updatestr_vstringls(Tcl_Obj *o, ...); + /* const char*, int, const char*, int, ..., (const char*)0 */ +void obj_updatestr_string_len(Tcl_Obj *o, const char *str, int l); +void obj_updatestr_string(Tcl_Obj *o, const char *str); /* from parse.c */ @@ -102,6 +180,11 @@ typedef struct { void fini_hbv(Tcl_Interp *ip, int rc, HBytes_Var *agg); /* from chop.c */ + /* only do_... functions declared in tables.h */ + +/* from ulong.c */ + +Tcl_ObjType ulong_type; /* from enum.c */ @@ -113,7 +196,7 @@ const void *enum_lookup_cached_func(Tcl_Interp *ip, Tcl_Obj *o, 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*. @@ -128,21 +211,85 @@ int enum1_lookup_cached_func(Tcl_Interp *ip, Tcl_Obj *o, /* from crypto.c */ +void memxor(Byte *dest, const Byte *src, int l); + +typedef struct { + const char *name; + int pad, use_algname; +} PadMethod; + +extern Tcl_ObjType blockcipherkey_type; + +/* from algtables.c */ + typedef struct { - int blocksize, hashsize; + const char *name; + int hashsize, blocksize, statesize; + void (*init)(void *state); + void (*update)(void *state, const void *data, int len); + void (*final)(void *state, void *digest); + void (*oneshot)(void *digest, const void *data, int len); } HashAlgInfo; +extern const HashAlgInfo hashalginfos[]; + typedef struct { - int blocksize; + void (*make_schedule)(void *schedule, const void *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 */ +} BlockCipherPerDirectionInfo; + +typedef struct { + const char *name; + int blocksize, schedule_size, key_min, key_max; + void (*byteswap)(void *block); + BlockCipherPerDirectionInfo encrypt, decrypt; } BlockCipherAlgInfo; +extern const BlockCipherAlgInfo blockcipheralginfos[]; + +/* from bcmode.c */ + typedef struct { - int dummy; + const char *name; + int iv_blocks, buf_blocks, mac_blocks; + + /* Each function is allowed to use up to buf_blocks * blocksize + * bytes of space in buf. data is blocks * blocksize bytes + * long. data should be modified in place by encrypt and decrypt; + * modes may not change the size of data. iv is always provided and + * is always of length iv_blocks * blocksize; encrypt and + * decrypt may modify the iv value (in which case the Tcl caller + * will get the modified IV) but this is not recommended. mac + * should leave the mac, which must be mac_blocks * blocksize + * bytes, in buf. (Therefore mac_blocks must be at least + * buf_blocks.) + */ + const char *(*encrypt)(Byte *data, int nblocks, + const Byte *iv, Byte *buf, + const BlockCipherAlgInfo *alg, int encr, + const void *sch); + const char *(*decrypt)(Byte *data, int nblocks, + const Byte *iv, Byte *buf, + const BlockCipherAlgInfo *alg, int encr, + const void *sch); + const char *(*mac)(const Byte *data, int nblocks, + const Byte *iv, Byte *buf, + const BlockCipherAlgInfo *alg, + const void *sch); } BlockCipherModeInfo; +extern const BlockCipherModeInfo blockciphermodeinfos[]; + +/* from misc.c */ + +int setnonblock(int fd, int isnonblock); + /* useful macros */ #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)))