1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4 
5 /* try to be compatible with older perls */
6 /* SvPV_nolen() macro first defined in 5.005_55 */
7 /* this is slow, not threadsafe, but works */
8 #include "patchlevel.h"
9 #if (PATCHLEVEL == 4) || ((PATCHLEVEL == 5) && (SUBVERSION < 55))
10 static STRLEN nolen_na;
11 # define SvPV_nolen(sv) SvPV ((sv), nolen_na)
12 #endif
13 
14 #include "aes.h"
15 #include "twofish.c"
16 
17 typedef struct cryptstate {
18   keyInstance ki;
19   cipherInstance ci;
20 } *Crypt__Twofish2;
21 
22 MODULE = Crypt::Twofish2		PACKAGE = Crypt::Twofish2
23 
24 PROTOTYPES: ENABLE
25 
26 BOOT:
27 {
28 	HV *stash = gv_stashpv ("Crypt::Twofish2", 0);
29 
30 	newCONSTSUB (stash, "keysize",   newSViv (32));
31 	newCONSTSUB (stash, "blocksize", newSViv (16));
32 	newCONSTSUB (stash, "MODE_ECB",  newSViv (MODE_ECB));
33 	newCONSTSUB (stash, "MODE_CBC",  newSViv (MODE_CBC));
34 	newCONSTSUB (stash, "MODE_CFB1", newSViv (MODE_CFB1));
35 }
36 
37 Crypt::Twofish2
38 new(class, key, mode=MODE_ECB)
39 	SV *	class
40 	SV *	key
41         int	mode
42         CODE:
43         {
44           STRLEN keysize;
45 
46           if (!SvPOK (key))
47             croak ("key must be a string scalar");
48 
49           keysize = SvCUR(key);
50 
51           if (keysize != 16 && keysize != 24 && keysize != 32)
52             croak ("wrong key length: key must be 128, 192 or 256 bits long");
53           if (mode != MODE_ECB && mode != MODE_CBC && mode != MODE_CFB1)
54             croak ("illegal mode: mode must be MODE_ECB, MODE_2 or MODE_CFB1");
55 
56           Newz (0, RETVAL, 1, struct cryptstate); /* Newz required for defined IV */
57 
58           if (makeKey (&RETVAL->ki, DIR_ENCRYPT, keysize*8, SvPV_nolen(key)) != TRUE)
59             croak ("Crypt::Twofish2: makeKey failed, please report!");
60           if (cipherInit (&RETVAL->ci, mode, 0) != TRUE) /* no IV supported (yet) */
61             croak ("Crypt::Twofish2: makeKey failed, please report!");
62         }
63 	OUTPUT:
64         RETVAL
65 
66 SV *
encrypt(self,data)67 encrypt(self, data)
68  	Crypt::Twofish2 self
69         SV *	data
70         ALIAS:
71         	decrypt = 1
72         CODE:
73         {
74           SV *res;
75           STRLEN size;
76           void *rawbytes = SvPV(data,size);
77 
78           if (size)
79             {
80               if (size % (BLOCK_SIZE >> 3))
81                 croak ("encrypt: datasize not multiple of blocksize (%d bits)", BLOCK_SIZE);
82 
83               RETVAL = NEWSV (0, size);
84               SvPOK_only (RETVAL);
85               (SvPVX (RETVAL))[size] = 0;
86               SvCUR_set (RETVAL, size);
87 
88               if ((ix ? blockDecrypt : blockEncrypt)
89                     (&self->ci, &self->ki, rawbytes, size << 3, (void *)SvPV_nolen(RETVAL)) < 0)
90                 croak ("block(De|En)crypt: unknown error, please report");
91             }
92           else
93             RETVAL = newSVpv ("", 0);
94         }
95 	OUTPUT:
96         RETVAL
97 
98 void
99 DESTROY(self)
100         Crypt::Twofish2 self
101         CODE:
102         Safefree(self);
103 
104 
105 
106 
107