1#include "EXTERN.h"
2#include "perl.h"
3#include "XSUB.h"
4#include "des.h"
5
6#define deschar	char
7static STRLEN len;
8
9static int
10not_here(s)
11char *s;
12{
13    croak("%s not implemented on this architecture", s);
14    return -1;
15}
16
17MODULE = DES	PACKAGE = DES	PREFIX = des_
18
19char *
20des_crypt(buf,salt)
21	char *	buf
22	char *	salt
23
24void
25des_set_odd_parity(key)
26	des_cblock *	key
27PPCODE:
28	{
29	SV *s;
30
31	s=sv_newmortal();
32	sv_setpvn(s,(char *)key,8);
33	des_set_odd_parity((des_cblock *)SvPV(s,na));
34	PUSHs(s);
35	}
36
37int
38des_is_weak_key(key)
39	des_cblock *	key
40
41des_key_schedule
42des_set_key(key)
43	des_cblock *	key
44CODE:
45	des_set_key(key,RETVAL);
46OUTPUT:
47RETVAL
48
49des_cblock
50des_ecb_encrypt(input,ks,encrypt)
51	des_cblock *	input
52	des_key_schedule *	ks
53	int	encrypt
54CODE:
55	des_ecb_encrypt(input,&RETVAL,*ks,encrypt);
56OUTPUT:
57RETVAL
58
59void
60des_cbc_encrypt(input,ks,ivec,encrypt)
61	char *	input
62	des_key_schedule *	ks
63	des_cblock *	ivec
64	int	encrypt
65PPCODE:
66	{
67	SV *s;
68	STRLEN len,l;
69	char *c;
70
71	l=SvCUR(ST(0));
72	len=((((unsigned long)l)+7)/8)*8;
73	s=sv_newmortal();
74	sv_setpvn(s,"",0);
75	SvGROW(s,len);
76	SvCUR_set(s,len);
77	c=(char *)SvPV(s,na);
78	des_cbc_encrypt((des_cblock *)input,(des_cblock *)c,
79		l,*ks,ivec,encrypt);
80	sv_setpvn(ST(2),(char *)c[len-8],8);
81	PUSHs(s);
82	}
83
84void
85des_cbc3_encrypt(input,ks1,ks2,ivec1,ivec2,encrypt)
86	char *	input
87	des_key_schedule *	ks1
88	des_key_schedule *	ks2
89	des_cblock *	ivec1
90	des_cblock *	ivec2
91	int	encrypt
92PPCODE:
93	{
94	SV *s;
95	STRLEN len,l;
96
97	l=SvCUR(ST(0));
98	len=((((unsigned long)l)+7)/8)*8;
99	s=sv_newmortal();
100	sv_setpvn(s,"",0);
101	SvGROW(s,len);
102	SvCUR_set(s,len);
103	des_3cbc_encrypt((des_cblock *)input,(des_cblock *)SvPV(s,na),
104		l,*ks1,*ks2,ivec1,ivec2,encrypt);
105	sv_setpvn(ST(3),(char *)ivec1,8);
106	sv_setpvn(ST(4),(char *)ivec2,8);
107	PUSHs(s);
108	}
109
110void
111des_cbc_cksum(input,ks,ivec)
112	char *	input
113	des_key_schedule *	ks
114	des_cblock *	ivec
115PPCODE:
116	{
117	SV *s1,*s2;
118	STRLEN len,l;
119	des_cblock c;
120	unsigned long i1,i2;
121
122	s1=sv_newmortal();
123	s2=sv_newmortal();
124	l=SvCUR(ST(0));
125	des_cbc_cksum((des_cblock *)input,(des_cblock *)c,
126		l,*ks,ivec);
127	i1=c[4]|(c[5]<<8)|(c[6]<<16)|(c[7]<<24);
128	i2=c[0]|(c[1]<<8)|(c[2]<<16)|(c[3]<<24);
129	sv_setiv(s1,i1);
130	sv_setiv(s2,i2);
131	sv_setpvn(ST(2),(char *)c,8);
132	PUSHs(s1);
133	PUSHs(s2);
134	}
135
136void
137des_cfb_encrypt(input,numbits,ks,ivec,encrypt)
138	char *	input
139	int	numbits
140	des_key_schedule *	ks
141	des_cblock *	ivec
142	int	encrypt
143PPCODE:
144	{
145	SV *s;
146	STRLEN len;
147	char *c;
148
149	len=SvCUR(ST(0));
150	s=sv_newmortal();
151	sv_setpvn(s,"",0);
152	SvGROW(s,len);
153	SvCUR_set(s,len);
154	c=(char *)SvPV(s,na);
155	des_cfb_encrypt((unsigned char *)input,(unsigned char *)c,
156		(int)numbits,(long)len,*ks,ivec,encrypt);
157	sv_setpvn(ST(3),(char *)ivec,8);
158	PUSHs(s);
159	}
160
161des_cblock *
162des_ecb3_encrypt(input,ks1,ks2,encrypt)
163	des_cblock *	input
164	des_key_schedule *	ks1
165	des_key_schedule *	ks2
166	int	encrypt
167CODE:
168	{
169	des_cblock c;
170
171	des_ecb3_encrypt((des_cblock *)input,(des_cblock *)&c,
172		*ks1,*ks2,encrypt);
173	RETVAL= &c;
174	}
175OUTPUT:
176RETVAL
177
178void
179des_ofb_encrypt(input,numbits,ks,ivec)
180	unsigned char *	input
181	int	numbits
182	des_key_schedule *	ks
183	des_cblock *	ivec
184PPCODE:
185	{
186	SV *s;
187	STRLEN len,l;
188	unsigned char *c;
189
190	len=SvCUR(ST(0));
191	s=sv_newmortal();
192	sv_setpvn(s,"",0);
193	SvGROW(s,len);
194	SvCUR_set(s,len);
195	c=(unsigned char *)SvPV(s,na);
196	des_ofb_encrypt((unsigned char *)input,(unsigned char *)c,
197		numbits,len,*ks,ivec);
198	sv_setpvn(ST(3),(char *)ivec,8);
199	PUSHs(s);
200	}
201
202void
203des_pcbc_encrypt(input,ks,ivec,encrypt)
204	char *	input
205	des_key_schedule *	ks
206	des_cblock *	ivec
207	int	encrypt
208PPCODE:
209	{
210	SV *s;
211	STRLEN len,l;
212	char *c;
213
214	l=SvCUR(ST(0));
215	len=((((unsigned long)l)+7)/8)*8;
216	s=sv_newmortal();
217	sv_setpvn(s,"",0);
218	SvGROW(s,len);
219	SvCUR_set(s,len);
220	c=(char *)SvPV(s,na);
221	des_pcbc_encrypt((des_cblock *)input,(des_cblock *)c,
222		l,*ks,ivec,encrypt);
223	sv_setpvn(ST(2),(char *)c[len-8],8);
224	PUSHs(s);
225	}
226
227des_cblock *
228des_random_key()
229CODE:
230	{
231	des_cblock c;
232
233	des_random_key(c);
234	RETVAL=&c;
235	}
236OUTPUT:
237RETVAL
238
239des_cblock *
240des_string_to_key(str)
241char *	str
242CODE:
243	{
244	des_cblock c;
245
246	des_string_to_key(str,&c);
247	RETVAL=&c;
248	}
249OUTPUT:
250RETVAL
251
252void
253des_string_to_2keys(str)
254char *	str
255PPCODE:
256	{
257	des_cblock c1,c2;
258	SV *s1,*s2;
259
260	des_string_to_2keys(str,&c1,&c2);
261	EXTEND(sp,2);
262	s1=sv_newmortal();
263	sv_setpvn(s1,(char *)c1,8);
264	s2=sv_newmortal();
265	sv_setpvn(s2,(char *)c2,8);
266	PUSHs(s1);
267	PUSHs(s2);
268	}
269