chiark / gitweb /
Padding works.
authorian <ian>
Sun, 1 Sep 2002 22:27:06 +0000 (22:27 +0000)
committerian <ian>
Sun, 1 Sep 2002 22:27:06 +0000 (22:27 +0000)
base/chiark-tcl.h
base/hook.c
base/parse.c
base/tables-examples.tct
crypto/crypto.c
hbytes/hbytes.h
hbytes/hook.c
hbytes/parse.c

index 75ce6c816bf0f86f95fb3ded4d91c2f88cfb7702..cfc96e912f9fd994de502e05c69c0f7e57ab04de 100644 (file)
@@ -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 {
index 08e055d6426379687d01c580a3e8caf6e099c121..d6d96d9ce1a406ff4b34b4199415abc0b3fa1040 100644 (file)
@@ -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,
index e5e3465c93c450eea9357c55e35718663ed58f03..ddb5ac5e37ee9efca562f96d8fe91da1ca0994eb 100644 (file)
@@ -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;
 }
index 13a3e5d68a05ab9629c4b254c538eb3e3fab6e51..d74353098edf625ecbacc7d411539fdc32044eb1 100644 (file)
@@ -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;
index 1866a6578504be8232074ecdd19d6f47322b6953..f6f12e1e70c568adeec252ee9379964834f89679 100644 (file)
@@ -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<padlen-1; i++, unpad++) if (*unpad != padlen) goto bad;
+  }
+
+  *ok= 1;
+  return TCL_OK;
+
+ bad:
+  *ok= 0;
+  return TCL_OK;
 }
index 75ce6c816bf0f86f95fb3ded4d91c2f88cfb7702..cfc96e912f9fd994de502e05c69c0f7e57ab04de 100644 (file)
@@ -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 {
index 08e055d6426379687d01c580a3e8caf6e099c121..d6d96d9ce1a406ff4b34b4199415abc0b3fa1040 100644 (file)
@@ -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,
index e5e3465c93c450eea9357c55e35718663ed58f03..ddb5ac5e37ee9efca562f96d8fe91da1ca0994eb 100644 (file)
@@ -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;
 }