#include "EXTERN.h" #include "perl.h" #include "XSUB.h" /* try to be compatible with older perls */ /* SvPV_nolen() macro first defined in 5.005_55 */ /* this is slow, not threadsafe, but works */ #include "patchlevel.h" #if (PATCHLEVEL == 4) || ((PATCHLEVEL == 5) && (SUBVERSION < 55)) static STRLEN nolen_na; # define SvPV_nolen(sv) SvPV ((sv), nolen_na) #endif #include "aes.h" #include "twofish.c" typedef struct cryptstate { keyInstance ki; cipherInstance ci; } *Crypt__Twofish2; MODULE = Crypt::Twofish2 PACKAGE = Crypt::Twofish2 PROTOTYPES: ENABLE BOOT: { HV * stash = gv_stashpv ("Crypt::Twofish2", 0); newCONSTSUB (stash, "keysize", newSViv (32)); newCONSTSUB (stash, "blocksize", newSViv (16)); newCONSTSUB (stash, "MODE_ECB", newSViv (MODE_ECB)); newCONSTSUB (stash, "MODE_CBC", newSViv (MODE_CBC)); newCONSTSUB (stash, "MODE_CFB1", newSViv (MODE_CFB1)); } Crypt::Twofish2 new(class, key, mode=MODE_ECB) SV * class SV * key int mode CODE: { STRLEN keysize; if (!SvPOK (key)) croak ("key must be a string scalar"); keysize = SvCUR(key); if (keysize != 16 && keysize != 24 && keysize != 32) croak ("wrong key length: key must be 128, 192 or 256 bits long"); if (mode != MODE_ECB && mode != MODE_CBC && mode != MODE_CFB1) croak ("illegal mode: mode must be MODE_ECB, MODE_2 or MODE_CFB1"); Newz(0, RETVAL, 1, struct cryptstate); if (makeKey (&RETVAL->ki, DIR_ENCRYPT, keysize*8, SvPV_nolen(key)) != TRUE) croak ("Crypt::Twofish2: makeKey failed, please report!"); if (cipherInit (&RETVAL->ci, mode, 0) != TRUE) /* no IV supported (yet) */ croak ("Crypt::Twofish2: makeKey failed, please report!"); } OUTPUT: RETVAL SV * encrypt(self, data) Crypt::Twofish2 self SV * data ALIAS: decrypt = 1 CODE: { SV *res; STRLEN size; void *rawbytes = SvPV(data,size); if (size) { if (size % (BLOCK_SIZE >> 3)) croak ("encrypt: datasize not multiple of blocksize (%d bits)", BLOCK_SIZE); RETVAL = NEWSV (0, size); SvPOK_only (RETVAL); SvCUR_set (RETVAL, size); if ((ix ? blockDecrypt : blockEncrypt) (&self->ci, &self->ki, rawbytes, size << 3, (void *)SvPV_nolen(RETVAL)) < 0) croak ("block(De|En)crypt: unknown error, please report"); } else RETVAL = newSVpv ("", 0); } OUTPUT: RETVAL void DESTROY(self) Crypt::Twofish2 self CODE: Safefree(self);