Import of old SSLeay release: SSLeay 0.9.0b
[openssl.git] / perl / openssl_bn.xs
1 #include "p5SSLeay.h"
2
3 int sv_to_BIGNUM(var,arg,name)
4 BIGNUM **var;
5 SV *arg;
6 char *name;
7         {
8         int ret=1;
9
10         if (sv_derived_from(arg,"SSLeay::BN"))
11                 {
12                 IV tmp = SvIV((SV*)SvRV(arg));
13                 *var = (BIGNUM *) tmp;
14                 }
15         else if (SvIOK(arg)) {
16                 SV *tmp=sv_newmortal();
17                 *var=BN_new();
18                 BN_set_word(*var,SvIV(arg));
19                 sv_setref_pv(tmp,"SSLeay::BN",(void*)*var);
20                 }
21         else if (SvPOK(arg)) {
22                 char *ptr;
23                 STRLEN len;
24                 SV *tmp=sv_newmortal();
25                 *var=BN_new();
26                 sv_setref_pv(tmp,"SSLeay::BN", (void*)*var);
27                 ptr=SvPV(arg,len);
28                 SvGROW(arg,len+1);
29                 ptr[len]='\0';
30                 BN_dec2bn(var,ptr);
31                 }
32         else
33                 {
34                 croak(name);
35                 ret=0;
36                 }
37         return(ret);
38         }
39
40 typedef struct gpc_args_st {
41         SV *cb;
42         SV *arg;
43         } GPC_ARGS;
44
45 static void generate_prime_callback(pos,num,arg)
46 int pos;
47 int num;
48 char *arg;
49         {
50         dSP ;
51         int i;
52         GPC_ARGS *a=(GPC_ARGS *)arg;
53
54         ENTER ;
55         SAVETMPS ;
56
57         PUSHMARK(sp);
58         XPUSHs(sv_2mortal(newSViv(pos)));
59         XPUSHs(sv_2mortal(newSViv(num)));
60         XPUSHs(sv_2mortal(newSVsv(a->arg)));
61         PUTBACK;
62
63         i=perl_call_sv(a->cb,G_DISCARD);
64
65         SPAGAIN;
66
67         PUTBACK;
68         FREETMPS;
69         LEAVE;
70         }
71
72 MODULE =  SSLeay::BN    PACKAGE = SSLeay::BN    PREFIX = p5_BN_
73
74 VERSIONCHECK: DISABLE
75
76 void
77 p5_BN_new(...)
78         PREINIT:
79                 BIGNUM *bn;
80                 SV *arg;
81         PPCODE:
82                 pr_name("p5_BN_new");
83                 EXTEND(sp,1);
84                 PUSHs(sv_newmortal());
85                 bn=BN_new();
86                 sv_setref_pv(ST(0), "SSLeay::BN", (void*)bn);
87
88 void
89 p5_BN_dup(a)
90         BIGNUM *a;
91         PREINIT:
92                 BIGNUM *bn;
93         PPCODE:
94                 pr_name("p5_BN_dup");
95                 EXTEND(sp,1);
96                 PUSHs(sv_newmortal());
97                 bn=BN_dup(a);
98                 sv_setref_pv(ST(0), "SSLeay::BN", (void*)bn);
99
100 void
101 p5_BN_rand(bits,...)
102         int bits;
103         PREINIT:
104                 int top=1;
105                 int bottom=0;
106                 BIGNUM *ret;
107         PPCODE: 
108                 pr_name("p5_BN_rand");
109                 if ((items < 1) || (items > 3))
110                         croak("Usage: SSLeay::BN::rand(bits[,top_bit][,bottombit]");
111                 if (items >= 2) top=(int)SvIV(ST(0));
112                 if (items >= 3) bottom=(int)SvIV(ST(1));
113                 EXTEND(sp,1);
114                 PUSHs(sv_newmortal());
115                 ret=BN_new();
116                 BN_rand(ret,bits,top,bottom);
117                 sv_setref_pv(ST(0), "SSLeay::BN", (void*)ret);
118
119 void
120 p5_BN_bin2bn(a)
121         datum a;
122         PREINIT:
123                 BIGNUM *ret;
124         PPCODE:
125                 pr_name("p5_BN_bin2bn");
126                 EXTEND(sp,1);
127                 PUSHs(sv_newmortal());
128                 ret=BN_bin2bn(a.dptr,a.dsize,NULL);
129                 sv_setref_pv(ST(0), "SSLeay::BN", (void*)ret);
130
131 void
132 p5_BN_bn2bin(a)
133         BIGNUM *a;
134         PREINIT:
135                 int i;
136         PPCODE:
137                 pr_name("p5_BN_bn2bin");
138                 EXTEND(sp,1);
139                 PUSHs(sv_newmortal());
140                 i=BN_num_bytes(a)+2;
141                 sv_setpvn(ST(0),"",1);
142                 SvGROW(ST(0),i+1);
143                 SvCUR_set(ST(0),BN_bn2bin(a,SvPV(ST(0),na)));
144
145 void
146 p5_BN_mpi2bn(a)
147         datum a;
148         PREINIT:
149                 BIGNUM *ret;
150         PPCODE:
151                 pr_name("p5_BN_mpi2bn");
152                 EXTEND(sp,1);
153                 PUSHs(sv_newmortal());
154                 ret=BN_mpi2bn(a.dptr,a.dsize,NULL);
155                 sv_setref_pv(ST(0), "SSLeay::BN", (void*)ret);
156
157 void
158 p5_BN_bn2mpi(a)
159         BIGNUM *a;
160         PREINIT:
161                 int i;
162         PPCODE:
163                 pr_name("p5_BN_bn2mpi");
164                 EXTEND(sp,1);
165                 PUSHs(sv_newmortal());
166                 i=BN_bn2mpi(a,NULL);
167                 sv_setpvn(ST(0),"",1);
168                 SvGROW(ST(0),i+1);
169                 SvCUR_set(ST(0),BN_bn2mpi(a,SvPV(ST(0),na)));
170
171 void
172 p5_BN_hex2bn(a)
173         datum a;
174         PREINIT:
175                 BIGNUM *ret;
176         PPCODE:
177                 pr_name("p5_BN_hex2bn");
178                 EXTEND(sp,1);
179                 PUSHs(sv_newmortal());
180                 ret=BN_new();
181                 sv_setref_pv(ST(0), "SSLeay::BN", (void*)ret);
182                 BN_hex2bn(&ret,a.dptr);
183
184 void
185 p5_BN_dec2bn(a)
186         datum a;
187         PREINIT:
188                 BIGNUM *ret;
189         PPCODE:
190                 pr_name("p5_BN_dec2bn");
191                 EXTEND(sp,1);
192                 PUSHs(sv_newmortal());
193                 ret=BN_new();
194                 sv_setref_pv(ST(0), "SSLeay::BN", (void*)ret);
195                 BN_dec2bn(&ret,a.dptr);
196
197 SV *
198 p5_BN_bn2hex(a)
199         BIGNUM *a;
200         PREINIT:
201                 char *ptr;
202                 int i;
203         CODE:
204                 pr_name("p5_BN_bn2hex");
205                 ptr=BN_bn2hex(a);
206                 RETVAL=newSVpv("",0);
207                 i=strlen(ptr);
208                 SvGROW(RETVAL,i+1);
209                 memcpy(SvPV(RETVAL,na),ptr,i+1);
210                 SvCUR_set(RETVAL,i);
211                 Free(ptr);
212         OUTPUT:
213                 RETVAL
214
215 SV *
216 p5_BN_bn2dec(a)
217         BIGNUM *a;
218         PREINIT:
219                 char *ptr;
220                 int i;
221         CODE:
222                 pr_name("p5_BN_bn2dec");
223                 ptr=BN_bn2dec(a);
224                 RETVAL=newSVpv("",0);
225                 i=strlen(ptr);
226                 SvGROW(RETVAL,i+1);
227                 memcpy(SvPV(RETVAL,na),ptr,i+1);
228                 SvCUR_set(RETVAL,i);
229                 Free(ptr);
230         OUTPUT:
231                 RETVAL
232
233 void
234 p5_BN_add(a,b)
235         BIGNUM *a;
236         BIGNUM *b;
237         PREINIT:
238                 BIGNUM *ret;
239         PPCODE:
240                 pr_name("p5_BN_add");
241                 EXTEND(sp,1);
242                 PUSHs(sv_newmortal());
243                 ret=BN_new();
244                 sv_setref_pv(ST(0), "SSLeay::BN", (void*)ret);
245                 BN_add(ret,a,b);
246
247 void
248 p5_BN_sub(a,b)
249         BIGNUM *a;
250         BIGNUM *b;
251         PREINIT:
252                 BIGNUM *ret;
253         PPCODE:
254                 pr_name("p5_BN_sub");
255                 EXTEND(sp,1);
256                 PUSHs(sv_newmortal());
257                 ret=BN_new();
258                 sv_setref_pv(ST(0), "SSLeay::BN", (void*)ret);
259                 BN_sub(ret,a,b);
260
261 void
262 p5_BN_mul(a,b)
263         BIGNUM *a;
264         BIGNUM *b;
265         PREINIT:
266                 BIGNUM *ret;
267         PPCODE:
268                 pr_name("p5_BN_mul");
269                 EXTEND(sp,1);
270                 PUSHs(sv_newmortal());
271                 ret=BN_new();
272                 sv_setref_pv(ST(0), "SSLeay::BN", (void*)ret);
273                 BN_mul(ret,a,b);
274
275 void
276 p5_BN_div(a,b)
277         BIGNUM *a;
278         BIGNUM *b;
279         PREINIT:
280                 static BN_CTX *ctx=NULL;
281                 BIGNUM *div,*mod;
282         PPCODE:
283                 pr_name("p5_BN_div");
284                 if (ctx == NULL) ctx=BN_CTX_new();
285                 EXTEND(sp,2);
286                 PUSHs(sv_newmortal());
287                 PUSHs(sv_newmortal());
288                 div=BN_new();
289                 mod=BN_new();
290                 sv_setref_pv(ST(0), "SSLeay::BN", (void*)div);
291                 sv_setref_pv(ST(1), "SSLeay::BN", (void*)mod);
292                 BN_div(div,mod,a,b,ctx);
293
294 void
295 p5_BN_mod(a,b)
296         BIGNUM *a;
297         BIGNUM *b;
298         PREINIT:
299                 static BN_CTX *ctx=NULL;
300                 BIGNUM *rem;
301         PPCODE:
302                 pr_name("p5_BN_mod");
303                 if (ctx == NULL) ctx=BN_CTX_new();
304                 EXTEND(sp,1);
305                 PUSHs(sv_newmortal());
306                 rem=BN_new();
307                 sv_setref_pv(ST(0), "SSLeay::BN", (void*)rem);
308                 BN_mod(rem,a,b,ctx);
309
310 void
311 p5_BN_exp(a,p)
312         BIGNUM *a;
313         BIGNUM *p;
314         PREINIT:
315                 BIGNUM *ret;
316                 static BN_CTX *ctx=NULL;
317         PPCODE:
318                 pr_name("p5_BN_exp");
319                 if (ctx == NULL) ctx=BN_CTX_new();
320                 EXTEND(sp,1);
321                 PUSHs(sv_newmortal());
322                 ret=BN_new();
323                 sv_setref_pv(ST(0), "SSLeay::BN", (void*)ret);
324                 BN_exp(ret,a,p,ctx);
325
326 void
327 p5_BN_mod_mul(a,b,c)
328         BIGNUM *a;
329         BIGNUM *b;
330         BIGNUM *c;
331         PREINIT:
332                 static BN_CTX *ctx=NULL;
333                 BIGNUM *ret;
334         PPCODE:
335                 pr_name("p5_BN_mod_mul");
336                 if (ctx == NULL) ctx=BN_CTX_new();
337                 EXTEND(sp,1);
338                 PUSHs(sv_newmortal());
339                 ret=BN_new();
340                 sv_setref_pv(ST(0), "SSLeay::BN", (void*)ret);
341                 BN_mod_mul(ret,a,b,c,ctx);
342
343 void
344 p5_BN_mod_exp(a,b,c)
345         BIGNUM *a;
346         BIGNUM *b;
347         BIGNUM *c;
348         PREINIT:
349                 static BN_CTX *ctx=NULL;
350                 BIGNUM *ret;
351         PPCODE:
352                 pr_name("p5_BN_mod_exp");
353                 if (ctx == NULL) ctx=BN_CTX_new();
354                 EXTEND(sp,1);
355                 PUSHs(sv_newmortal());
356                 ret=BN_new();
357                 sv_setref_pv(ST(0), "SSLeay::BN", (void*)ret);
358                 BN_mod_exp(ret,a,b,c,ctx);
359
360 void
361 p5_BN_generate_prime(...)
362         PREINIT:
363                 int bits=512;
364                 int strong=0;
365                 BIGNUM *ret=NULL;
366                 SV *callback=NULL;
367                 SV *cb_arg=NULL;
368                 GPC_ARGS arg;
369                 dSP;
370
371         PPCODE:
372                 pr_name("p5_BN_generate_prime");
373                 if ((items < 0) || (items > 4))
374                         croak("Usage: SSLeay::BN::generate_prime(a[,strong][,callback][,cb_arg]");
375                 if (items >= 1) bits=(int)SvIV(ST(0));
376                 if (items >= 2) strong=(int)SvIV(ST(1));
377                 if (items >= 3) callback=ST(2);
378                 if (items == 4) cb_arg=ST(3);
379
380                 if (callback == NULL)
381                         ret=BN_generate_prime(bits,strong,NULL,NULL,NULL,NULL);
382                 else
383                         {
384                         arg.cb=callback;
385                         arg.arg=cb_arg;
386
387                         ret=BN_generate_prime(bits,strong,NULL,NULL,
388                                 generate_prime_callback,(char *)&arg);
389                         }
390
391                 SPAGAIN;
392                 sp-=items; /* a bit evil that I do this */
393
394                 EXTEND(sp,1);
395                 PUSHs(sv_newmortal());
396                 sv_setref_pv(ST(0), "SSLeay::BN", (void*)ret);
397
398 void
399 p5_BN_is_prime(p,...)
400         BIGNUM *p;
401         PREINIT:
402         int nchecks=5,ret;
403         SV *callback=NULL;
404         SV *cb_arg=NULL;
405         GPC_ARGS arg;
406         dSP;
407         static BN_CTX *ctx=NULL;
408         PPCODE:
409                 pr_name("p5_BN_is_prime");
410                 if ((items < 1) || (items > 4))
411                         croak("Usage: SSLeay::BN::is_prime(a[,ncheck][,callback][,callback_arg]");
412                 if (ctx == NULL) ctx=BN_CTX_new();
413                 if (items >= 2) nchecks=(int)SvIV(ST(1));
414                 if (items >= 3) callback=ST(2);
415                 if (items >= 4) cb_arg=ST(3);
416                 arg.arg=cb_arg; 
417                 if (callback == NULL)
418                         ret=BN_is_prime(p,nchecks,NULL,ctx,NULL);
419                 else
420                         {
421                         arg.cb=callback;
422                         arg.arg=cb_arg;
423                         ret=BN_is_prime(p,nchecks,generate_prime_callback,
424                                 ctx,(char *)&arg);
425                         }
426                 SPAGAIN;
427                 sp-=items; /* a bit evil */
428                 PUSHs(sv_2mortal(newSViv(ret)));
429
430 int
431 p5_BN_num_bits(a)
432         BIGNUM *a;
433         CODE:
434                 pr_name("p5_BN_num_bits");
435                 RETVAL=BN_num_bits(a);
436         OUTPUT:
437                 RETVAL
438
439 int
440 p5_BN_cmp(a,b)
441         BIGNUM *a;
442         BIGNUM *b;
443         CODE:
444                 pr_name("p5_BN_cmp");
445                 RETVAL=BN_cmp(a,b);
446         OUTPUT:
447                 RETVAL
448
449 int
450 p5_BN_ucmp(a,b)
451         BIGNUM *a;
452         BIGNUM *b;
453         CODE:
454                 pr_name("p5_BN_ucmp");
455                 RETVAL=BN_ucmp(a,b);
456         OUTPUT:
457                 RETVAL
458
459 int
460 p5_BN_is_bit_set(a,b)
461         BIGNUM *a;
462         int b;
463         CODE:
464                 pr_name("p5_BN_is_bit_set");
465                 RETVAL=BN_is_bit_set(a,b);
466         OUTPUT:
467                 RETVAL
468
469 void
470 p5_BN_set_bit(a,b)
471         BIGNUM *a;
472         int b;
473         PREINIT:
474                 BIGNUM *ret;
475         PPCODE:
476                 pr_name("p5_BN_set_bit");
477                 EXTEND(sp,1);
478                 PUSHs(sv_newmortal());
479                 ret=BN_dup(a);
480                 sv_setref_pv(ST(0), "SSLeay::BN", (void*)ret);
481                 BN_set_bit(ret,b);
482
483 void
484 p5_BN_clear_bit(a,b)
485         BIGNUM *a;
486         int b;
487         PREINIT:
488                 BIGNUM *ret;
489         PPCODE:
490                 pr_name("p5_BN_clear_bit");
491                 EXTEND(sp,1);
492                 PUSHs(sv_newmortal());
493                 ret=BN_dup(a);
494                 sv_setref_pv(ST(0), "SSLeay::BN", (void*)ret);
495                 BN_clear_bit(ret,b);
496
497 void
498 p5_BN_lshift(a,b)
499         BIGNUM *a;
500         int b;
501         PREINIT:
502                 BIGNUM *ret;
503         PPCODE:
504                 pr_name("p5_BN_lshift");
505                 EXTEND(sp,1);
506                 PUSHs(sv_newmortal());
507                 ret=BN_new();
508                 sv_setref_pv(ST(0), "SSLeay::BN", (void*)ret);
509                 if (b == 1)
510                         BN_lshift1(ret,a);
511                 else
512                         BN_lshift(ret,a,b);
513
514 void
515 p5_BN_rshift(a,b)
516         BIGNUM *a;
517         int b;
518         PREINIT:
519                 BIGNUM *ret;
520         PPCODE:
521                 pr_name("p5_BN_rshift");
522                 EXTEND(sp,1);
523                 PUSHs(sv_newmortal());
524                 ret=BN_new();
525                 sv_setref_pv(ST(0), "SSLeay::BN", (void*)ret);
526                 if (b == 1)
527                         BN_rshift1(ret,a);
528                 else
529                         BN_rshift(ret,a,b);
530
531 void
532 p5_BN_mask_bits(a,b)
533         BIGNUM *a;
534         int b;
535         PREINIT:
536                 BIGNUM *ret;
537         PPCODE:
538                 pr_name("p5_BN_mask_bits");
539                 EXTEND(sp,1);
540                 PUSHs(sv_newmortal());
541                 ret=BN_dup(a);
542                 sv_setref_pv(ST(0), "SSLeay::BN", (void*)ret);
543                 BN_mask_bits(ret,b);
544
545 void
546 p5_BN_clear(a)
547         BIGNUM *a;
548         PPCODE:
549                 pr_name("p5_BN_clear");
550                 BN_clear(a);
551
552 void
553 p5_BN_gcd(a,b)
554         BIGNUM *a;
555         BIGNUM *b;
556         PREINIT:
557                 static BN_CTX *ctx=NULL;
558                 BIGNUM *ret;
559         PPCODE:
560                 pr_name("p5_BN_gcd");
561                 if (ctx == NULL) ctx=BN_CTX_new();
562                 EXTEND(sp,1);
563                 PUSHs(sv_newmortal());
564                 ret=BN_new();
565                 sv_setref_pv(ST(0), "SSLeay::BN", (void*)ret);
566                 BN_gcd(ret,a,b,ctx);
567
568 void
569 p5_BN_mod_inverse(a,mod)
570         BIGNUM *a;
571         BIGNUM *mod;
572         PREINIT:
573                 static BN_CTX *ctx=NULL;
574                 BIGNUM *ret;
575         PPCODE:
576                 pr_name("p5_BN_mod_inverse");
577                 if (ctx == NULL) ctx=BN_CTX_new();
578                 ret=BN_mod_inverse(a,mod,ctx);
579                 EXTEND(sp,1);
580                 PUSHs(sv_newmortal());
581                 sv_setref_pv(ST(0), "SSLeay::BN", (void*)ret);
582
583 void
584 p5_BN_DESTROY(bn)
585         BIGNUM *bn
586         CODE:
587         pr_name("p5_BN_DESTROY");
588         BN_free(bn);
589