From bc4e7d2673e44826dd768ad7f91c393349da24de Mon Sep 17 00:00:00 2001 From: ian Date: Sun, 1 Sep 2002 22:27:06 +0000 Subject: [PATCH 1/1] Padding works. --- base/chiark-tcl.h | 8 ++++++- base/hook.c | 30 ++++---------------------- base/parse.c | 6 +++++- base/tables-examples.tct | 24 ++++++--------------- crypto/crypto.c | 46 ++++++++++++++++++++++++++++++++++++++-- hbytes/hbytes.h | 8 ++++++- hbytes/hook.c | 30 ++++---------------------- hbytes/parse.c | 6 +++++- 8 files changed, 82 insertions(+), 76 deletions(-) diff --git a/base/chiark-tcl.h b/base/chiark-tcl.h index 75ce6c8..cfc96e9 100644 --- a/base/chiark-tcl.h +++ b/base/chiark-tcl.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 ...] @@ -113,7 +114,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*. @@ -130,6 +131,11 @@ int enum1_lookup_cached_func(Tcl_Interp *ip, Tcl_Obj *o, void memxor(Byte *dest, const Byte *src, int l); +typedef struct { + const char *name; + int pad, use_algname; +} PadMethod; + /* from hash.c */ typedef struct { diff --git a/base/hook.c b/base/hook.c index 08e055d..d6d96d9 100644 --- a/base/hook.c +++ b/base/hook.c @@ -119,33 +119,11 @@ int do_hbytes_h2raw(ClientData cd, Tcl_Interp *ip, return TCL_OK; } -#if 0 -HC_DEFINE(pkcs5) { - static const PadKindInfo padkindinfos[0]= { - { "pa", 1, 1 }, - { "pn", 1, 0 }, - { "ua", 0, 1 }, - { "un", 0, 0 }, - { 0 } - }; - - HC_DECLS_HBV; - Tcl_Obj *v; - int blocksize; - const PadKindInfo *pk; - const BlockCipherInfo *bc; - - HC_ARG_ENUM(pk, padkindinfos); - HC_ARG_HBV; - if (!pk->algname) HC_ARG_INTRANGE(blocksize, 1,255); - else { HC_ARG_ENUM(bc, blockciphers); blocksize= bc->blocksize; } - HC_ARGS_E; - - /* do nothing :-) */ - - HC_FINI_HBV; +int do_hbytes_length(ClientData cd, Tcl_Interp *ip, + HBytes_Value v, int *result) { + *result= hbytes_len(&v); + return TCL_OK; } -#endif int do__hbytes(ClientData cd, Tcl_Interp *ip, const HBytes_SubCommand *subcmd, diff --git a/base/parse.c b/base/parse.c index e5e3465..ddb5ac5 100644 --- a/base/parse.c +++ b/base/parse.c @@ -49,7 +49,7 @@ int pat_hbv(Tcl_Interp *ip, Tcl_Obj *var, HBytes_Var *agg) { void fini_hbv(Tcl_Interp *ip, int rc, HBytes_Var *agg) { Tcl_Obj *ro; - Tcl_InvalidateStringRep(agg->obj); + if (agg->obj) Tcl_InvalidateStringRep(agg->obj); if (!rc) { assert(agg->obj); ro= Tcl_ObjSetVar2(ip,agg->var,0,agg->obj,TCL_LEAVE_ERR_MSG); @@ -75,6 +75,10 @@ Tcl_Obj *ret_hb(Tcl_Interp *ip, HBytes_Value val) { return obj; } +Tcl_Obj *ret_int(Tcl_Interp *ip, int val) { + return Tcl_NewIntObj(val); +} + Tcl_Obj *ret_obj(Tcl_Interp *ip, Tcl_Obj *val) { return val; } diff --git a/base/tables-examples.tct b/base/tables-examples.tct index 13a3e5d..d743530 100644 --- a/base/tables-examples.tct +++ b/base/tables-examples.tct @@ -18,6 +18,9 @@ Table hbytes HBytes_SubCommand h2raw hex hb => obj + length + v hb + => int prepend v hbv str ... @@ -44,7 +47,9 @@ Table hbytes HBytes_SubCommand => hb pkcs5 meth enum(PadMethod, "hbytes pad subcommand") - obj ... + v hbv + block obj + => int # blockcipher # encrypt charfrom("de","encrypt/decrypt") # v hbv @@ -62,20 +67,3 @@ Table hbytes HBytes_SubCommand # key hb # maclen int # => hb - -Table padmethod PadMethod - pa 1 - v hbv - alg enum(BlockCipherAlgInfo, "pad alg") - ua 0 - v hbv - alg enum(BlockCipherAlgInfo, "pad alg") - pn 1 - v hbv - block int - un 0 - v hbv - block int - -EntryExtra PadMethod - int pad; diff --git a/crypto/crypto.c b/crypto/crypto.c index 1866a65..f6f12e1 100644 --- a/crypto/crypto.c +++ b/crypto/crypto.c @@ -11,7 +11,49 @@ void memxor(Byte *dest, const Byte *src, int l) { while (l--) *dest++ ^= *src++; } +const PadMethod padmethods[]= { + { "un", 0, 0 }, + { "ua", 0, 1 }, + { "pn", 1, 0 }, + { "pa", 1, 1 }, + { 0 } +}; + int do_hbytes_pkcs5(ClientData cd, Tcl_Interp *ip, - const PadMethod *meth, int objc, Tcl_Obj *const *objv) { - return meth->func((void*)meth, ip, objc, objv); + const PadMethod *meth, HBytes_Var v, Tcl_Obj *block, + int *ok) { + int rc, blocksize, padlen, old_len, i; + Byte *padding; + const Byte *unpad; + + if (meth->use_algname) { + const BlockCipherAlgInfo *alg; + alg= enum_lookup_cached(ip,block,blockcipheralginfos,"cipher alg for pad"); + if (!alg) return TCL_ERROR; + blocksize= alg->blocksize; + } else { + rc= Tcl_GetIntFromObj(ip, block, &blocksize); if (rc) return rc; + if (blocksize < 1 || blocksize > 255) + return staticerr(ip, "block size out of pkcs#5 range 1..255"); + } + + if (meth->pad) { + padlen= blocksize - (hbytes_len(v.hb) % blocksize); + padding= hbytes_append(v.hb, padlen); + memset(padding, padlen, padlen); + } else { + old_len= hbytes_len(v.hb); if (old_len % blocksize) goto bad; + unpad= hbytes_unappend(v.hb, 1); if (!unpad) goto bad; + padlen= *unpad; + if (padlen < 1 || padlen > blocksize) goto bad; + unpad= hbytes_unappend(v.hb, padlen-1); if (!unpad) goto bad; + for (i=0; i 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 ...] @@ -113,7 +114,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*. @@ -130,6 +131,11 @@ int enum1_lookup_cached_func(Tcl_Interp *ip, Tcl_Obj *o, void memxor(Byte *dest, const Byte *src, int l); +typedef struct { + const char *name; + int pad, use_algname; +} PadMethod; + /* from hash.c */ typedef struct { diff --git a/hbytes/hook.c b/hbytes/hook.c index 08e055d..d6d96d9 100644 --- a/hbytes/hook.c +++ b/hbytes/hook.c @@ -119,33 +119,11 @@ int do_hbytes_h2raw(ClientData cd, Tcl_Interp *ip, return TCL_OK; } -#if 0 -HC_DEFINE(pkcs5) { - static const PadKindInfo padkindinfos[0]= { - { "pa", 1, 1 }, - { "pn", 1, 0 }, - { "ua", 0, 1 }, - { "un", 0, 0 }, - { 0 } - }; - - HC_DECLS_HBV; - Tcl_Obj *v; - int blocksize; - const PadKindInfo *pk; - const BlockCipherInfo *bc; - - HC_ARG_ENUM(pk, padkindinfos); - HC_ARG_HBV; - if (!pk->algname) HC_ARG_INTRANGE(blocksize, 1,255); - else { HC_ARG_ENUM(bc, blockciphers); blocksize= bc->blocksize; } - HC_ARGS_E; - - /* do nothing :-) */ - - HC_FINI_HBV; +int do_hbytes_length(ClientData cd, Tcl_Interp *ip, + HBytes_Value v, int *result) { + *result= hbytes_len(&v); + return TCL_OK; } -#endif int do__hbytes(ClientData cd, Tcl_Interp *ip, const HBytes_SubCommand *subcmd, diff --git a/hbytes/parse.c b/hbytes/parse.c index e5e3465..ddb5ac5 100644 --- a/hbytes/parse.c +++ b/hbytes/parse.c @@ -49,7 +49,7 @@ int pat_hbv(Tcl_Interp *ip, Tcl_Obj *var, HBytes_Var *agg) { void fini_hbv(Tcl_Interp *ip, int rc, HBytes_Var *agg) { Tcl_Obj *ro; - Tcl_InvalidateStringRep(agg->obj); + if (agg->obj) Tcl_InvalidateStringRep(agg->obj); if (!rc) { assert(agg->obj); ro= Tcl_ObjSetVar2(ip,agg->var,0,agg->obj,TCL_LEAVE_ERR_MSG); @@ -75,6 +75,10 @@ Tcl_Obj *ret_hb(Tcl_Interp *ip, HBytes_Value val) { return obj; } +Tcl_Obj *ret_int(Tcl_Interp *ip, int val) { + return Tcl_NewIntObj(val); +} + Tcl_Obj *ret_obj(Tcl_Interp *ip, Tcl_Obj *val) { return val; } -- 2.30.2