1 |
root |
1.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 |
root |
1.2 |
HV *stash = gv_stashpv ("Crypt::Twofish2", 0); |
29 |
root |
1.1 |
|
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); |
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 * |
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 |
root |
1.2 |
(SvPVX (RETVAL))[size] = 0; |
86 |
root |
1.1 |
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 |
|
|
|