X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-tcl.git;a=blobdiff_plain;f=hbytes%2Fhbytes.h;h=b49301f02a935950b0c9a17c725ce395dde0671e;hp=23cad209c11840758e99052d62198efd632bca04;hb=9b2c18cc9d122b45f9e737864921d32baa599f0c;hpb=29d695bbfb0f42019af456fc8a7a3137e9745806 diff --git a/hbytes/hbytes.h b/hbytes/hbytes.h index 23cad20..b49301f 100644 --- a/hbytes/hbytes.h +++ b/hbytes/hbytes.h @@ -15,10 +15,44 @@ * * hbytes range VALUE START SIZE => substring (or error) * hbytes overwrite VAR START VALUE + * hbytes trimleft VAR removes any leading 0 octets * hbytes repeat VALUE COUNT => COUNT copies of VALUE + * hbytes zeroes COUNT => COUNT zero bytes + * hbytes random COUNT => COUNT random bytes + * hbytes xor VAR VALUE $VAR (+)= VALUE * - * hbytes h2ulong HEX => ulong (HEX len must be 4) - * hbytes ulong2h UL => hex + * hbytes ushort2h LONG => LONG must be <2^16, returns as hex + * hbytes h2ushort HEX => |HEX| must be 2 bytes, returns as ulong + * + * hbytes compare A B + * => -2 A is lexically earlier than B and not a prefix of B (A worked? (always 1 for p) + * hbytes pad pn|un VAR BS METH [METHARGS] => worked? (always 1 for p) + * hbytes pad pa|pn VAR ALG|BS pkcs5 => 1 + * hbytes pad ua|un VAR ALG|BS pkcs5 => worked? + * hbytes pad pa|pn VAR ALG|BS rfc2406 NXTHDR => 1 + * hbytes pad ua|un VAR ALG|BS rfc2406 NXTHDRVAR => worked? + * + * hbytes blockcipher d|e VAR ALG KEY MODE [IV] => IV + * hbytes blockcipher mac MSG ALG KEY MODE IV => final block + * hbytes blockcipher prop PROPERTY ALG => property value + * + * hbytes hash ALG MESSAGE => hash + * hbytes hmac ALG MESSAGE KEY [MACLENGTH] => mac + * hbytes hash-prop PROPERTY ALG => property value + * + * ulong ul2int ULONG => INT can fail if >INT_MAX + * ulong int2ul INT => ULONG can fail if <0 + * ulong mask A B => A & B + * ulong add A B => A + B (mod 2^32) + * ulong subtract A B => A - B (mod 2^32) + * ulong compare A B => 0 -1 (AB) + * ulong shift l|r ULONG BITS fails if BITS >32 * * ulong ul2bitfields VALUE [SIZE TYPE [TYPE-ARG...] ...] => 0/1 * ulong bitfields2ul BASE [SIZE TYPE [TYPE-ARG...] ...] => ULONG @@ -31,25 +65,44 @@ * 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 mask-map lookup MAP-VAR ADDRESS [DEFAULT] => DATA + * error on missing default or if any prefix longer than address + * hbytes mask-map amend MAP-VAR PREFIX PREFIX-LENGTH DATA + * a maskmap MAP is [list [list PREFIX PREFIX-LENGTH DATA]] sorted + * first by descending PREFIX-LENGTH and then by ascending PREFIX + * each PREFIX _in the map_ is truncated to the shortest number of + * pairs of hex digits which can represent it * - * hbytes shift l|r ULONG BITS fails if BITS >32 - * hbytes mask A B => A & B + * Error codes * - * 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 KEY MODE [IV] => IV - * - * hbytes hash ALG MESSAGE => hash - * hbytes hmac ALG MESSAGE KEY [MACLENGTH] => mac + * HBYTES BLOCKCIPHER CRYPTFAIL CRYPT block cipher mode failed somehow (!) + * HBYTES BLOCKCIPHER CRYPTFAIL MAC HMAC failed somehow (!) + * HBYTES BLOCKCIPHER LENGTH block cipher input has unsuitable length + * HBYTES BLOCKCIPHER PARAMS key or iv not suitable + * HBYTES HMAC PARAMS key, input or output size not suitable + * HBYTES LENGTH OVERRUN block too long + * HBYTES LENGTH RANGE input length or offset is -ve or silly + * HBYTES LENGTH UNDERRUN block too short (or offset too big) + * HBYTES LENGTH MISMATCH when blocks must be exactly same length + * HBYTES SYNTAX supposed hex block had wrong syntax + * HBYTES VALUE OVERFLOW value to be conv'd to hex too big/long + * HBYTES MASKMAP NOMATCH no addr/mask matches address for lookup + * HBYTES MASKMAP UNDERRUN addr value for lookup is too short + * HBYTES MASKMAP SYNTAX LLENGTH value for mask-map entry not llength==3 + * HBYTES MASKMAP SYNTAX UNDERRUN value for mask-map entry hex too short + * HBYTES MASKMAP SYNTAX OVERRUN actual mask-map entry hex too short + * HBYTES MASKMAP SYNTAX ORDER actual mask-map is disordered + * HBYTES MASKMAP SYNTAX EXCLBITS mask-map has 1-bits outside prefix len + * SOCKADDR AFUNIX LENGTH path for AF_UNIX socket too long + * SOCKADDR SYNTAX IPV4 bad IPv4 socket address &/or port + * SOCKADDR SYNTAX OTHER bad socket addr, couldn't tell what kind + * ULONG BITCOUNT NEGATIVE -ve bitcount specified where not allowed + * ULONG BITCOUNT OVERRUN attempt to use more than 32 bits + * ULONG BITCOUNT UNDERRUN bitfields add up to less than 32 + * ULONG VALUE NEGATIVE attempt convert -ve integers to ulong + * ULONG VALUE OVERFLOW converted value does not fit in result + * TUNTAP IFNAME LENGTH tun/tap interface name too long + * TUNTAP MTU OVERRUN tun/tap mtu limited to 2^16 bytes * * Refs: HMAC: RFC2104 */ @@ -67,7 +120,9 @@ #include #include -#include +#include + +#include typedef unsigned char Byte; @@ -142,14 +197,60 @@ int sockaddr_len(const SockAddr_Value*); const struct sockaddr *sockaddr_addr(const SockAddr_Value*); void sockaddr_free(const SockAddr_Value*); +/* from scriptinv.c */ + +typedef struct { /* semi-opaque - read only, and then only where commented */ + Tcl_Interp *ip; /* valid, non-0 and useable if set */ + Tcl_Obj *obj; /* non-0 iff set (but only test for 0/non-0) */ + int llength; +} ScriptToInvoke; + +void scriptinv_init(ScriptToInvoke *si); +int scriptinv_set(ScriptToInvoke *si, Tcl_Interp *ip, Tcl_Obj *newscript); +void scriptinv_cancel(ScriptToInvoke *si); /* then don't invoke */ + /* no separate free function - just cancel */ + +void scriptinv_invoke(ScriptToInvoke *si, int argc, Tcl_Obj **argv); + +/* from idtable.c */ + +typedef struct { + const char *valprefix, *assockey; + void (*destroyitem)(Tcl_Interp *ip, void *val); +} IdDataSpec; + +/* The stored struct must start with a single int, conventionally + * named `ix'. When the struct is returned for the first time ix must + * be -1; on subsequent occasions it must be >=0. ix will be -1 iff + * the struct is registered by the iddatatable machinery. */ + +extern Tcl_ObjType tabledataid_nearlytype; +int tabledataid_parse(Tcl_Interp *ip, Tcl_Obj *o, const IdDataSpec *idds); +void tabledataid_disposing(Tcl_Interp *ip, void *val, const IdDataSpec *idds); + /* call this when you destroy the struct, to remove its name; + * _disposing is idempotent */ + +/* from adns.c */ + +typedef struct { + const char *name; + adns_rrtype number; +} AdnsTclRRTypeInfo; + +extern const IdDataSpec adnstcl_queries, adnstcl_resolvers; + /* from dgram.c */ -extern Tcl_ObjType dgramsockid_type; -typedef struct DgramSocket *DgramSockID; +extern const IdDataSpec dgram_socks; +int newfdposixerr(Tcl_Interp *ip, int fd, const char *m); + +/* from tuntap.c */ + +extern const IdDataSpec tuntap_socks; /* from hook.c */ -int staticerr(Tcl_Interp *ip, const char *m); +int staticerr(Tcl_Interp *ip, const char *m, const char *ec); 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); @@ -166,11 +267,30 @@ void obj_updatestr_string(Tcl_Obj *o, const char *str); /* from parse.c */ typedef struct { - HBytes_Value *hb; Tcl_Obj *obj, *var; + int copied; +} Something_Var; + +void init_somethingv(Something_Var *sth); +void fini_somethingv(Tcl_Interp *ip, int rc, Something_Var *sth); +int pat_somethingv(Tcl_Interp *ip, Tcl_Obj *var, + Something_Var *sth, Tcl_ObjType *type); + +typedef struct { + HBytes_Value *hb; + Something_Var sth; } HBytes_Var; -void fini_hbv(Tcl_Interp *ip, int rc, HBytes_Var *agg); +/* from maskmap.c */ + +typedef struct MaskMap_Value MaskMap_Value; + +typedef struct { + MaskMap_Value *mm; + Something_Var sth; +} MaskMap_Var; + +extern Tcl_ObjType maskmap_type; /* from chop.c */ /* only do_... functions declared in tables.h */ @@ -209,35 +329,39 @@ void memxor(Byte *dest, const Byte *src, int l); typedef struct { const char *name; int pad, use_algname; -} PadMethod; +} PadOp; extern Tcl_ObjType blockcipherkey_type; /* from algtables.c */ +typedef struct { + const char *name; + int int_offset; +} BlockCipherPropInfo, HashAlgPropInfo; + 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); + 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 { - void (*make_schedule)(void *schedule, const Byte *key, int keylen); + 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 */ -} BlockCipherDirectionInfo; +} BlockCipherPerDirectionInfo; typedef struct { const char *name; int blocksize, schedule_size, key_min, key_max; - void (*byteswap)(Byte *block); - BlockCipherDirectionInfo encrypt, decrypt; + BlockCipherPerDirectionInfo encrypt, decrypt; } BlockCipherAlgInfo; extern const BlockCipherAlgInfo blockcipheralginfos[]; @@ -246,16 +370,31 @@ extern const BlockCipherAlgInfo blockcipheralginfos[]; typedef struct { const char *name; - int iv_blocks, buf_blocks; - const char *(*encrypt)(Byte *data, int blocks, + 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, - int blocksize, const void *sch); - const char *(*decrypt)(Byte *data, int blocks, + const void *sch); + const char *(*decrypt)(Byte *data, int nblocks, 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 */ + 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[]; @@ -271,5 +410,6 @@ int setnonblock(int fd, int isnonblock); #define TALLOC(s) ((void*)Tcl_Alloc((s))) #define TFREE(f) (Tcl_Free((void*)(f))) +#define TREALLOC(p,l) ((void*)Tcl_Realloc((void*)(p),(l))) #endif /*HBYTES_H*/