- 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;