summaryrefslogtreecommitdiff
path: root/lib/dns/sec
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dns/sec')
-rw-r--r--lib/dns/sec/.cvsignore1
-rw-r--r--lib/dns/sec/Makefile.in23
-rw-r--r--lib/dns/sec/dnssafe/.cvsignore1
-rw-r--r--lib/dns/sec/dnssafe/Makefile.in77
-rw-r--r--lib/dns/sec/dnssafe/ahcbcpad.c174
-rw-r--r--lib/dns/sec/dnssafe/ahcbcpad.h37
-rw-r--r--lib/dns/sec/dnssafe/ahchdig.c130
-rw-r--r--lib/dns/sec/dnssafe/ahchdig.h32
-rw-r--r--lib/dns/sec/dnssafe/ahchencr.c266
-rw-r--r--lib/dns/sec/dnssafe/ahchencr.h74
-rw-r--r--lib/dns/sec/dnssafe/ahchgen.c216
-rw-r--r--lib/dns/sec/dnssafe/ahchgen.h44
-rw-r--r--lib/dns/sec/dnssafe/ahchrand.c128
-rw-r--r--lib/dns/sec/dnssafe/ahchrand.h31
-rw-r--r--lib/dns/sec/dnssafe/ahdigest.c91
-rw-r--r--lib/dns/sec/dnssafe/ahdigest.h48
-rw-r--r--lib/dns/sec/dnssafe/ahencryp.c169
-rw-r--r--lib/dns/sec/dnssafe/ahencryp.h85
-rw-r--r--lib/dns/sec/dnssafe/ahgen.c90
-rw-r--r--lib/dns/sec/dnssafe/ahgen.h47
-rw-r--r--lib/dns/sec/dnssafe/ahrandom.c97
-rw-r--r--lib/dns/sec/dnssafe/ahrandom.h47
-rw-r--r--lib/dns/sec/dnssafe/ahrsaenc.c241
-rw-r--r--lib/dns/sec/dnssafe/ahrsaenc.h68
-rw-r--r--lib/dns/sec/dnssafe/ahrsaepr.c99
-rw-r--r--lib/dns/sec/dnssafe/ahrsaepr.h20
-rw-r--r--lib/dns/sec/dnssafe/ahrsaepu.c112
-rw-r--r--lib/dns/sec/dnssafe/ahrsaepu.h20
-rw-r--r--lib/dns/sec/dnssafe/aichdig.c36
-rw-r--r--lib/dns/sec/dnssafe/aichdig.h17
-rw-r--r--lib/dns/sec/dnssafe/aichenc8.c33
-rw-r--r--lib/dns/sec/dnssafe/aichenc8.h19
-rw-r--r--lib/dns/sec/dnssafe/aichencn.c17
-rw-r--r--lib/dns/sec/dnssafe/aichencn.h17
-rw-r--r--lib/dns/sec/dnssafe/aichencr.c31
-rw-r--r--lib/dns/sec/dnssafe/aichencr.h17
-rw-r--r--lib/dns/sec/dnssafe/aichgen.c31
-rw-r--r--lib/dns/sec/dnssafe/aichgen.h17
-rw-r--r--lib/dns/sec/dnssafe/aichrand.c36
-rw-r--r--lib/dns/sec/dnssafe/aichrand.h17
-rw-r--r--lib/dns/sec/dnssafe/aimd5.c25
-rw-r--r--lib/dns/sec/dnssafe/aimd5ran.c25
-rw-r--r--lib/dns/sec/dnssafe/ainfotyp.c30
-rw-r--r--lib/dns/sec/dnssafe/ainfotyp.h39
-rw-r--r--lib/dns/sec/dnssafe/ainull.c26
-rw-r--r--lib/dns/sec/dnssafe/ainull.h10
-rw-r--r--lib/dns/sec/dnssafe/airsaepr.c45
-rw-r--r--lib/dns/sec/dnssafe/airsaepu.c45
-rw-r--r--lib/dns/sec/dnssafe/airsakgn.c60
-rw-r--r--lib/dns/sec/dnssafe/airsaprv.c25
-rw-r--r--lib/dns/sec/dnssafe/airsapub.c25
-rw-r--r--lib/dns/sec/dnssafe/algae.h66
-rw-r--r--lib/dns/sec/dnssafe/algchoic.c167
-rw-r--r--lib/dns/sec/dnssafe/algchoic.h111
-rw-r--r--lib/dns/sec/dnssafe/algobj.c121
-rw-r--r--lib/dns/sec/dnssafe/algobj.h19
-rw-r--r--lib/dns/sec/dnssafe/amcrte.c117
-rw-r--r--lib/dns/sec/dnssafe/amdigest.h19
-rw-r--r--lib/dns/sec/dnssafe/amencdec.h21
-rw-r--r--lib/dns/sec/dnssafe/amgen.h19
-rw-r--r--lib/dns/sec/dnssafe/ammd5.c100
-rw-r--r--lib/dns/sec/dnssafe/ammd5r.c77
-rw-r--r--lib/dns/sec/dnssafe/amrandom.h17
-rw-r--r--lib/dns/sec/dnssafe/amrkg.c81
-rw-r--r--lib/dns/sec/dnssafe/amrsae.c115
-rw-r--r--lib/dns/sec/dnssafe/atypes.h60
-rw-r--r--lib/dns/sec/dnssafe/balg.c115
-rw-r--r--lib/dns/sec/dnssafe/balg.h116
-rw-r--r--lib/dns/sec/dnssafe/balgmeth.h18
-rw-r--r--lib/dns/sec/dnssafe/bgclrbit.c28
-rw-r--r--lib/dns/sec/dnssafe/bgmdmpyx.c26
-rw-r--r--lib/dns/sec/dnssafe/bgmdsqx.c24
-rw-r--r--lib/dns/sec/dnssafe/bgmodexp.c132
-rw-r--r--lib/dns/sec/dnssafe/bgpegcd.c78
-rw-r--r--lib/dns/sec/dnssafe/big2exp.c25
-rw-r--r--lib/dns/sec/dnssafe/bigabs.c22
-rw-r--r--lib/dns/sec/dnssafe/bigacc.c34
-rw-r--r--lib/dns/sec/dnssafe/bigarith.c138
-rw-r--r--lib/dns/sec/dnssafe/bigcmp.c34
-rw-r--r--lib/dns/sec/dnssafe/bigconst.c26
-rw-r--r--lib/dns/sec/dnssafe/biginv.c103
-rw-r--r--lib/dns/sec/dnssafe/biglen.c28
-rw-r--r--lib/dns/sec/dnssafe/bigmath.h71
-rw-r--r--lib/dns/sec/dnssafe/bigmaxes.h47
-rw-r--r--lib/dns/sec/dnssafe/bigmodx.c25
-rw-r--r--lib/dns/sec/dnssafe/bigmpy.c36
-rw-r--r--lib/dns/sec/dnssafe/bigpdiv.c159
-rw-r--r--lib/dns/sec/dnssafe/bigpmpy.c25
-rw-r--r--lib/dns/sec/dnssafe/bigpmpyh.c30
-rw-r--r--lib/dns/sec/dnssafe/bigpmpyl.c30
-rw-r--r--lib/dns/sec/dnssafe/bigpsq.c42
-rw-r--r--lib/dns/sec/dnssafe/bigqrx.c85
-rw-r--r--lib/dns/sec/dnssafe/bigsmod.c28
-rw-r--r--lib/dns/sec/dnssafe/bigtocan.c60
-rw-r--r--lib/dns/sec/dnssafe/bigu.c21
-rw-r--r--lib/dns/sec/dnssafe/bigunexp.c98
-rw-r--r--lib/dns/sec/dnssafe/binfocsh.c63
-rw-r--r--lib/dns/sec/dnssafe/binfocsh.h33
-rw-r--r--lib/dns/sec/dnssafe/bkey.c101
-rw-r--r--lib/dns/sec/dnssafe/bkey.h32
-rw-r--r--lib/dns/sec/dnssafe/bmempool.c275
-rw-r--r--lib/dns/sec/dnssafe/bmempool.h53
-rw-r--r--lib/dns/sec/dnssafe/bsafe2.h194
-rw-r--r--lib/dns/sec/dnssafe/btypechk.h25
-rw-r--r--lib/dns/sec/dnssafe/cantobig.c57
-rw-r--r--lib/dns/sec/dnssafe/crt2.c228
-rw-r--r--lib/dns/sec/dnssafe/crt2.h50
-rw-r--r--lib/dns/sec/dnssafe/digest.c67
-rw-r--r--lib/dns/sec/dnssafe/digrand.c88
-rw-r--r--lib/dns/sec/dnssafe/digrand.h53
-rw-r--r--lib/dns/sec/dnssafe/encrypt.c147
-rw-r--r--lib/dns/sec/dnssafe/generate.c78
-rw-r--r--lib/dns/sec/dnssafe/global.h60
-rw-r--r--lib/dns/sec/dnssafe/intbits.c32
-rw-r--r--lib/dns/sec/dnssafe/intitem.c54
-rw-r--r--lib/dns/sec/dnssafe/intitem.h11
-rw-r--r--lib/dns/sec/dnssafe/keyobj.c113
-rw-r--r--lib/dns/sec/dnssafe/keyobj.h16
-rw-r--r--lib/dns/sec/dnssafe/ki8byte.c70
-rw-r--r--lib/dns/sec/dnssafe/ki8byte.h9
-rw-r--r--lib/dns/sec/dnssafe/kifulprv.c151
-rw-r--r--lib/dns/sec/dnssafe/kifulprv.h12
-rw-r--r--lib/dns/sec/dnssafe/kiitem.c44
-rw-r--r--lib/dns/sec/dnssafe/kiitem.h9
-rw-r--r--lib/dns/sec/dnssafe/kinfotyp.c26
-rw-r--r--lib/dns/sec/dnssafe/kinfotyp.h57
-rw-r--r--lib/dns/sec/dnssafe/kipkcrpr.c100
-rw-r--r--lib/dns/sec/dnssafe/kipkcrpr.h13
-rw-r--r--lib/dns/sec/dnssafe/kirsacrt.c101
-rw-r--r--lib/dns/sec/dnssafe/kirsapub.c80
-rw-r--r--lib/dns/sec/dnssafe/kirsapub.h13
-rw-r--r--lib/dns/sec/dnssafe/md5.c281
-rw-r--r--lib/dns/sec/dnssafe/md5.h32
-rw-r--r--lib/dns/sec/dnssafe/md5rand.c69
-rw-r--r--lib/dns/sec/dnssafe/md5rand.h36
-rw-r--r--lib/dns/sec/dnssafe/prime.c163
-rw-r--r--lib/dns/sec/dnssafe/prime.h26
-rw-r--r--lib/dns/sec/dnssafe/random.c58
-rw-r--r--lib/dns/sec/dnssafe/rsa.c209
-rw-r--r--lib/dns/sec/dnssafe/rsa.h44
-rw-r--r--lib/dns/sec/dnssafe/rsakeygn.c242
-rw-r--r--lib/dns/sec/dnssafe/rsakeygn.h54
-rw-r--r--lib/dns/sec/dnssafe/seccbcd.c146
-rw-r--r--lib/dns/sec/dnssafe/seccbce.c97
-rw-r--r--lib/dns/sec/dnssafe/secrcbc.h36
-rw-r--r--lib/dns/sec/dnssafe/surrendr.c24
-rw-r--r--lib/dns/sec/dnssafe/surrendr.h22
-rw-r--r--lib/dns/sec/dst/.cvsignore1
-rw-r--r--lib/dns/sec/dst/Makefile.in44
-rw-r--r--lib/dns/sec/dst/bsafe_link.c1093
-rw-r--r--lib/dns/sec/dst/dst_api.c1092
-rw-r--r--lib/dns/sec/dst/dst_internal.h123
-rw-r--r--lib/dns/sec/dst/dst_lib.c65
-rw-r--r--lib/dns/sec/dst/dst_parse.c391
-rw-r--r--lib/dns/sec/dst/dst_parse.h88
-rw-r--r--lib/dns/sec/dst/dst_result.c87
-rw-r--r--lib/dns/sec/dst/dst_support.c129
-rw-r--r--lib/dns/sec/dst/hmac_link.c504
-rw-r--r--lib/dns/sec/dst/include/.cvsignore1
-rw-r--r--lib/dns/sec/dst/include/Makefile.in23
-rw-r--r--lib/dns/sec/dst/include/dst/.cvsignore1
-rw-r--r--lib/dns/sec/dst/include/dst/Makefile.in40
-rw-r--r--lib/dns/sec/dst/include/dst/dst.h332
-rw-r--r--lib/dns/sec/dst/include/dst/lib.h37
-rw-r--r--lib/dns/sec/dst/include/dst/result.h40
-rw-r--r--lib/dns/sec/dst/openssl_link.c628
-rw-r--r--lib/dns/sec/dst/openssldh_link.c694
-rw-r--r--lib/dns/sec/dst/opensslmd5_link.c102
-rw-r--r--lib/dns/sec/openssl/.cvsignore1
-rw-r--r--lib/dns/sec/openssl/Makefile.in55
-rw-r--r--lib/dns/sec/openssl/bn_add.c307
-rw-r--r--lib/dns/sec/openssl/bn_asm.c802
-rw-r--r--lib/dns/sec/openssl/bn_comba.c345
-rw-r--r--lib/dns/sec/openssl/bn_div.c358
-rw-r--r--lib/dns/sec/openssl/bn_err.c116
-rw-r--r--lib/dns/sec/openssl/bn_exp.c549
-rw-r--r--lib/dns/sec/openssl/bn_exp2.c195
-rw-r--r--lib/dns/sec/openssl/bn_gcd.c204
-rw-r--r--lib/dns/sec/openssl/bn_lcl.h272
-rw-r--r--lib/dns/sec/openssl/bn_lib.c787
-rw-r--r--lib/dns/sec/openssl/bn_mont.c407
-rw-r--r--lib/dns/sec/openssl/bn_mul.c756
-rw-r--r--lib/dns/sec/openssl/bn_prime.c447
-rw-r--r--lib/dns/sec/openssl/bn_prime.h325
-rw-r--r--lib/dns/sec/openssl/bn_print.c327
-rw-r--r--lib/dns/sec/openssl/bn_rand.c117
-rw-r--r--lib/dns/sec/openssl/bn_recp.c228
-rw-r--r--lib/dns/sec/openssl/bn_shift.c200
-rw-r--r--lib/dns/sec/openssl/bn_sqr.c281
-rw-r--r--lib/dns/sec/openssl/bn_word.c194
-rw-r--r--lib/dns/sec/openssl/buffer.c144
-rw-r--r--lib/dns/sec/openssl/cryptlib.c296
-rw-r--r--lib/dns/sec/openssl/cryptlib.h96
-rw-r--r--lib/dns/sec/openssl/dh_err.c98
-rw-r--r--lib/dns/sec/openssl/dh_gen.c148
-rw-r--r--lib/dns/sec/openssl/dh_key.c154
-rw-r--r--lib/dns/sec/openssl/dh_lib.c103
-rw-r--r--lib/dns/sec/openssl/dsa_asn1.c99
-rw-r--r--lib/dns/sec/openssl/dsa_err.c106
-rw-r--r--lib/dns/sec/openssl/dsa_gen.c333
-rw-r--r--lib/dns/sec/openssl/dsa_key.c112
-rw-r--r--lib/dns/sec/openssl/dsa_lib.c150
-rw-r--r--lib/dns/sec/openssl/dsa_sign.c214
-rw-r--r--lib/dns/sec/openssl/dsa_vrf.c163
-rw-r--r--lib/dns/sec/openssl/err.c642
-rw-r--r--lib/dns/sec/openssl/include/.cvsignore1
-rw-r--r--lib/dns/sec/openssl/include/Makefile.in23
-rw-r--r--lib/dns/sec/openssl/include/openssl/.cvsignore1
-rw-r--r--lib/dns/sec/openssl/include/openssl/Makefile.in41
-rw-r--r--lib/dns/sec/openssl/include/openssl/bio.h596
-rw-r--r--lib/dns/sec/openssl/include/openssl/bn.h473
-rw-r--r--lib/dns/sec/openssl/include/openssl/buffer.h98
-rw-r--r--lib/dns/sec/openssl/include/openssl/crypto.h314
-rw-r--r--lib/dns/sec/openssl/include/openssl/dh.h158
-rw-r--r--lib/dns/sec/openssl/include/openssl/dsa.h195
-rw-r--r--lib/dns/sec/openssl/include/openssl/e_os.h373
-rw-r--r--lib/dns/sec/openssl/include/openssl/e_os2.h28
-rw-r--r--lib/dns/sec/openssl/include/openssl/err.h262
-rw-r--r--lib/dns/sec/openssl/include/openssl/lhash.h144
-rw-r--r--lib/dns/sec/openssl/include/openssl/md5.h114
-rw-r--r--lib/dns/sec/openssl/include/openssl/opensslconf.h7
-rw-r--r--lib/dns/sec/openssl/include/openssl/opensslv.h20
-rw-r--r--lib/dns/sec/openssl/include/openssl/rand.h89
-rw-r--r--lib/dns/sec/openssl/include/openssl/sha.h119
-rw-r--r--lib/dns/sec/openssl/include/openssl/stack.h106
-rw-r--r--lib/dns/sec/openssl/lhash.c476
-rw-r--r--lib/dns/sec/openssl/md32_common.h594
-rw-r--r--lib/dns/sec/openssl/md5_dgst.c317
-rw-r--r--lib/dns/sec/openssl/md5_locl.h172
-rw-r--r--lib/dns/sec/openssl/md_rand.c429
-rw-r--r--lib/dns/sec/openssl/mem.c382
-rw-r--r--lib/dns/sec/openssl/rand_lib.c98
-rw-r--r--lib/dns/sec/openssl/sha1_one.c76
-rw-r--r--lib/dns/sec/openssl/sha1dgst.c498
-rw-r--r--lib/dns/sec/openssl/sha_locl.h288
-rw-r--r--lib/dns/sec/openssl/stack.c303
-rw-r--r--lib/dns/sec/openssl/th-lock.c373
237 files changed, 32793 insertions, 0 deletions
diff --git a/lib/dns/sec/.cvsignore b/lib/dns/sec/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/lib/dns/sec/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/lib/dns/sec/Makefile.in b/lib/dns/sec/Makefile.in
new file mode 100644
index 00000000..281e6008
--- /dev/null
+++ b/lib/dns/sec/Makefile.in
@@ -0,0 +1,23 @@
+# Copyright (C) 1998, 1999, 2000 Internet Software Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+# CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+# SOFTWARE.
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+SUBDIRS = dnssafe dst openssl
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/dns/sec/dnssafe/.cvsignore b/lib/dns/sec/dnssafe/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/lib/dns/sec/dnssafe/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/lib/dns/sec/dnssafe/Makefile.in b/lib/dns/sec/dnssafe/Makefile.in
new file mode 100644
index 00000000..127568eb
--- /dev/null
+++ b/lib/dns/sec/dnssafe/Makefile.in
@@ -0,0 +1,77 @@
+# Copyright (C) 1998, 1999, 2000 Internet Software Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+# CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+# SOFTWARE.
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_INCLUDES@
+
+CINCLUDES = -I${srcdir} ${ISC_INCLUDES}
+
+CDEFINES =
+CWARNINGS =
+
+LIBS = @LIBS@
+
+# Alphabetically
+OBJS = ahchdig.@O@ ahchencr.@O@ ahchgen.@O@ ahchrand.@O@ \
+ ahdigest.@O@ ahencryp.@O@ ahgen.@O@ ahrandom.@O@ \
+ ahrsaenc.@O@ ahrsaepr.@O@ ahrsaepu.@O@ aichdig.@O@ \
+ aichenc8.@O@ aichencn.@O@ aichencr.@O@ aichgen.@O@ \
+ aichrand.@O@ aimd5.@O@ aimd5ran.@O@ ainfotyp.@O@ \
+ ainull.@O@ airsaepr.@O@ airsaepu.@O@ airsakgn.@O@ \
+ airsaprv.@O@ airsapub.@O@ algchoic.@O@ algobj.@O@ \
+ amcrte.@O@ ammd5.@O@ ammd5r.@O@ amrkg.@O@ amrsae.@O@ \
+ balg.@O@ bgclrbit.@O@ bgmdmpyx.@O@ bgmdsqx.@O@ \
+ bgmodexp.@O@ bgpegcd.@O@ big2exp.@O@ bigabs.@O@ \
+ bigacc.@O@ bigarith.@O@ bigcmp.@O@ bigconst.@O@ \
+ biginv.@O@ biglen.@O@ bigmodx.@O@ bigmpy.@O@ \
+ bigpdiv.@O@ bigpmpy.@O@ bigpmpyh.@O@ bigpmpyl.@O@ \
+ bigpsq.@O@ bigqrx.@O@ bigsmod.@O@ bigtocan.@O@ \
+ bigu.@O@ bigunexp.@O@ binfocsh.@O@ bkey.@O@ \
+ bmempool.@O@ cantobig.@O@ crt2.@O@ digest.@O@ \
+ digrand.@O@ encrypt.@O@ generate.@O@ intbits.@O@ \
+ intitem.@O@ keyobj.@O@ ki8byte.@O@ kiitem.@O@ \
+ kinfotyp.@O@ kifulprv.@O@ kipkcrpr.@O@ kirsacrt.@O@ \
+ kirsapub.@O@ md5.@O@ md5rand.@O@ prime.@O@ random.@O@ \
+ rsa.@O@ rsakeygn.@O@ seccbcd.@O@ seccbce.@O@ surrendr.@O@
+
+SRCS = ahchdig.c ahchencr.c ahchgen.c ahchrand.c \
+ ahdigest.c ahencryp.c ahgen.c ahrandom.c \
+ ahrsaenc.c ahrsaepr.c ahrsaepu.c aichdig.c \
+ aichenc8.c aichencn.c aichencr.c aichgen.c \
+ aichrand.c aimd5.c aimd5ran.c ainfotyp.c \
+ ainull.c airsaepr.c airsaepu.c airsakgn.c \
+ airsaprv.c airsapub.c algchoic.c algobj.c \
+ amcrte.c ammd5.c ammd5r.c amrkg.c amrsae.c \
+ balg.c bgclrbit.c bgmdmpyx.c bgmdsqx.c \
+ bgmodexp.c bgpegcd.c big2exp.c bigabs.c \
+ bigacc.c bigarith.c bigcmp.c bigconst.c \
+ biginv.c biglen.c bigmodx.c bigmpy.c \
+ bigpdiv.c bigpmpy.c bigpmpyh.c bigpmpyl.c \
+ bigpsq.c bigqrx.c bigsmod.c bigtocan.c \
+ bigu.c bigunexp.c binfocsh.c bkey.c \
+ bmempool.c cantobig.c crt2.c digest.c \
+ digrand.c encrypt.c generate.c intbits.c \
+ intitem.c keyobj.c ki8byte.c kiitem.c \
+ kinfotyp.c kifulprv.c kipkcrpr.c kirsacrt.c \
+ kirsapub.c md5.c md5rand.c prime.c random.c \
+ rsa.c rsakeygn.c seccbcd.c seccbce.c surrendr.c
+
+SUBDIRS =
+TARGETS = ${OBJS}
+
+@BIND9_MAKE_RULES@
diff --git a/lib/dns/sec/dnssafe/ahcbcpad.c b/lib/dns/sec/dnssafe/ahcbcpad.c
new file mode 100644
index 00000000..5bc74383
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahcbcpad.c
@@ -0,0 +1,174 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+/* Define this so that the type of the 'this' pointer in the
+ virtual functions will be correct for this derived class.
+ */
+struct AHSecretCBCPad;
+#define THIS_ENCRYPT_DECRYPT struct AHSecretCBCPad
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "ahcbcpad.h"
+
+#define GENERATE_BREAK(type) { \
+ status = type; \
+ break; \
+ }
+
+/* Inherit the base class destructor, block size,
+ and decrypt init and update routines.
+ */
+static AHEncryptDecryptVTable V_TABLE = {
+ AHChooseEncryptDestructor, AHChooseEncryptGetBlockLen,
+ AHSecretCBCPadEncryptInit, AHChooseEncryptDecryptInit,
+ AHSecretCBCPadEncryptUpdate, AHChooseEncryptDecryptUpdate,
+ AHSecretCBCPadEncryptFinal, AHSecretCBCPadDecryptFinal
+};
+
+AHSecretCBCPad *AHSecretCBCPadConstructor2 (handler, infoType, info)
+AHSecretCBCPad *handler;
+struct B_AlgorithmInfoType *infoType;
+POINTER info;
+{
+ if (handler == (AHSecretCBCPad *)NULL_PTR) {
+ /* This constructor is being used to do a new */
+ if ((handler = (AHSecretCBCPad *)T_malloc (sizeof (*handler)))
+ == (AHSecretCBCPad *)NULL_PTR)
+ return (handler);
+ }
+
+ /* Construct base class with the infoType and info. */
+ AHChooseEncryptConstructor2
+ (&handler->chooseEncryptDecrypt, infoType, info);
+
+ handler->chooseEncryptDecrypt.encryptDecrypt.vTable = &V_TABLE;
+ return (handler);
+}
+
+int AHSecretCBCPadEncryptInit (handler, key, chooser, surrenderContext)
+AHSecretCBCPad *handler;
+B_Key *key;
+B_ALGORITHM_CHOOSER chooser;
+A_SURRENDER_CTX *surrenderContext;
+{
+ /* For encryption, we need to track the input length */
+ handler->_inputRemainder = 0;
+
+ return (AHChooseEncryptEncryptInit
+ (handler, key, chooser, surrenderContext));
+}
+
+int AHSecretCBCPadEncryptUpdate
+ (handler, partOut, partOutLen, maxPartOutLen, partIn, partInLen,
+ randomAlgorithm, surrenderContext)
+AHSecretCBCPad *handler;
+unsigned char *partOut;
+unsigned int *partOutLen;
+unsigned int maxPartOutLen;
+unsigned char *partIn;
+unsigned int partInLen;
+B_Algorithm *randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ /* For encryption, we need to track the input length */
+ handler->_inputRemainder = (handler->_inputRemainder + partInLen) % 8;
+
+ return (AHChooseEncryptEncryptUpdate
+ (handler, partOut, partOutLen, maxPartOutLen, partIn, partInLen,
+ randomAlgorithm, surrenderContext));
+}
+
+int AHSecretCBCPadEncryptFinal
+ (handler, partOut, partOutLen, maxPartOutLen, randomAlgorithm,
+ surrenderContext)
+AHSecretCBCPad *handler;
+unsigned char *partOut;
+unsigned int *partOutLen;
+unsigned int maxPartOutLen;
+B_Algorithm *randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+ unsigned char finalBuffer[8];
+ unsigned int padLen, dummyPartOutLen;
+
+ padLen = 8 - handler->_inputRemainder;
+ T_memset ((POINTER)finalBuffer, padLen, padLen);
+
+ /* Add the pad bytes. This should force the output of the final block.
+ */
+ if ((status = AHChooseEncryptEncryptUpdate
+ (handler, partOut, partOutLen, maxPartOutLen, finalBuffer, padLen,
+ randomAlgorithm, surrenderContext)) != 0)
+ return (status);
+
+ /* The encrypt final operation should have no output. */
+ if ((status = AHChooseEncryptEncryptFinal
+ (handler, (unsigned char *)NULL_PTR, &dummyPartOutLen, 0,
+ (B_Algorithm *)NULL_PTR, (A_SURRENDER_CTX *)NULL_PTR)) != 0)
+ return (status);
+
+ /* Restart the context. */
+ handler->_inputRemainder = 0;
+
+ /* No need to zeroize the finalBuffer since it only contains pad bytes. */
+ return (0);
+}
+
+int AHSecretCBCPadDecryptFinal
+ (handler, partOut, partOutLen, maxPartOutLen, randomAlgorithm,
+ surrenderContext)
+AHSecretCBCPad *handler;
+unsigned char *partOut;
+unsigned int *partOutLen;
+unsigned int maxPartOutLen;
+B_Algorithm *randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+ unsigned char finalBuffer[16], *padBuffer;
+ unsigned int padLen, localPartOutLen, i;
+
+ do {
+ /* For now, the DecrypyFinal operations is set to output 16 bytes.
+ */
+ if ((status = AHChooseEncryptDecryptFinal
+ (handler, finalBuffer, &localPartOutLen, sizeof (finalBuffer),
+ randomAlgorithm, surrenderContext)) != 0)
+ break;
+
+ if (localPartOutLen == 8)
+ padBuffer = finalBuffer;
+ else if (localPartOutLen == 16)
+ padBuffer = finalBuffer + 8;
+ else
+ GENERATE_BREAK (BE_INPUT_LEN);
+
+ /* Check that padding is one 1 to eight 8's.
+ */
+ if ((padLen = (unsigned int)padBuffer[7]) == 0 || padLen > 8)
+ GENERATE_BREAK (BE_INPUT_DATA);
+ for (i = 8 - padLen; i < 8; i++) {
+ if ((unsigned int)padBuffer[i] != padLen)
+ GENERATE_BREAK (BE_INPUT_DATA);
+ }
+
+ if ((*partOutLen = localPartOutLen - padLen) > maxPartOutLen)
+ GENERATE_BREAK (BE_OUTPUT_LEN);
+
+ T_memcpy
+ ((POINTER)partOut, (POINTER)finalBuffer, *partOutLen);
+ } while (0);
+
+ T_memset ((POINTER)finalBuffer, 0, sizeof (finalBuffer));
+ return (status);
+}
+
diff --git a/lib/dns/sec/dnssafe/ahcbcpad.h b/lib/dns/sec/dnssafe/ahcbcpad.h
new file mode 100644
index 00000000..9daa2435
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahcbcpad.h
@@ -0,0 +1,37 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _AHCBCPAD_H_
+#define _AHCBCPAD_H_
+
+#include "ahchencr.h"
+
+typedef struct AHSecretCBCPad {
+ AHChooseEncryptDecrypt chooseEncryptDecrypt; /* base class */
+
+ unsigned int _inputRemainder; /* Used for encrypt to compute pad length */
+} AHSecretCBCPad;
+
+AHSecretCBCPad *AHSecretCBCPadConstructor2 PROTO_LIST
+ ((AHSecretCBCPad *, struct B_AlgorithmInfoType *, POINTER));
+
+int AHSecretCBCPadEncryptInit PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, B_Key *, B_ALGORITHM_CHOOSER,
+ A_SURRENDER_CTX *));
+int AHSecretCBCPadEncryptUpdate PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *,
+ unsigned int, unsigned char *, unsigned int, B_Algorithm *,
+ A_SURRENDER_CTX *));
+int AHSecretCBCPadEncryptFinal PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *,
+ unsigned int, B_Algorithm *, A_SURRENDER_CTX *));
+int AHSecretCBCPadDecryptFinal PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *,
+ unsigned int, B_Algorithm *, A_SURRENDER_CTX *));
+
+#endif
diff --git a/lib/dns/sec/dnssafe/ahchdig.c b/lib/dns/sec/dnssafe/ahchdig.c
new file mode 100644
index 00000000..8f4b4e23
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahchdig.c
@@ -0,0 +1,130 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+/* Define this so that the type of the 'this' pointer in the
+ virtual functions will be correct for this derived class.
+ */
+struct AHChooseDigest;
+#define THIS_DIGEST struct AHChooseDigest
+
+#include "global.h"
+#include "algae.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "balgmeth.h"
+#include "ahchdig.h"
+#include "amdigest.h"
+
+static int InitDigestAlga PROTO_LIST
+ ((AlgaChoice *, POINTER, B_ALGORITHM_METHOD *, A_SURRENDER_CTX *));
+
+static AHDigestVTable V_TABLE = {
+ AHChooseDigestDestructor, AHChooseDigestInit, AHChooseDigestUpdate,
+ AHChooseDigestFinal
+};
+
+AHChooseDigest *AHChooseDigestConstructor2 (handler, infoType, info)
+AHChooseDigest *handler;
+struct B_AlgorithmInfoType *infoType;
+POINTER info;
+{
+ if (handler == (AHChooseDigest *)NULL_PTR) {
+ /* This constructor is being used to do a new */
+ if ((handler = (AHChooseDigest *)T_malloc (sizeof (*handler)))
+ == (AHChooseDigest *)NULL_PTR)
+ return (handler);
+ }
+
+ /* Construct base class */
+ AHDigestConstructor (&handler->digest);
+
+ ALGA_CHOICE_Constructor (&handler->algaChoice, InitDigestAlga);
+ handler->algaChoice._algorithmInfoType = infoType;
+ handler->algaChoice._algorithmInfo = info;
+
+ handler->digest.vTable = &V_TABLE;
+
+ return (handler);
+}
+
+void AHChooseDigestDestructor (handler)
+AHChooseDigest *handler;
+{
+ ALGA_CHOICE_Destructor (&handler->algaChoice);
+ /* There is no desructor to call for the base class. */
+}
+
+int AHChooseDigestInit (handler, key, chooser, surrenderContext)
+AHChooseDigest *handler;
+B_Key *key;
+B_ALGORITHM_CHOOSER chooser;
+A_SURRENDER_CTX *surrenderContext;
+{
+ return (AlgaChoiceChoose
+ (&handler->algaChoice, 0, key, chooser, surrenderContext));
+}
+
+int AHChooseDigestUpdate (handler, partIn, partInLen, surrenderContext)
+AHChooseDigest *handler;
+unsigned char *partIn;
+unsigned int partInLen;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = (*((A_DIGEST_ALGA *)handler->algaChoice._alga)->Update)
+ (handler->algaChoice.context.z.context, partIn, partInLen,
+ surrenderContext)) != 0)
+ return (ConvertAlgaeError (status));
+ return (0);
+}
+
+int AHChooseDigestFinal
+ (handler, partOut, partOutLen, maxPartOutLen, surrenderContext)
+AHChooseDigest *handler;
+unsigned char *partOut;
+unsigned int *partOutLen;
+unsigned int maxPartOutLen;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = (*((A_DIGEST_ALGA *)handler->algaChoice._alga)->Final)
+ (handler->algaChoice.context.z.context, partOut, partOutLen,
+ maxPartOutLen, surrenderContext)) != 0)
+ return (ConvertAlgaeError (status));
+ return (0);
+}
+
+static int InitDigestAlga
+ (algaChoice, keyInfo, algorithmMethod, surrenderContext)
+AlgaChoice *algaChoice;
+POINTER keyInfo;
+B_ALGORITHM_METHOD *algorithmMethod;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+ unsigned int contextSize;
+
+UNUSED_ARG (keyInfo)
+ if ((status = (*((A_DIGEST_ALGA *)algorithmMethod->alga)->Query)
+ (&contextSize, algaChoice->_algorithmInfo)) != 0)
+ return (ConvertAlgaeError (status));
+
+ if ((status = ResizeContextMakeNewContext
+ (&algaChoice->context, contextSize)) != 0)
+ return (status);
+
+ if ((status = (*((A_DIGEST_ALGA *)algorithmMethod->alga)->Init)
+ (algaChoice->context.z.context, algaChoice->_algorithmInfo,
+ surrenderContext)) != 0)
+ return (ConvertAlgaeError (status));
+
+ return (0);
+}
diff --git a/lib/dns/sec/dnssafe/ahchdig.h b/lib/dns/sec/dnssafe/ahchdig.h
new file mode 100644
index 00000000..d56df5ba
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahchdig.h
@@ -0,0 +1,32 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _AHCHDIG_H_
+#define _AHCHDIG_H_ 1
+
+#include "ahdigest.h"
+#include "algchoic.h"
+
+typedef struct AHChooseDigest {
+ AHDigest digest; /* base class */
+ AlgaChoice algaChoice;
+} AHChooseDigest;
+
+AHChooseDigest *AHChooseDigestConstructor2 PROTO_LIST
+ ((AHChooseDigest *, struct B_AlgorithmInfoType *, POINTER));
+void AHChooseDigestDestructor PROTO_LIST ((THIS_DIGEST *));
+
+int AHChooseDigestInit PROTO_LIST
+ ((THIS_DIGEST *, B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *));
+int AHChooseDigestUpdate PROTO_LIST
+ ((THIS_DIGEST *, unsigned char *, unsigned int, A_SURRENDER_CTX *));
+int AHChooseDigestFinal PROTO_LIST
+ ((THIS_DIGEST *, unsigned char *, unsigned int *, unsigned int,
+ A_SURRENDER_CTX *));
+
+#endif
diff --git a/lib/dns/sec/dnssafe/ahchencr.c b/lib/dns/sec/dnssafe/ahchencr.c
new file mode 100644
index 00000000..64cf959c
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahchencr.c
@@ -0,0 +1,266 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+/* Define this so that the type of the 'this' pointer in the
+ virtual functions will be correct for this derived class.
+ */
+struct AHChooseEncryptDecrypt;
+#define THIS_ENCRYPT_DECRYPT struct AHChooseEncryptDecrypt
+
+#include "global.h"
+#include "algae.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "balgmeth.h"
+#include "ahchencr.h"
+#include "amencdec.h"
+
+static int InitEncryptDecryptAlga PROTO_LIST
+ ((AlgaChoice *, POINTER, B_ALGORITHM_METHOD *, A_SURRENDER_CTX *));
+
+static AHEncryptDecryptVTable V_TABLE = {
+ AHChooseEncryptDestructor, AHChooseEncryptGetBlockLen,
+ AHChooseEncryptEncryptInit, AHChooseEncryptDecryptInit,
+ AHChooseEncryptEncryptUpdate, AHChooseEncryptDecryptUpdate,
+ AHChooseEncryptEncryptFinal, AHChooseEncryptDecryptFinal
+};
+
+/* In C++:
+AHChooseEncryptDecrypt::AHChooseEncryptDecrypt
+ (B_AlgorithmInfoType *infoType, POINTER info)
+ : algaChoice (InitEncryptDecryptAlga)
+{
+ algaChoice.setAlgorithmInfoType (infoType);
+ algaChoice.setAlgorithmInfo (info);
+}
+ */
+AHChooseEncryptDecrypt *AHChooseEncryptConstructor2 (handler, infoType, info)
+AHChooseEncryptDecrypt *handler;
+struct B_AlgorithmInfoType *infoType;
+POINTER info;
+{
+ if (handler == (AHChooseEncryptDecrypt *)NULL_PTR) {
+ /* This constructor is being used to do a new */
+ if ((handler = (AHChooseEncryptDecrypt *)T_malloc (sizeof (*handler)))
+ == (AHChooseEncryptDecrypt *)NULL_PTR)
+ return (handler);
+ }
+
+ /* Construct base class */
+ AHEncryptDecryptConstructor (&handler->encryptDecrypt);
+
+ ALGA_CHOICE_Constructor (&handler->algaChoice, InitEncryptDecryptAlga);
+ handler->algaChoice._algorithmInfoType = infoType;
+ handler->algaChoice._algorithmInfo = info;
+
+ handler->encryptDecrypt.vTable = &V_TABLE;
+
+ return (handler);
+}
+
+void AHChooseEncryptDestructor (handler)
+AHChooseEncryptDecrypt *handler;
+{
+ ALGA_CHOICE_Destructor (&handler->algaChoice);
+ /* There is no desructor to call for the base class. */
+}
+
+int AHChooseEncryptGetBlockLen (handler, blockLen)
+AHChooseEncryptDecrypt *handler;
+unsigned int *blockLen;
+{
+ int status;
+
+ if ((status = (*((A_ENCRYPT_DECRYPT_ALGA *)handler->algaChoice._alga)->
+ GetBlockLen)
+ (handler->algaChoice.context.z.context, blockLen)) != 0)
+ return (ConvertAlgaeError (status));
+ return (0);
+}
+
+/* In C++:
+int AHChooseEncryptDecrypt::encryptInit
+ (B_Key *key, B_ALGORITHM_CHOOSER chooser, A_SURRENDER_CTX *surrenderContext)
+{
+ return (algaChoice.choose (1, key, chooser, surrenderContext));
+}
+ */
+int AHChooseEncryptEncryptInit (handler, key, chooser, surrenderContext)
+AHChooseEncryptDecrypt *handler;
+B_Key *key;
+B_ALGORITHM_CHOOSER chooser;
+A_SURRENDER_CTX *surrenderContext;
+{
+ return (AlgaChoiceChoose
+ (&handler->algaChoice, 1, key, chooser, surrenderContext));
+}
+
+int AHChooseEncryptDecryptInit (handler, key, chooser, surrenderContext)
+AHChooseEncryptDecrypt *handler;
+B_Key *key;
+B_ALGORITHM_CHOOSER chooser;
+A_SURRENDER_CTX *surrenderContext;
+{
+ return (AlgaChoiceChoose
+ (&handler->algaChoice, 0, key, chooser, surrenderContext));
+}
+
+/* In C++:
+int AHChooseEncryptDecrypt::encryptUpdate
+ (unsigned char *partOut, unsigned int *partOutLen,
+ unsigned int maxPartOutLen, unsigned char *partIn, unsigned int partInLen,
+ B_Algorithm *randomAlgorithm, A_SURRENDER_CTX *surrenderContext)
+{
+ int status;
+
+ if ((status = (*((A_ENCRYPT_DECRYPT_ALGA *)algaChoice.alga ()) ->Update)
+ (algaChoice.context (), partOut, partOutLen, maxPartOutLen,
+ partIn, partInLen, surrenderContext)) != 0)
+ return (ConvertAlgaeError (status));
+ return (0);
+}
+ */
+int AHChooseEncryptEncryptUpdate
+ (handler, partOut, partOutLen, maxPartOutLen, partIn, partInLen,
+ randomAlgorithm, surrenderContext)
+AHChooseEncryptDecrypt *handler;
+unsigned char *partOut;
+unsigned int *partOutLen;
+unsigned int maxPartOutLen;
+unsigned char *partIn;
+unsigned int partInLen;
+B_Algorithm *randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+UNUSED_ARG (randomAlgorithm)
+
+ if ((status = (*((A_ENCRYPT_DECRYPT_ALGA *)handler->algaChoice._alga)->
+ Update)
+ (handler->algaChoice.context.z.context, partOut, partOutLen,
+ maxPartOutLen, partIn, partInLen, surrenderContext)) != 0)
+ return (ConvertAlgaeError (status));
+ return (0);
+}
+
+int AHChooseEncryptDecryptUpdate
+ (handler, partOut, partOutLen, maxPartOutLen, partIn, partInLen,
+ randomAlgorithm, surrenderContext)
+AHChooseEncryptDecrypt *handler;
+unsigned char *partOut;
+unsigned int *partOutLen;
+unsigned int maxPartOutLen;
+unsigned char *partIn;
+unsigned int partInLen;
+B_Algorithm *randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+UNUSED_ARG (randomAlgorithm)
+
+ if ((status = (*((A_ENCRYPT_DECRYPT_ALGA *)handler->algaChoice._alga)->
+ Update)
+ (handler->algaChoice.context.z.context, partOut, partOutLen,
+ maxPartOutLen, partIn, partInLen, surrenderContext)) != 0)
+ return (ConvertAlgaeError (status));
+ return (0);
+}
+
+int AHChooseEncryptEncryptFinal
+ (handler, partOut, partOutLen, maxPartOutLen, randomAlgorithm,
+ surrenderContext)
+AHChooseEncryptDecrypt *handler;
+unsigned char *partOut;
+unsigned int *partOutLen;
+unsigned int maxPartOutLen;
+B_Algorithm *randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+UNUSED_ARG (randomAlgorithm)
+
+ if ((status = (*((A_ENCRYPT_DECRYPT_ALGA *)handler->algaChoice._alga)->Final)
+ (handler->algaChoice.context.z.context, partOut, partOutLen,
+ maxPartOutLen, surrenderContext)) != 0)
+ return (ConvertAlgaeError (status));
+ return (0);
+}
+
+int AHChooseEncryptDecryptFinal
+ (handler, partOut, partOutLen, maxPartOutLen, randomAlgorithm,
+ surrenderContext)
+AHChooseEncryptDecrypt *handler;
+unsigned char *partOut;
+unsigned int *partOutLen;
+unsigned int maxPartOutLen;
+B_Algorithm *randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+UNUSED_ARG (randomAlgorithm)
+
+ if ((status = (*((A_ENCRYPT_DECRYPT_ALGA *)handler->algaChoice._alga)->Final)
+ (handler->algaChoice.context.z.context, partOut, partOutLen,
+ maxPartOutLen, surrenderContext)) != 0)
+ return (ConvertAlgaeError (status));
+ return (0);
+}
+
+/* In C++:
+static int InitEncryptDecryptAlga
+ (AlgaChoice *algaChoice, POINTER keyInfo, POINTER alga,
+ A_SURRENDER_CTX *surrenderContext)
+{
+ int status;
+ unsigned int contextSize;
+
+ if ((status = (*((A_ENCRYPT_DECRYPT_ALGA *)alga)->Query)
+ (&contextSize, keyInfo, algaChoice->algorithmInfo ())) != 0)
+ return (ConvertAlgaeError (status));
+
+ if ((status = algaChoice->makeNewContext (contextSize)) != 0)
+ return (status);
+
+ if ((status = (*((A_ENCRYPT_DECRYPT_ALGA *)alga)->Init)
+ (algaChoice->context (), keyInfo, algaChoice->algorithmInfo (),
+ surrenderContext)) != 0)
+ return (ConvertAlgaeError (status));
+
+ return (0);
+}
+ */
+static int InitEncryptDecryptAlga
+ (algaChoice, keyInfo, algorithmMethod, surrenderContext)
+AlgaChoice *algaChoice;
+POINTER keyInfo;
+B_ALGORITHM_METHOD *algorithmMethod;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+ unsigned int contextSize;
+
+ if ((status = (*((A_ENCRYPT_DECRYPT_ALGA *)algorithmMethod->alga)->Query)
+ (&contextSize, keyInfo, algaChoice->_algorithmInfo)) != 0)
+ return (ConvertAlgaeError (status));
+
+ if ((status = ResizeContextMakeNewContext
+ (&algaChoice->context, contextSize)) != 0)
+ return (status);
+
+ if ((status = (*((A_ENCRYPT_DECRYPT_ALGA *)algorithmMethod->alga)->Init)
+ (algaChoice->context.z.context, keyInfo, algaChoice->_algorithmInfo,
+ surrenderContext)) != 0)
+ return (ConvertAlgaeError (status));
+
+ return (0);
+}
diff --git a/lib/dns/sec/dnssafe/ahchencr.h b/lib/dns/sec/dnssafe/ahchencr.h
new file mode 100644
index 00000000..4befa783
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahchencr.h
@@ -0,0 +1,74 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _AHCHENCR_H_
+#define _AHCHENCR_H_ 1
+
+#include "ahencryp.h"
+#include "algchoic.h"
+
+/* In C++:
+class AHChooseEncryptDecrypt : public AHEncryptDecrypt {
+public:
+ AHChooseEncryptDecrypt (B_AlgorithmInfoType *, POINTER);
+ virtual ~AHChooseEncryptDecrypt () {};
+
+ virtual int getBlockLen (unsigned int *);
+ virtual int encryptInit (B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *);
+ virtual int decryptInit (B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *);
+ virtual int encryptUpdate
+ (unsigned char *, unsigned int *, unsigned int, unsigned char *,
+ unsigned int, B_Algorithm *, A_SURRENDER_CTX *);
+ virtual int decryptUpdate
+ (unsigned char *, unsigned int *, unsigned int, unsigned char *,
+ unsigned int, B_Algorithm *, A_SURRENDER_CTX *);
+ virtual int encryptFinal
+ (unsigned char *, unsigned int *, unsigned int, B_Algorithm *,
+ A_SURRENDER_CTX *);
+ virtual int decryptFinal
+ (unsigned char *, unsigned int *, unsigned int, B_Algorithm *,
+ A_SURRENDER_CTX *);
+
+private:
+ AlgaChoice algaChoice;
+};
+ */
+
+typedef struct AHChooseEncryptDecrypt {
+ AHEncryptDecrypt encryptDecrypt; /* base class */
+ AlgaChoice algaChoice;
+} AHChooseEncryptDecrypt;
+
+AHChooseEncryptDecrypt *AHChooseEncryptConstructor2 PROTO_LIST
+ ((AHChooseEncryptDecrypt *, struct B_AlgorithmInfoType *, POINTER));
+void AHChooseEncryptDestructor PROTO_LIST ((THIS_ENCRYPT_DECRYPT *));
+
+int AHChooseEncryptGetBlockLen PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, unsigned int *));
+int AHChooseEncryptEncryptInit PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, B_Key *, B_ALGORITHM_CHOOSER,
+ A_SURRENDER_CTX *));
+int AHChooseEncryptDecryptInit PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, B_Key *, B_ALGORITHM_CHOOSER,
+ A_SURRENDER_CTX *));
+int AHChooseEncryptEncryptUpdate PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *,
+ unsigned int, unsigned char *, unsigned int, B_Algorithm *,
+ A_SURRENDER_CTX *));
+int AHChooseEncryptDecryptUpdate PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *,
+ unsigned int, unsigned char *, unsigned int, B_Algorithm *,
+ A_SURRENDER_CTX *));
+int AHChooseEncryptEncryptFinal PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *,
+ unsigned int, B_Algorithm *, A_SURRENDER_CTX *));
+int AHChooseEncryptDecryptFinal PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *,
+ unsigned int, B_Algorithm *, A_SURRENDER_CTX *));
+
+#endif
diff --git a/lib/dns/sec/dnssafe/ahchgen.c b/lib/dns/sec/dnssafe/ahchgen.c
new file mode 100644
index 00000000..f1d7bd7c
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahchgen.c
@@ -0,0 +1,216 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+/* Define this so that the type of the 'this' pointer in the
+ virtual functions will be correct for this derived class.
+ */
+struct AHChooseGenerate;
+#define THIS_GENERATE struct AHChooseGenerate
+
+/* Define this so that the type of the AlgaChoice pointer in the
+ INIT_ALGA functions will be correct for this derived class.
+ */
+struct GenerateAlgaChoice;
+#define THIS_ALGA_CHOICE struct GenerateAlgaChoice
+
+#include "global.h"
+#include "algae.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "balgmeth.h"
+#include "ahchgen.h"
+#include "amgen.h"
+
+static int InitGenerateAlga PROTO_LIST
+ ((GenerateAlgaChoice *, POINTER, B_ALGORITHM_METHOD *, A_SURRENDER_CTX *));
+static int GenerateResult PROTO_LIST
+ ((GenerateAlgaChoice *, POINTER *, B_Algorithm *, A_SURRENDER_CTX *));
+
+static AHGenerateVTable V_TABLE = {
+ AHChooseGenerateDestructor, AHChooseGenerateInit, AHChooseGenerateKeypair,
+ AHChooseGenerateParameters
+};
+
+AHChooseGenerate *AHChooseGenerateConstructor2 (handler, infoType, info)
+AHChooseGenerate *handler;
+struct B_AlgorithmInfoType *infoType;
+POINTER info;
+{
+ if (handler == (AHChooseGenerate *)NULL_PTR) {
+ /* This constructor is being used to do a new */
+ if ((handler = (AHChooseGenerate *)T_malloc (sizeof (*handler)))
+ == (AHChooseGenerate *)NULL_PTR)
+ return (handler);
+ }
+
+ /* Construct base class */
+ AHGenerateConstructor (&handler->generate);
+
+ ALGA_CHOICE_Constructor
+ (&handler->generateAlgaChoice.algaChoice, InitGenerateAlga);
+ ResizeContextConstructor (&handler->generateAlgaChoice.secondContext);
+ ResizeContextConstructor (&handler->generateAlgaChoice.randomBlock);
+
+ /* Set algaChoice.
+ */
+ handler->generateAlgaChoice.algaChoice._algorithmInfoType = infoType;
+ handler->generateAlgaChoice.algaChoice._algorithmInfo = info;
+
+ handler->generate.vTable = &V_TABLE;
+
+ return (handler);
+}
+
+void AHChooseGenerateDestructor (handler)
+AHChooseGenerate *handler;
+{
+ ResizeContextDestructor (&handler->generateAlgaChoice.secondContext);
+ ResizeContextDestructor (&handler->generateAlgaChoice.randomBlock);
+ ALGA_CHOICE_Destructor (&handler->generateAlgaChoice.algaChoice);
+ /* There is no desructor to call for the base class. */
+}
+
+int AHChooseGenerateInit (handler, chooser, surrenderContext)
+AHChooseGenerate *handler;
+B_ALGORITHM_CHOOSER chooser;
+A_SURRENDER_CTX *surrenderContext;
+{
+ return (AlgaChoiceChoose
+ (&handler->generateAlgaChoice.algaChoice, 0, (B_Key *)NULL_PTR,
+ chooser, surrenderContext));
+}
+
+int AHChooseGenerateKeypair
+ (handler, publicKey, privateKey, randomAlgorithm, surrenderContext)
+AHChooseGenerate *handler;
+B_Key *publicKey;
+B_Key *privateKey;
+B_Algorithm *randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ POINTER result;
+ int status;
+
+ if ((status = GenerateResult
+ (&handler->generateAlgaChoice, &result, randomAlgorithm,
+ surrenderContext)) != 0)
+ return (status);
+ if ((status = B_KeySetInfo
+ (publicKey, handler->generateAlgaChoice._resultInfoType, result)) != 0)
+ return (status);
+ return (B_KeySetInfo
+ (privateKey, handler->generateAlgaChoice._resultInfoType, result));
+}
+
+int AHChooseGenerateParameters
+ (handler, resultAlgorithm, randomAlgorithm, surrenderContext)
+AHChooseGenerate *handler;
+B_Algorithm *resultAlgorithm;
+B_Algorithm *randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ POINTER result;
+ int status;
+
+ if ((status = GenerateResult
+ (&handler->generateAlgaChoice, &result, randomAlgorithm,
+ surrenderContext)) != 0)
+ return (status);
+
+ /* Force the resultInfoType into a B_AlgorithmInfoType since it is
+ supplied in the chooser as a B_KeyInfoType. */
+ return (B_AlgorithmSetInfo
+ (resultAlgorithm, (struct B_AlgorithmInfoType *)
+ handler->generateAlgaChoice._resultInfoType, result));
+}
+
+static int InitGenerateAlga
+ (generateAlgaChoice, keyInfo, algorithmMethod, surrenderContext)
+GenerateAlgaChoice *generateAlgaChoice;
+POINTER keyInfo;
+B_ALGORITHM_METHOD *algorithmMethod;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+ unsigned int contextSize, secondContextSize;
+
+UNUSED_ARG (keyInfo)
+ /* Note that this also gets the resultInfoType which will be used later
+ by GenerateResult. */
+ if ((status = (*((A_GENERATE_ALGA *)algorithmMethod->alga)->Query)
+ (&contextSize, &secondContextSize, &generateAlgaChoice->_randomBlockLen,
+ &generateAlgaChoice->_resultInfoType,
+ generateAlgaChoice->algaChoice._algorithmInfo)) != 0)
+ return (ConvertAlgaeError (status));
+
+ /* Create the context.
+ */
+ if ((status = ResizeContextMakeNewContext
+ (&generateAlgaChoice->algaChoice.context, contextSize)) != 0)
+ return (status);
+
+ /* Create the second context which is only passed during Init, but
+ must persist for all operations. */
+ if ((status = ResizeContextMakeNewContext
+ (&generateAlgaChoice->secondContext, secondContextSize)) != 0)
+ return (status);
+
+ /* Create randomBlock which will be filled in during GenerateResult. */
+ if ((status = ResizeContextMakeNewContext
+ (&generateAlgaChoice->randomBlock, generateAlgaChoice->_randomBlockLen))
+ != 0)
+ return (status);
+
+ if ((status = (*((A_GENERATE_ALGA *)algorithmMethod->alga)->Init)
+ (generateAlgaChoice->algaChoice.context.z.context,
+ generateAlgaChoice->secondContext.z.context,
+ generateAlgaChoice->algaChoice._algorithmInfo, surrenderContext)) != 0)
+ return (ConvertAlgaeError (status));
+
+ return (0);
+}
+
+/* Call the generate procedure repeatedly with a new random block
+ until it succeeds.
+ */
+static int GenerateResult
+ (generateAlgaChoice, result, randomAlgorithm, surrenderContext)
+GenerateAlgaChoice *generateAlgaChoice;
+POINTER *result;
+B_Algorithm *randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ /* Fill in the random block and try generating as long as the
+ the generate operation returns BE_NEED_RANDOM.
+ */
+ do {
+ if ((status = B_AlgorithmGenerateRandomBytes
+ (randomAlgorithm,
+ (unsigned char *)generateAlgaChoice->randomBlock.z.context,
+ generateAlgaChoice->_randomBlockLen, surrenderContext)) != 0)
+ return (status);
+
+ if ((status = (*((A_GENERATE_ALGA *)
+ generateAlgaChoice->algaChoice._alga)->Generate)
+ (generateAlgaChoice->algaChoice.context.z.context, result,
+ (unsigned char *)generateAlgaChoice->randomBlock.z.context,
+ surrenderContext)) != 0) {
+ if (status != AE_NEED_RANDOM)
+ return (ConvertAlgaeError (status));
+
+ /* Else continue and try again */
+ }
+ else
+ /* Success, so return */
+ return (0);
+ } while (1);
+}
+
diff --git a/lib/dns/sec/dnssafe/ahchgen.h b/lib/dns/sec/dnssafe/ahchgen.h
new file mode 100644
index 00000000..8e7ecf3d
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahchgen.h
@@ -0,0 +1,44 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _AHCHGEN_H_
+#define _AHCHGEN_H_ 1
+
+#include "ahgen.h"
+#include "algchoic.h"
+
+/* Make a new class derived from an AlgaChoice which records the
+ result algorithm info type and needed randomBlockLen.
+ */
+typedef struct GenerateAlgaChoice {
+ AlgaChoice algaChoice; /* base class */
+
+ struct B_KeyInfoType *_resultInfoType;
+ ResizeContext secondContext; /* used for scratch */
+ ResizeContext randomBlock;
+ unsigned int _randomBlockLen;
+} GenerateAlgaChoice;
+
+typedef struct AHChooseGenerate {
+ AHGenerate generate; /* base class */
+
+ GenerateAlgaChoice generateAlgaChoice;
+} AHChooseGenerate;
+
+AHChooseGenerate *AHChooseGenerateConstructor2 PROTO_LIST
+ ((AHChooseGenerate *, struct B_AlgorithmInfoType *, POINTER));
+void AHChooseGenerateDestructor PROTO_LIST ((THIS_GENERATE *));
+
+int AHChooseGenerateInit PROTO_LIST
+ ((THIS_GENERATE *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *));
+int AHChooseGenerateKeypair PROTO_LIST
+ ((THIS_GENERATE *, B_Key *, B_Key *, B_Algorithm *, A_SURRENDER_CTX *));
+int AHChooseGenerateParameters PROTO_LIST
+ ((THIS_GENERATE *, B_Algorithm *, B_Algorithm *, A_SURRENDER_CTX *));
+
+#endif
diff --git a/lib/dns/sec/dnssafe/ahchrand.c b/lib/dns/sec/dnssafe/ahchrand.c
new file mode 100644
index 00000000..e565a1d9
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahchrand.c
@@ -0,0 +1,128 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+/* Define this so that the type of the 'this' pointer in the
+ virtual functions will be correct for this derived class.
+ */
+struct AHChooseRandom;
+#define THIS_RANDOM struct AHChooseRandom
+
+#include "global.h"
+#include "algae.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "balgmeth.h"
+#include "ahchrand.h"
+#include "amrandom.h"
+
+static int InitRandomAlga PROTO_LIST
+ ((AlgaChoice *, POINTER, B_ALGORITHM_METHOD *, A_SURRENDER_CTX *));
+
+static AHRandomVTable V_TABLE = {
+ AHChooseRandomDestructor, AHChooseRandomInit, AHChooseRandomUpdate,
+ AHChooseRandomGenerateBytes
+};
+
+AHChooseRandom *AHChooseRandomConstructor2 (handler, infoType, info)
+AHChooseRandom *handler;
+struct B_AlgorithmInfoType *infoType;
+POINTER info;
+{
+ if (handler == (AHChooseRandom *)NULL_PTR) {
+ /* This constructor is being used to do a new */
+ if ((handler = (AHChooseRandom *)T_malloc (sizeof (*handler)))
+ == (AHChooseRandom *)NULL_PTR)
+ return (handler);
+ }
+
+ /* Construct base class */
+ AHRandomConstructor (&handler->random);
+
+ ALGA_CHOICE_Constructor (&handler->algaChoice, InitRandomAlga);
+ handler->algaChoice._algorithmInfoType = infoType;
+ handler->algaChoice._algorithmInfo = info;
+
+ handler->random.vTable = &V_TABLE;
+
+ return (handler);
+}
+
+void AHChooseRandomDestructor (handler)
+AHChooseRandom *handler;
+{
+ ALGA_CHOICE_Destructor (&handler->algaChoice);
+ /* There is no desructor to call for the base class. */
+}
+
+int AHChooseRandomInit (handler, chooser, surrenderContext)
+AHChooseRandom *handler;
+B_ALGORITHM_CHOOSER chooser;
+A_SURRENDER_CTX *surrenderContext;
+{
+ return (AlgaChoiceChoose
+ (&handler->algaChoice, 0, (B_Key *)NULL_PTR, chooser,
+ surrenderContext));
+}
+
+int AHChooseRandomUpdate (handler, input, inputLen, surrenderContext)
+AHChooseRandom *handler;
+unsigned char *input;
+unsigned int inputLen;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = (*((A_RANDOM_ALGA *)handler->algaChoice._alga)->Update)
+ (handler->algaChoice.context.z.context, input, inputLen,
+ surrenderContext)) != 0)
+ return (ConvertAlgaeError (status));
+ return (0);
+}
+
+int AHChooseRandomGenerateBytes (handler, output, outputLen, surrenderContext)
+AHChooseRandom *handler;
+unsigned char *output;
+unsigned int outputLen;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = (*((A_RANDOM_ALGA *)handler->algaChoice._alga)->Generate)
+ (handler->algaChoice.context.z.context, output, outputLen,
+ surrenderContext)) != 0)
+ return (ConvertAlgaeError (status));
+ return (0);
+}
+
+static int InitRandomAlga
+ (algaChoice, keyInfo, algorithmMethod, surrenderContext)
+AlgaChoice *algaChoice;
+POINTER keyInfo;
+B_ALGORITHM_METHOD *algorithmMethod;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+ unsigned int contextSize;
+
+UNUSED_ARG (keyInfo)
+ if ((status = (*((A_RANDOM_ALGA *)algorithmMethod->alga)->Query)
+ (&contextSize, algaChoice->_algorithmInfo)) != 0)
+ return (ConvertAlgaeError (status));
+
+ if ((status = ResizeContextMakeNewContext
+ (&algaChoice->context, contextSize)) != 0)
+ return (status);
+
+ if ((status = (*((A_RANDOM_ALGA *)algorithmMethod->alga)->Init)
+ (algaChoice->context.z.context, algaChoice->_algorithmInfo,
+ surrenderContext)) != 0)
+ return (ConvertAlgaeError (status));
+
+ return (0);
+}
diff --git a/lib/dns/sec/dnssafe/ahchrand.h b/lib/dns/sec/dnssafe/ahchrand.h
new file mode 100644
index 00000000..51e0f984
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahchrand.h
@@ -0,0 +1,31 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _AHCHRAND_H_
+#define _AHCHRAND_H_ 1
+
+#include "ahrandom.h"
+#include "algchoic.h"
+
+typedef struct AHChooseRandom {
+ AHRandom random; /* base class */
+ AlgaChoice algaChoice;
+} AHChooseRandom;
+
+AHChooseRandom *AHChooseRandomConstructor2 PROTO_LIST
+ ((AHChooseRandom *, struct B_AlgorithmInfoType *, POINTER));
+void AHChooseRandomDestructor PROTO_LIST ((THIS_RANDOM *));
+
+int AHChooseRandomInit PROTO_LIST
+ ((THIS_RANDOM *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *));
+int AHChooseRandomUpdate PROTO_LIST
+ ((THIS_RANDOM *, unsigned char *, unsigned int, A_SURRENDER_CTX *));
+int AHChooseRandomGenerateBytes PROTO_LIST
+ ((THIS_RANDOM *, unsigned char *, unsigned int, A_SURRENDER_CTX *));
+
+#endif
diff --git a/lib/dns/sec/dnssafe/ahdigest.c b/lib/dns/sec/dnssafe/ahdigest.c
new file mode 100644
index 00000000..b1dc9f46
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahdigest.c
@@ -0,0 +1,91 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "ahdigest.h"
+
+static void TypedAHDigestDestructor PROTO_LIST ((B_TypeCheck *));
+
+void AHDigestConstructor (handler)
+AHDigest *handler;
+{
+ /* Construct base class, setting type tag. */
+ B_TYPE_CHECK_Constructor
+ (&handler->typeCheck, TypedAHDigestDestructor);
+
+ /* Don't set vTable since this is a pure virtual base class. */
+}
+
+int B_AlgorithmDigestInit
+ (algorithm, key, algorithmChooser, surrenderContext)
+B_Algorithm *algorithm;
+B_Key *key;
+B_ALGORITHM_CHOOSER algorithmChooser;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = B_AlgorithmCheckType
+ (algorithm, TypedAHDigestDestructor)) != 0)
+ return (status);
+
+ if ((status =
+ (*((AHDigest *)algorithm->z.handler)->vTable->DigestInit)
+ ((AHDigest *)algorithm->z.handler, key, algorithmChooser,
+ surrenderContext)) != 0)
+ return (status);
+
+ algorithm->z.initFlag = 1;
+ return (0);
+}
+
+int B_AlgorithmDigestUpdate (algorithm, partIn, partInLen, surrenderContext)
+B_Algorithm *algorithm;
+unsigned char *partIn;
+unsigned int partInLen;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = B_AlgorithmCheckTypeAndInitFlag
+ (algorithm, TypedAHDigestDestructor)) != 0)
+ return (status);
+
+ return ((*((AHDigest *)algorithm->z.handler)->vTable->DigestUpdate)
+ ((AHDigest *)algorithm->z.handler, partIn, partInLen,
+ surrenderContext));
+}
+
+int B_AlgorithmDigestFinal
+ (algorithm, partOut, partOutLen, maxPartOutLen, surrenderContext)
+B_Algorithm *algorithm;
+unsigned char *partOut;
+unsigned int *partOutLen;
+unsigned int maxPartOutLen;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = B_AlgorithmCheckTypeAndInitFlag
+ (algorithm, TypedAHDigestDestructor)) != 0)
+ return (status);
+
+ return ((*((AHDigest *)algorithm->z.handler)->vTable->DigestFinal)
+ ((AHDigest *)algorithm->z.handler, partOut, partOutLen,
+ maxPartOutLen, surrenderContext));
+}
+
+static void TypedAHDigestDestructor (typeCheck)
+B_TypeCheck *typeCheck;
+{
+ (*((AHDigest *)typeCheck)->vTable->Destructor) ((AHDigest *)typeCheck);
+}
+
diff --git a/lib/dns/sec/dnssafe/ahdigest.h b/lib/dns/sec/dnssafe/ahdigest.h
new file mode 100644
index 00000000..d7cc5f93
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahdigest.h
@@ -0,0 +1,48 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _AHDIGEST_H_
+#define _AHDIGEST_H_ 1
+
+#include "btypechk.h"
+
+/* Use the THIS_DIGEST macro to define the type of object in the
+ virtual function prototype. It defaults to the most base class, but
+ derived modules may define the macro to a more derived class before
+ including this header file.
+ */
+#ifndef THIS_DIGEST
+#define THIS_DIGEST struct AHDigest
+#endif
+
+struct AHDigest;
+
+typedef struct {
+ void (*Destructor) PROTO_LIST ((THIS_DIGEST *));
+ int (*DigestInit) PROTO_LIST
+ ((THIS_DIGEST *, B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *));
+ int (*DigestUpdate) PROTO_LIST
+ ((THIS_DIGEST *, unsigned char *, unsigned int, A_SURRENDER_CTX *));
+ int (*DigestFinal) PROTO_LIST
+ ((THIS_DIGEST *, unsigned char *, unsigned int *, unsigned int,
+ A_SURRENDER_CTX *));
+} AHDigestVTable;
+
+typedef struct AHDigest {
+ B_TypeCheck typeCheck; /* inherited */
+ AHDigestVTable *vTable; /* pure virtual */
+} AHDigest;
+
+/* The constructor does not set the vTable since this is a pure base class.
+ */
+void AHDigestConstructor PROTO_LIST ((AHDigest *));
+/* No destructor because it is pure virtual. Also, do not call destructor
+ for B_TypeCheck, since this will just re-invoke this virtual
+ destructor. */
+
+#endif
diff --git a/lib/dns/sec/dnssafe/ahencryp.c b/lib/dns/sec/dnssafe/ahencryp.c
new file mode 100644
index 00000000..255a5491
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahencryp.c
@@ -0,0 +1,169 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "ahencryp.h"
+
+static void TypedAHEncryptDecryptDestructor PROTO_LIST ((B_TypeCheck *));
+
+void AHEncryptDecryptConstructor (handler)
+AHEncryptDecrypt *handler;
+{
+ /* Construct base class, setting type tag. */
+ B_TYPE_CHECK_Constructor
+ (&handler->typeCheck, TypedAHEncryptDecryptDestructor);
+
+ /* Don't set vTable since this is a pure virtual base class. */
+}
+
+int B_AlgorithmEncryptInit
+ (algorithm, key, algorithmChooser, surrenderContext)
+B_Algorithm *algorithm;
+B_Key *key;
+B_ALGORITHM_CHOOSER algorithmChooser;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = B_AlgorithmCheckType
+ (algorithm, TypedAHEncryptDecryptDestructor)) != 0)
+ return (status);
+
+ if ((status =
+ (*((AHEncryptDecrypt *)algorithm->z.handler)->vTable->EncryptInit)
+ ((AHEncryptDecrypt *)algorithm->z.handler, key, algorithmChooser,
+ surrenderContext)) != 0)
+ return (status);
+
+ algorithm->z.initFlag = 1;
+ return (0);
+}
+
+int B_AlgorithmDecryptInit
+ (algorithm, key, algorithmChooser, surrenderContext)
+B_Algorithm *algorithm;
+B_Key *key;
+B_ALGORITHM_CHOOSER algorithmChooser;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = B_AlgorithmCheckType
+ (algorithm, TypedAHEncryptDecryptDestructor)) != 0)
+ return (status);
+
+ if ((status =
+ (*((AHEncryptDecrypt *)algorithm->z.handler)->vTable->DecryptInit)
+ ((AHEncryptDecrypt *)algorithm->z.handler, key, algorithmChooser,
+ surrenderContext)) != 0)
+ return (status);
+
+ algorithm->z.initFlag = 1;
+ return (0);
+}
+
+int B_AlgorithmEncryptUpdate
+ (algorithm, partOut, partOutLen, maxPartOutLen, partIn, partInLen,
+ randomAlgorithm, surrenderContext)
+B_Algorithm *algorithm;
+unsigned char *partOut;
+unsigned int *partOutLen;
+unsigned int maxPartOutLen;
+unsigned char *partIn;
+unsigned int partInLen;
+B_Algorithm *randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = B_AlgorithmCheckTypeAndInitFlag
+ (algorithm, TypedAHEncryptDecryptDestructor)) != 0)
+ return (status);
+
+ return ((*((AHEncryptDecrypt *)algorithm->z.handler)->vTable->EncryptUpdate)
+ ((AHEncryptDecrypt *)algorithm->z.handler, partOut, partOutLen,
+ maxPartOutLen, partIn, partInLen, randomAlgorithm,
+ surrenderContext));
+}
+
+int B_AlgorithmDecryptUpdate
+ (algorithm, partOut, partOutLen, maxPartOutLen, partIn, partInLen,
+ randomAlgorithm, surrenderContext)
+B_Algorithm *algorithm;
+unsigned char *partOut;
+unsigned int *partOutLen;
+unsigned int maxPartOutLen;
+unsigned char *partIn;
+unsigned int partInLen;
+B_Algorithm *randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = B_AlgorithmCheckTypeAndInitFlag
+ (algorithm, TypedAHEncryptDecryptDestructor)) != 0)
+ return (status);
+
+ return ((*((AHEncryptDecrypt *)algorithm->z.handler)->vTable->DecryptUpdate)
+ ((AHEncryptDecrypt *)algorithm->z.handler, partOut, partOutLen,
+ maxPartOutLen, partIn, partInLen, randomAlgorithm,
+ surrenderContext));
+}
+
+int B_AlgorithmEncryptFinal
+ (algorithm, partOut, partOutLen, maxPartOutLen, randomAlgorithm,
+ surrenderContext)
+B_Algorithm *algorithm;
+unsigned char *partOut;
+unsigned int *partOutLen;
+unsigned int maxPartOutLen;
+B_Algorithm *randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = B_AlgorithmCheckTypeAndInitFlag
+ (algorithm, TypedAHEncryptDecryptDestructor)) != 0)
+ return (status);
+
+ return ((*((AHEncryptDecrypt *)algorithm->z.handler)->vTable->EncryptFinal)
+ ((AHEncryptDecrypt *)algorithm->z.handler, partOut, partOutLen,
+ maxPartOutLen, randomAlgorithm, surrenderContext));
+}
+
+int B_AlgorithmDecryptFinal
+ (algorithm, partOut, partOutLen, maxPartOutLen, randomAlgorithm,
+ surrenderContext)
+B_Algorithm *algorithm;
+unsigned char *partOut;
+unsigned int *partOutLen;
+unsigned int maxPartOutLen;
+B_Algorithm *randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = B_AlgorithmCheckTypeAndInitFlag
+ (algorithm, TypedAHEncryptDecryptDestructor)) != 0)
+ return (status);
+
+ return ((*((AHEncryptDecrypt *)algorithm->z.handler)->vTable->DecryptFinal)
+ ((AHEncryptDecrypt *)algorithm->z.handler, partOut, partOutLen,
+ maxPartOutLen, randomAlgorithm, surrenderContext));
+}
+
+static void TypedAHEncryptDecryptDestructor (typeCheck)
+B_TypeCheck *typeCheck;
+{
+ (*((AHEncryptDecrypt *)typeCheck)->vTable->Destructor)
+ ((AHEncryptDecrypt *)typeCheck);
+}
+
diff --git a/lib/dns/sec/dnssafe/ahencryp.h b/lib/dns/sec/dnssafe/ahencryp.h
new file mode 100644
index 00000000..f7ab14ca
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahencryp.h
@@ -0,0 +1,85 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _AHENCRYP_H_
+#define _AHENCRYP_H_ 1
+
+#include "btypechk.h"
+
+/* In C++:
+class AHEncryptDecrypt : public B_TypeCheck {
+ AHEncryptDecrypt ();
+ virtual ~AHEncryptDecrypt () = 0;
+
+ virtual int getBlockLen (unsigned int *) = 0;
+ virtual int encryptInit
+ (B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *) = 0;
+ virtual int decryptInit
+ (B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *) = 0;
+ virtual int encryptUpdate
+ (unsigned char *, unsigned int *, unsigned int, unsigned char *,
+ unsigned int, B_Algorithm *, A_SURRENDER_CTX *) = 0;
+ virtual int decryptUpdate
+ (unsigned char *, unsigned int *, unsigned int, unsigned char *,
+ unsigned int, B_Algorithm *, A_SURRENDER_CTX *) = 0;
+ virtual int encryptFinal
+ (unsigned char *, unsigned int *, unsigned int, B_Algorithm *,
+ A_SURRENDER_CTX *) = 0;
+ virtual int decryptFinal
+ (unsigned char *, unsigned int *, unsigned int, B_Algorithm *,
+ A_SURRENDER_CTX *) = 0;
+};
+ */
+
+/* Use the THIS_ENCRYPT_DECRYPT macro to define the type of object in the
+ virtual function prototype. It defaults to the most base class, but
+ derived modules may define the macro to a more derived class before
+ including this header file.
+ */
+#ifndef THIS_ENCRYPT_DECRYPT
+#define THIS_ENCRYPT_DECRYPT struct AHEncryptDecrypt
+#endif
+
+struct AHEncryptDecrypt;
+
+typedef struct {
+ void (*Destructor) PROTO_LIST ((THIS_ENCRYPT_DECRYPT *));
+ int (*GetBlockLen) PROTO_LIST ((THIS_ENCRYPT_DECRYPT *, unsigned int *));
+ int (*EncryptInit) PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, B_Key *, B_ALGORITHM_CHOOSER,
+ A_SURRENDER_CTX *));
+ int (*DecryptInit) PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, B_Key *, B_ALGORITHM_CHOOSER,
+ A_SURRENDER_CTX *));
+ int (*EncryptUpdate) PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *, unsigned int,
+ unsigned char *, unsigned int, B_Algorithm *, A_SURRENDER_CTX *));
+ int (*DecryptUpdate) PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *, unsigned int,
+ unsigned char *, unsigned int, B_Algorithm *, A_SURRENDER_CTX *));
+ int (*EncryptFinal) PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *, unsigned int,
+ B_Algorithm *, A_SURRENDER_CTX *));
+ int (*DecryptFinal) PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *, unsigned int,
+ B_Algorithm *, A_SURRENDER_CTX *));
+} AHEncryptDecryptVTable;
+
+typedef struct AHEncryptDecrypt {
+ B_TypeCheck typeCheck; /* inherited */
+ AHEncryptDecryptVTable *vTable; /* pure virtual */
+} AHEncryptDecrypt;
+
+/* The constructor does not set the vTable since this is a pure base class.
+ */
+void AHEncryptDecryptConstructor PROTO_LIST ((AHEncryptDecrypt *));
+/* No destructor because it is pure virtual. Also, do not call destructor
+ for B_TypeCheck, since this will just re-invoke this virtual
+ destructor. */
+
+#endif
diff --git a/lib/dns/sec/dnssafe/ahgen.c b/lib/dns/sec/dnssafe/ahgen.c
new file mode 100644
index 00000000..34216683
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahgen.c
@@ -0,0 +1,90 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "ahgen.h"
+
+static void TypedAHGenerateDestructor PROTO_LIST ((B_TypeCheck *));
+
+void AHGenerateConstructor (handler)
+AHGenerate *handler;
+{
+ /* Construct base class, setting type tag. */
+ B_TYPE_CHECK_Constructor
+ (&handler->typeCheck, TypedAHGenerateDestructor);
+
+ /* Don't set vTable since this is a pure virtual base class. */
+}
+
+int B_AlgorithmGenerateInit (algorithm, algorithmChooser, surrenderContext)
+B_Algorithm *algorithm;
+B_ALGORITHM_CHOOSER algorithmChooser;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = B_AlgorithmCheckType
+ (algorithm, TypedAHGenerateDestructor)) != 0)
+ return (status);
+
+ if ((status =
+ (*((AHGenerate *)algorithm->z.handler)->vTable->GenerateInit)
+ ((AHGenerate *)algorithm->z.handler, algorithmChooser,
+ surrenderContext)) != 0)
+ return (status);
+
+ algorithm->z.initFlag = 1;
+ return (0);
+}
+
+int B_AlgorithmGenerateKeypair
+ (algorithm, publicKey, privateKey, randomAlgorithm, surrenderContext)
+B_Algorithm *algorithm;
+B_Key *publicKey;
+B_Key *privateKey;
+B_Algorithm *randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = B_AlgorithmCheckTypeAndInitFlag
+ (algorithm, TypedAHGenerateDestructor)) != 0)
+ return (status);
+
+ return ((*((AHGenerate *)algorithm->z.handler)->vTable->GenerateKeypair)
+ ((AHGenerate *)algorithm->z.handler, publicKey, privateKey,
+ randomAlgorithm, surrenderContext));
+}
+
+int B_AlgorithmGenerateParameters
+ (algorithm, resultAlgorithm, randomAlgorithm, surrenderContext)
+B_Algorithm *algorithm;
+B_Algorithm *resultAlgorithm;
+B_Algorithm *randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = B_AlgorithmCheckTypeAndInitFlag
+ (algorithm, TypedAHGenerateDestructor)) != 0)
+ return (status);
+
+ return ((*((AHGenerate *)algorithm->z.handler)->vTable->GenerateParameters)
+ ((AHGenerate *)algorithm->z.handler, resultAlgorithm,
+ randomAlgorithm, surrenderContext));
+}
+
+static void TypedAHGenerateDestructor (typeCheck)
+B_TypeCheck *typeCheck;
+{
+ (*((AHGenerate *)typeCheck)->vTable->Destructor) ((AHGenerate *)typeCheck);
+}
+
diff --git a/lib/dns/sec/dnssafe/ahgen.h b/lib/dns/sec/dnssafe/ahgen.h
new file mode 100644
index 00000000..7240e2e1
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahgen.h
@@ -0,0 +1,47 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _AHGEN_H_
+#define _AHGEN_H_ 1
+
+#include "btypechk.h"
+
+/* Use the THIS_GENERATE macro to define the type of object in the
+ virtual function prototype. It defaults to the most base class, but
+ derived modules may define the macro to a more derived class before
+ including this header file.
+ */
+#ifndef THIS_GENERATE
+#define THIS_GENERATE struct AHGenerate
+#endif
+
+struct AHGenerate;
+
+typedef struct {
+ void (*Destructor) PROTO_LIST ((THIS_GENERATE *));
+ int (*GenerateInit) PROTO_LIST
+ ((THIS_GENERATE *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *));
+ int (*GenerateKeypair) PROTO_LIST
+ ((THIS_GENERATE *, B_Key *, B_Key *, B_Algorithm *, A_SURRENDER_CTX *));
+ int (*GenerateParameters) PROTO_LIST
+ ((THIS_GENERATE *, B_Algorithm *, B_Algorithm *, A_SURRENDER_CTX *));
+} AHGenerateVTable;
+
+typedef struct AHGenerate {
+ B_TypeCheck typeCheck; /* inherited */
+ AHGenerateVTable *vTable; /* pure virtual */
+} AHGenerate;
+
+/* The constructor does not set the vTable since this is a pure base class.
+ */
+void AHGenerateConstructor PROTO_LIST ((AHGenerate *));
+/* No destructor because it is pure virtual. Also, do not call destructor
+ for B_TypeCheck, since this will just re-invoke this virtual
+ destructor. */
+
+#endif
diff --git a/lib/dns/sec/dnssafe/ahrandom.c b/lib/dns/sec/dnssafe/ahrandom.c
new file mode 100644
index 00000000..f6f27187
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahrandom.c
@@ -0,0 +1,97 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "ahrandom.h"
+
+static void TypedAHRandomDestructor PROTO_LIST ((B_TypeCheck *));
+
+void AHRandomConstructor (handler)
+AHRandom *handler;
+{
+ /* Construct base class, setting type tag. */
+ B_TYPE_CHECK_Constructor
+ (&handler->typeCheck, TypedAHRandomDestructor);
+
+ /* Don't set vTable since this is a pure virtual base class. */
+}
+
+int B_AlgorithmRandomInit (algorithm, algorithmChooser, surrenderContext)
+B_Algorithm *algorithm;
+B_ALGORITHM_CHOOSER algorithmChooser;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = B_AlgorithmCheckType (algorithm, TypedAHRandomDestructor))
+ != 0)
+ return (status);
+
+ if ((status =
+ (*((AHRandom *)algorithm->z.handler)->vTable->RandomInit)
+ ((AHRandom *)algorithm->z.handler, algorithmChooser, surrenderContext))
+ != 0)
+ return (status);
+
+ algorithm->z.initFlag = 1;
+ return (0);
+}
+
+int B_AlgorithmRandomUpdate (algorithm, input, inputLen, surrenderContext)
+B_Algorithm *algorithm;
+unsigned char *input;
+unsigned int inputLen;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = B_AlgorithmCheckTypeAndInitFlag
+ (algorithm, TypedAHRandomDestructor)) != 0)
+ return (status == BE_ALGORITHM_NOT_INITIALIZED ?
+ BE_RANDOM_NOT_INITIALIZED : status);
+
+ return ((*((AHRandom *)algorithm->z.handler)->vTable->RandomUpdate)
+ ((AHRandom *)algorithm->z.handler, input, inputLen,
+ surrenderContext));
+}
+
+int B_AlgorithmGenerateRandomBytes
+ (algorithm, output, outputLen, surrenderContext)
+B_Algorithm *algorithm;
+unsigned char *output;
+unsigned int outputLen;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ /* As a special case, check here for a null this pointer when the object
+ is actually being used since many routines take a "dummy" null
+ random algorithm.
+ */
+ if (algorithm == (B_Algorithm *)NULL_PTR)
+ return (BE_RANDOM_OBJ);
+
+ if ((status = B_AlgorithmCheckTypeAndInitFlag
+ (algorithm, TypedAHRandomDestructor)) != 0)
+ return (status == BE_ALGORITHM_NOT_INITIALIZED ?
+ BE_RANDOM_NOT_INITIALIZED : status);
+
+ return ((*((AHRandom *)algorithm->z.handler)->vTable->GenerateBytes)
+ ((AHRandom *)algorithm->z.handler, output, outputLen,
+ surrenderContext));
+}
+
+static void TypedAHRandomDestructor (typeCheck)
+B_TypeCheck *typeCheck;
+{
+ (*((AHRandom *)typeCheck)->vTable->Destructor) ((AHRandom *)typeCheck);
+}
+
diff --git a/lib/dns/sec/dnssafe/ahrandom.h b/lib/dns/sec/dnssafe/ahrandom.h
new file mode 100644
index 00000000..aeb4f3b0
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahrandom.h
@@ -0,0 +1,47 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _AHRANDOM_H_
+#define _AHRANDOM_H_ 1
+
+#include "btypechk.h"
+
+/* Use the THIS_RANDOM macro to define the type of object in the
+ virtual function prototype. It defaults to the most base class, but
+ derived modules may define the macro to a more derived class before
+ including this header file.
+ */
+#ifndef THIS_RANDOM
+#define THIS_RANDOM struct AHRandom
+#endif
+
+struct AHRandom;
+
+typedef struct {
+ void (*Destructor) PROTO_LIST ((THIS_RANDOM *));
+ int (*RandomInit) PROTO_LIST
+ ((THIS_RANDOM *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *));
+ int (*RandomUpdate) PROTO_LIST
+ ((THIS_RANDOM *, unsigned char *, unsigned int, A_SURRENDER_CTX *));
+ int (*GenerateBytes) PROTO_LIST
+ ((THIS_RANDOM *, unsigned char *, unsigned int, A_SURRENDER_CTX *));
+} AHRandomVTable;
+
+typedef struct AHRandom {
+ B_TypeCheck typeCheck; /* inherited */
+ AHRandomVTable *vTable; /* pure virtual */
+} AHRandom;
+
+/* The constructor does not set the vTable since this is a pure base class.
+ */
+void AHRandomConstructor PROTO_LIST ((AHRandom *));
+/* No destructor because it is pure virtual. Also, do not call destructor
+ for B_TypeCheck, since this will just re-invoke this virtual
+ destructor. */
+
+#endif
diff --git a/lib/dns/sec/dnssafe/ahrsaenc.c b/lib/dns/sec/dnssafe/ahrsaenc.c
new file mode 100644
index 00000000..307d1fd8
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahrsaenc.c
@@ -0,0 +1,241 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+/* Define this so that the type of the 'this' pointer in the
+ virtual functions will be correct for this derived class.
+ */
+struct AH_RSAEncryption;
+#define THIS_ENCRYPT_DECRYPT struct AH_RSAEncryption
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "ahrsaenc.h"
+
+static int AH_RSAEncryptionInitHelper PROTO_LIST ((AH_RSAEncryption *, int));
+
+static AHEncryptDecryptVTable V_TABLE = {
+ AH_RSAEncryptionDestructor, AH_RSAEncryptionGetBlockLen,
+ AH_RSAEncryptionEncryptInit, AH_RSAEncryptionDecryptInit,
+ AH_RSAEncryptionUpdate, AH_RSAEncryptionUpdate,
+ AH_RSAEncryptionEncryptFinal, AH_RSAEncryptionDecryptFinal
+};
+
+void AH_RSAEncryptionConstructor1 (handler, infoType)
+AH_RSAEncryption *handler;
+struct B_AlgorithmInfoType *infoType;
+{
+ /* Construct base class with the infoType. Assume info is NULL_PTR. */
+ AHChooseEncryptConstructor2
+ (&handler->chooseEncryptDecrypt, infoType, NULL_PTR);
+
+ T_memset ((POINTER)&handler->z, 0, sizeof (handler->z));
+ /* Set the AHEncryptDecrypt vTable, but don't set the RSAEncryption vTable
+ since it is pure virtual. */
+ handler->chooseEncryptDecrypt.encryptDecrypt.vTable = &V_TABLE;
+}
+
+void AH_RSAEncryptionDestructor (handler)
+AH_RSAEncryption *handler;
+{
+ T_memset ((POINTER)handler->z.block, 0, handler->z.blockLen);
+ T_free ((POINTER)handler->z.block);
+
+ /* Call base class destructor */
+ AHChooseEncryptDestructor (handler);
+}
+
+int AH_RSAEncryptionGetBlockLen (handler, blockLen)
+AH_RSAEncryption *handler;
+unsigned int *blockLen;
+{
+UNUSED_ARG (handler)
+UNUSED_ARG (blockLen)
+ return (BE_NOT_SUPPORTED);
+}
+
+int AH_RSAEncryptionEncryptInit (handler, key, chooser, surrenderContext)
+AH_RSAEncryption *handler;
+B_Key *key;
+B_ALGORITHM_CHOOSER chooser;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = AHChooseEncryptEncryptInit
+ (handler, key, chooser, surrenderContext)) != 0)
+ return (status);
+
+ return (AH_RSAEncryptionInitHelper (handler, 1));
+}
+
+int AH_RSAEncryptionDecryptInit (handler, key, chooser, surrenderContext)
+AH_RSAEncryption *handler;
+B_Key *key;
+B_ALGORITHM_CHOOSER chooser;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = AHChooseEncryptDecryptInit
+ (handler, key, chooser, surrenderContext)) != 0)
+ return (status);
+
+ return (AH_RSAEncryptionInitHelper (handler, 0));
+}
+
+/* Accumulate into the z.block.
+ */
+int AH_RSAEncryptionUpdate
+ (handler, partOut, partOutLen, maxPartOutLen, partIn, partInLen,
+ randomAlgorithm, surrenderContext)
+AH_RSAEncryption *handler;
+unsigned char *partOut;
+unsigned int *partOutLen;
+unsigned int maxPartOutLen;
+unsigned char *partIn;
+unsigned int partInLen;
+B_Algorithm *randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+UNUSED_ARG (partOut)
+UNUSED_ARG (maxPartOutLen)
+UNUSED_ARG (randomAlgorithm)
+UNUSED_ARG (surrenderContext)
+ *partOutLen = 0;
+
+ if (handler->_inputLen + partInLen > handler->_maxInputLen)
+ return (BE_INPUT_LEN);
+ T_memcpy
+ ((POINTER)(handler->z.block + handler->_inputLen), (POINTER)partIn,
+ partInLen);
+ handler->_inputLen += partInLen;
+ return (0);
+}
+
+int AH_RSAEncryptionEncryptFinal
+ (handler, partOut, partOutLen, maxPartOutLen, randomAlgorithm,
+ surrenderContext)
+AH_RSAEncryption *handler;
+unsigned char *partOut;
+unsigned int *partOutLen;
+unsigned int maxPartOutLen;
+B_Algorithm *randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+ unsigned int dummyPartOutLen;
+
+ /* Encode methodContext in place. */
+ if ((status = (*handler->vTable->EncodeBlock)
+ (handler, randomAlgorithm, surrenderContext)) != 0)
+ return (status);
+
+ /* This should not return BE_INPUT_DATA since it is well-formatted. */
+ if ((status = AHChooseEncryptEncryptUpdate
+ (handler, partOut, partOutLen, maxPartOutLen, handler->z.block,
+ handler->z.blockLen, (B_Algorithm *)NULL_PTR, surrenderContext)) != 0)
+ return (status);
+
+ /* Expect final to return zero bytes. */
+ if ((status = AHChooseEncryptEncryptFinal
+ (handler, (unsigned char *)NULL_PTR, &dummyPartOutLen, 0,
+ (B_Algorithm *)NULL_PTR, surrenderContext)) != 0)
+ return (status);
+
+ /* Restart the handle for new input. */
+ handler->_inputLen = 0;
+ return (0);
+}
+
+int AH_RSAEncryptionDecryptFinal
+ (handler, partOut, partOutLen, maxPartOutLen, randomAlgorithm,
+ surrenderContext)
+AH_RSAEncryption *handler;
+unsigned char *partOut;
+unsigned int *partOutLen;
+unsigned int maxPartOutLen;
+B_Algorithm *randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ ITEM output;
+ int status;
+ unsigned int decryptedLen, dummyPartOutLen;
+
+UNUSED_ARG (randomAlgorithm)
+ /* Decrypt block in place. The block lenghts are already within limits.
+ */
+ if ((status = AHChooseEncryptDecryptUpdate
+ (handler, handler->z.block, &decryptedLen, handler->z.blockLen,
+ handler->z.block, handler->_inputLen, (B_Algorithm *)NULL_PTR,
+ surrenderContext)) != 0)
+ return (status);
+ /* Expect final to return zero bytes. */
+ if ((status = AHChooseEncryptDecryptFinal
+ (handler, (unsigned char *)NULL_PTR, &dummyPartOutLen, 0,
+ (B_Algorithm *)NULL_PTR, surrenderContext)) != 0)
+ return (status);
+
+ /* Restart the handle for new input. */
+ handler->_inputLen = 0;
+
+ /* Now decode the block and copy the result to the partOut.
+ */
+ if ((status = (*handler->vTable->DecodeBlock)
+ (handler, &output, decryptedLen)) != 0)
+ return (status);
+
+ if (output.len > handler->z.blockLen - 11)
+ /* This implies that the block was encrypted with less than
+ 8 bytes of padding */
+ return (BE_INPUT_DATA);
+
+ if ((*partOutLen = output.len) > maxPartOutLen)
+ return (BE_OUTPUT_LEN);
+ T_memcpy ((POINTER)partOut, (POINTER)output.data, output.len);
+
+ return (0);
+}
+
+static int AH_RSAEncryptionInitHelper (handler, encryptFlag)
+AH_RSAEncryption *handler;
+int encryptFlag;
+{
+ int status;
+ unsigned int newBlockLen;
+
+ if ((status = AHChooseEncryptGetBlockLen (handler, &newBlockLen)) != 0)
+ return (status);
+
+ if (newBlockLen < 12)
+ /* PKCS Requires at least 12 bytes of modulus */
+ return (BE_NOT_SUPPORTED);
+
+ /* During encrypt, this will ensure that there are 8 bytes of padding.
+ During decrypt, the DecodeBlock procedure must check that the block
+ was encrypted with 8 bytes of padding.
+ */
+ handler->_maxInputLen = encryptFlag ? (newBlockLen - 11) : newBlockLen;
+
+ handler->_inputLen = 0;
+
+ /* Zeroize old block and realloc to new size.
+ */
+ T_memset ((POINTER)handler->z.block, 0, handler->z.blockLen);
+ if ((handler->z.block = (unsigned char *)T_realloc
+ ((POINTER)handler->z.block, newBlockLen))
+ == (unsigned char *)NULL_PTR) {
+ handler->z.blockLen = 0;
+ return (BE_ALLOC);
+ }
+
+ handler->z.blockLen = newBlockLen;
+ return (0);
+}
+
diff --git a/lib/dns/sec/dnssafe/ahrsaenc.h b/lib/dns/sec/dnssafe/ahrsaenc.h
new file mode 100644
index 00000000..ede21c78
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahrsaenc.h
@@ -0,0 +1,68 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _AHRSAENC_H_
+#define _AHRSAENC_H_
+
+#include "ahchencr.h"
+
+struct AH_RSAEncryption;
+
+/* For EncodeBlock, the block to encode is left justified in the
+ z.block with length given by z._inputLen. EncodeBlock encodes the block
+ in place to fill it out to z.blockLen.
+ For DecodeBlock, return the contents in the given ITEM by decoding
+ the z.block value which has length given by decryptedLen. This
+ procedure must also ensure that the block was encrypted with 8 bytes
+ of padding.
+ */
+typedef struct {
+ int (*EncodeBlock) PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, B_Algorithm * /* randomAlgorithm */,
+ A_SURRENDER_CTX *));
+ int (*DecodeBlock) PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, ITEM *, unsigned int /* decryptedLen */));
+} AH_RSAEncryptionVTable;
+
+typedef struct AH_RSAEncryption {
+ AHChooseEncryptDecrypt chooseEncryptDecrypt; /* base class */
+
+ struct {
+ unsigned char *block;
+ unsigned int blockLen;
+ } z; /* Zeroized by constructor */
+
+ unsigned int _inputLen; /* Length of data accumulated by Update */
+ unsigned int _maxInputLen; /* used during update to check for overflow */
+ AH_RSAEncryptionVTable *vTable; /* pure virtual */
+} AH_RSAEncryption;
+
+void AH_RSAEncryptionConstructor1 PROTO_LIST
+ ((AH_RSAEncryption *, struct B_AlgorithmInfoType *));
+void AH_RSAEncryptionDestructor PROTO_LIST ((AH_RSAEncryption *));
+
+int AH_RSAEncryptionGetBlockLen PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, unsigned int *));
+int AH_RSAEncryptionEncryptInit PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, B_Key *, B_ALGORITHM_CHOOSER,
+ A_SURRENDER_CTX *));
+int AH_RSAEncryptionDecryptInit PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, B_Key *, B_ALGORITHM_CHOOSER,
+ A_SURRENDER_CTX *));
+int AH_RSAEncryptionUpdate PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *,
+ unsigned int, unsigned char *, unsigned int, B_Algorithm *,
+ A_SURRENDER_CTX *));
+int AH_RSAEncryptionEncryptFinal PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *,
+ unsigned int, B_Algorithm *, A_SURRENDER_CTX *));
+int AH_RSAEncryptionDecryptFinal PROTO_LIST
+ ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *,
+ unsigned int, B_Algorithm *, A_SURRENDER_CTX *));
+
+#endif
diff --git a/lib/dns/sec/dnssafe/ahrsaepr.c b/lib/dns/sec/dnssafe/ahrsaepr.c
new file mode 100644
index 00000000..e6fba2b9
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahrsaepr.c
@@ -0,0 +1,99 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+/* Define this so that the type of the 'this' pointer in the
+ virtual functions will be correct for this derived class.
+ */
+struct AH_RSAEncryption;
+#define THIS_ENCRYPT_DECRYPT struct AH_RSAEncryption
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "ahrsaepr.h"
+
+static int EncodeBlock1 PROTO_LIST
+ ((AH_RSAEncryptionPrivate *, B_Algorithm *, A_SURRENDER_CTX *));
+static int DecodeBlock2 PROTO_LIST
+ ((AH_RSAEncryptionPrivate *, ITEM *, unsigned int));
+
+static AH_RSAEncryptionVTable ENCRYPTION_V_TABLE =
+ {EncodeBlock1, DecodeBlock2};
+
+extern struct B_AlgorithmInfoType AIT_RSAPrivate;
+
+AH_RSAEncryptionPrivate *AH_RSAEncrypPrivateConstructor (handler)
+AH_RSAEncryptionPrivate *handler;
+{
+ if (handler == (AH_RSAEncryptionPrivate *)NULL_PTR) {
+ /* This constructor is being used to do a new */
+ if ((handler = (AH_RSAEncryptionPrivate *)T_malloc (sizeof (*handler)))
+ == (AH_RSAEncryptionPrivate *)NULL_PTR)
+ return (handler);
+ }
+
+ /* Construct base class */
+ AH_RSAEncryptionConstructor1 (handler, &AIT_RSAPrivate);
+
+ handler->vTable = &ENCRYPTION_V_TABLE;
+ return (handler);
+}
+
+/* block1 starts out with the input bytes of length inputLen left-justified.
+ Returns 0, BE_INPUT_LEN.
+ */
+static int EncodeBlock1 (handler, randomAlgorithm, surrenderContext)
+AH_RSAEncryptionPrivate *handler;
+B_Algorithm *randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ unsigned int padLen;
+
+UNUSED_ARG (randomAlgorithm)
+UNUSED_ARG (surrenderContext)
+ if ((handler->_inputLen + 3) > handler->z.blockLen)
+ /* input is too large to make a block 1 */
+ return (BE_INPUT_LEN);
+
+ padLen = handler->z.blockLen - (handler->_inputLen + 3);
+ T_memmove
+ ((POINTER)(handler->z.block + padLen + 3), (POINTER)handler->z.block,
+ handler->_inputLen);
+
+ handler->z.block[0] = 0;
+ handler->z.block[1] = 1;
+ T_memset ((POINTER)(handler->z.block + 2), 0xff, padLen);
+ handler->z.block[2 + padLen] = 0;
+ return (0);
+}
+
+static int DecodeBlock2 (handler, output, block2Len)
+AH_RSAEncryptionPrivate *handler;
+ITEM *output;
+unsigned int block2Len;
+{
+ unsigned int i;
+
+ if ((handler->z.block[0] != 0) || (handler->z.block[1] != 2))
+ return (BE_INPUT_DATA);
+
+ /* Should be able to find the data after the first zero byte following
+ the random bytes. */
+ for (i = 2; i < block2Len && handler->z.block[i] != 0; i++);
+ i++;
+
+ if (i > block2Len)
+ /* The data is not zero terminated. */
+ return (BE_INPUT_DATA);
+
+ output->len = block2Len - i;
+ output->data = handler->z.block + i;
+ return (0);
+}
+
diff --git a/lib/dns/sec/dnssafe/ahrsaepr.h b/lib/dns/sec/dnssafe/ahrsaepr.h
new file mode 100644
index 00000000..f5847bc6
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahrsaepr.h
@@ -0,0 +1,20 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _AHRSAEPR_H_
+#define _AHRSAEPR_H_
+
+#include "ahrsaenc.h"
+
+/* structure is identical to base class, so just re-typedef. */
+typedef AH_RSAEncryption AH_RSAEncryptionPrivate;
+
+AH_RSAEncryptionPrivate *AH_RSAEncrypPrivateConstructor PROTO_LIST
+ ((AH_RSAEncryptionPrivate *));
+
+#endif
diff --git a/lib/dns/sec/dnssafe/ahrsaepu.c b/lib/dns/sec/dnssafe/ahrsaepu.c
new file mode 100644
index 00000000..000e8420
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahrsaepu.c
@@ -0,0 +1,112 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+/* Define this so that the type of the 'this' pointer in the
+ virtual functions will be correct for this derived class.
+ */
+struct AH_RSAEncryption;
+#define THIS_ENCRYPT_DECRYPT struct AH_RSAEncryption
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "ahrsaepu.h"
+
+static int EncodeBlock2 PROTO_LIST
+ ((AH_RSAEncryptionPublic *, B_Algorithm *, A_SURRENDER_CTX *));
+static int DecodeBlock1 PROTO_LIST
+ ((AH_RSAEncryptionPublic *, ITEM *, unsigned int));
+
+static AH_RSAEncryptionVTable ENCRYPTION_V_TABLE =
+ {EncodeBlock2, DecodeBlock1};
+
+extern struct B_AlgorithmInfoType AIT_RSAPublic;
+
+AH_RSAEncryptionPublic *AH_RSAEncrypPublicConstructor (handler)
+AH_RSAEncryptionPublic *handler;
+{
+ if (handler == (AH_RSAEncryptionPublic *)NULL_PTR) {
+ /* This constructor is being used to do a new */
+ if ((handler = (AH_RSAEncryptionPublic *)T_malloc (sizeof (*handler)))
+ == (AH_RSAEncryptionPublic *)NULL_PTR)
+ return (handler);
+ }
+
+ /* Construct base class */
+ AH_RSAEncryptionConstructor1 (handler, &AIT_RSAPublic);
+
+ handler->vTable = &ENCRYPTION_V_TABLE;
+ return (handler);
+}
+
+/* block starts out with the input bytes of length inputLen left-justified.
+ */
+static int EncodeBlock2 (handler, randomAlgorithm, surrenderContext)
+AH_RSAEncryptionPublic *handler;
+B_Algorithm *randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+ unsigned char randomByte;
+ unsigned int padLen, i;
+
+ if ((handler->_inputLen + 3) > handler->z.blockLen)
+ /* input is too large to make a block 2 */
+ return (BE_INPUT_LEN);
+
+ padLen = handler->z.blockLen - (handler->_inputLen + 3);
+ T_memmove
+ ((POINTER)(handler->z.block + padLen + 3), (POINTER)handler->z.block,
+ handler->_inputLen);
+
+ handler->z.block[0] = 0;
+ handler->z.block[1] = 2;
+
+ /* Pad out with random bytes, making sure that none of the bytes is zero.
+ */
+ for (i = 2; i < (padLen + 2); i++) {
+ do {
+ if ((status = B_AlgorithmGenerateRandomBytes
+ (randomAlgorithm, &randomByte, 1, surrenderContext)) != 0)
+ return (status);
+ } while (randomByte == 0);
+
+ handler->z.block[i] = randomByte;
+ }
+
+ handler->z.block[2 + padLen] = 0;
+ return (0);
+}
+
+static int DecodeBlock1 (handler, output, block1Len)
+AH_RSAEncryptionPublic *handler;
+ITEM *output;
+unsigned int block1Len;
+{
+ unsigned int i;
+
+ /* Locate the digestInfo within the PKCS block 1.
+ */
+ if (handler->z.block[0] != 0 || handler->z.block[1] != 1)
+ return (BE_INPUT_DATA);
+
+ /* Should be able to find the data after the first zero byte following
+ the 0xff. */
+ for (i = 2; i < block1Len && handler->z.block[i] == 0xff; i++);
+ i++;
+
+ if (i > block1Len || handler->z.block[i - 1] != 0)
+ /* The data is not zero terminated, or a byte other than 0xff. */
+ return (BE_INPUT_DATA);
+
+ output->len = block1Len - i;
+ output->data = handler->z.block + i;
+ return (0);
+}
+
diff --git a/lib/dns/sec/dnssafe/ahrsaepu.h b/lib/dns/sec/dnssafe/ahrsaepu.h
new file mode 100644
index 00000000..0c13e204
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ahrsaepu.h
@@ -0,0 +1,20 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _AHRSAEPU_H_
+#define _AHRSAEPU_H_
+
+#include "ahrsaenc.h"
+
+/* structure is identical to base class, so just re-typedef. */
+typedef AH_RSAEncryption AH_RSAEncryptionPublic;
+
+AH_RSAEncryptionPublic *AH_RSAEncrypPublicConstructor PROTO_LIST
+ ((AH_RSAEncryptionPublic *));
+
+#endif
diff --git a/lib/dns/sec/dnssafe/aichdig.c b/lib/dns/sec/dnssafe/aichdig.c
new file mode 100644
index 00000000..7d86d89d
--- /dev/null
+++ b/lib/dns/sec/dnssafe/aichdig.c
@@ -0,0 +1,36 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "ahchdig.h"
+#include "aichdig.h"
+
+B_TypeCheck *AITChooseDigestNullNewHandler PROTO_LIST
+ ((B_AlgorithmInfoType *, B_Algorithm *));
+
+B_AlgorithmInfoTypeVTable AITChooseDigestNull_V_TABLE =
+ {AITNullAddInfo, AITChooseDigestNullNewHandler,
+ B_AlgorithmInfoTypeMakeError};
+
+/* This always uses NULL_PTR for the info.
+ */
+B_TypeCheck *AITChooseDigestNullNewHandler (infoType, algorithm)
+B_AlgorithmInfoType *infoType;
+B_Algorithm *algorithm;
+{
+UNUSED_ARG (algorithm)
+
+ /* Pass in NULL_PTR so that constructor will allocate.
+ */
+ return ((B_TypeCheck *)AHChooseDigestConstructor2
+ ((AHChooseDigest *)NULL_PTR, infoType, NULL_PTR));
+}
+
diff --git a/lib/dns/sec/dnssafe/aichdig.h b/lib/dns/sec/dnssafe/aichdig.h
new file mode 100644
index 00000000..e8228d91
--- /dev/null
+++ b/lib/dns/sec/dnssafe/aichdig.h
@@ -0,0 +1,17 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _AICHDIG_H_
+#define _AICHDIG_H_ 1
+
+#include "ainfotyp.h"
+#include "ainull.h"
+
+extern B_AlgorithmInfoTypeVTable AITChooseDigestNull_V_TABLE;
+
+#endif
diff --git a/lib/dns/sec/dnssafe/aichenc8.c b/lib/dns/sec/dnssafe/aichenc8.c
new file mode 100644
index 00000000..3612ab05
--- /dev/null
+++ b/lib/dns/sec/dnssafe/aichenc8.c
@@ -0,0 +1,33 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "aichenc8.h"
+
+B_AlgorithmInfoTypeVTable AITChooseEncrypt8_V_TABLE =
+ {AIT_8AddInfo, AITChooseEncryptNewHandler, B_AlgorithmInfoTypeMakeError};
+
+int AIT_8AddInfo (infoType, algorithm, info)
+B_AlgorithmInfoType *infoType;
+B_Algorithm *algorithm;
+POINTER info;
+{
+ POINTER newInfo;
+ int status;
+
+ if ((status = B_MemoryPoolAllocAndCopy
+ (&algorithm->infoCache.memoryPool, &newInfo, info, 8)) != 0)
+ return (status);
+
+ return (B_InfoCacheAddInfo
+ (&algorithm->infoCache, (POINTER)infoType, newInfo));
+}
+
diff --git a/lib/dns/sec/dnssafe/aichenc8.h b/lib/dns/sec/dnssafe/aichenc8.h
new file mode 100644
index 00000000..4c2096bd
--- /dev/null
+++ b/lib/dns/sec/dnssafe/aichenc8.h
@@ -0,0 +1,19 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _AICHENC8_H_
+#define _AICHENC8_H_ 1
+
+#include "aichencr.h"
+
+extern B_AlgorithmInfoTypeVTable AITChooseEncrypt8_V_TABLE;
+
+int AIT_8AddInfo PROTO_LIST
+ ((THIS_ALGORITHM_INFO_TYPE *, B_Algorithm *, POINTER));
+
+#endif
diff --git a/lib/dns/sec/dnssafe/aichencn.c b/lib/dns/sec/dnssafe/aichencn.c
new file mode 100644
index 00000000..58ffe2fd
--- /dev/null
+++ b/lib/dns/sec/dnssafe/aichencn.c
@@ -0,0 +1,17 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "aichencn.h"
+
+B_AlgorithmInfoTypeVTable AITChooseEncryptNull_V_TABLE =
+ {AITNullAddInfo, AITChooseEncryptNewHandler, B_AlgorithmInfoTypeMakeError};
+
diff --git a/lib/dns/sec/dnssafe/aichencn.h b/lib/dns/sec/dnssafe/aichencn.h
new file mode 100644
index 00000000..11301573
--- /dev/null
+++ b/lib/dns/sec/dnssafe/aichencn.h
@@ -0,0 +1,17 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _AICHENCN_H_
+#define _AICHENCN_H_ 1
+
+#include "aichencr.h"
+#include "ainull.h"
+
+extern B_AlgorithmInfoTypeVTable AITChooseEncryptNull_V_TABLE;
+
+#endif
diff --git a/lib/dns/sec/dnssafe/aichencr.c b/lib/dns/sec/dnssafe/aichencr.c
new file mode 100644
index 00000000..ccdb27cc
--- /dev/null
+++ b/lib/dns/sec/dnssafe/aichencr.c
@@ -0,0 +1,31 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "ahchencr.h"
+#include "aichencr.h"
+
+B_TypeCheck *AITChooseEncryptNewHandler (infoType, algorithm)
+B_AlgorithmInfoType *infoType;
+B_Algorithm *algorithm;
+{
+ POINTER info;
+
+ if (B_InfoCacheFindInfo (&algorithm->infoCache, &info, (POINTER)infoType)
+ != 0)
+ /* This really shouldn't happen since the info was just added. */
+ return ((B_TypeCheck *)NULL_PTR);
+
+ /* Pass in NULL_PTR so that constructor will allocate. */
+ return ((B_TypeCheck *)AHChooseEncryptConstructor2
+ ((AHChooseEncryptDecrypt *)NULL_PTR, infoType, info));
+}
+
diff --git a/lib/dns/sec/dnssafe/aichencr.h b/lib/dns/sec/dnssafe/aichencr.h
new file mode 100644
index 00000000..2d99bfb0
--- /dev/null
+++ b/lib/dns/sec/dnssafe/aichencr.h
@@ -0,0 +1,17 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _AICHENCR_H_
+#define _AICHENCR_H_ 1
+
+#include "ainfotyp.h"
+
+struct B_TypeCheck *AITChooseEncryptNewHandler PROTO_LIST
+ ((B_AlgorithmInfoType *, B_Algorithm *));
+
+#endif
diff --git a/lib/dns/sec/dnssafe/aichgen.c b/lib/dns/sec/dnssafe/aichgen.c
new file mode 100644
index 00000000..ecc3d51d
--- /dev/null
+++ b/lib/dns/sec/dnssafe/aichgen.c
@@ -0,0 +1,31 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "ahchgen.h"
+#include "aichgen.h"
+
+B_TypeCheck *AITChooseGenerateNewHandler (infoType, algorithm)
+B_AlgorithmInfoType *infoType;
+B_Algorithm *algorithm;
+{
+ POINTER info;
+
+ if (B_InfoCacheFindInfo (&algorithm->infoCache, &info, (POINTER)infoType)
+ != 0)
+ /* This really shouldn't happen since the info was just added. */
+ return ((B_TypeCheck *)NULL_PTR);
+
+ /* Pass in NULL_PTR so that constructor will allocate. */
+ return ((B_TypeCheck *)AHChooseGenerateConstructor2
+ ((AHChooseGenerate *)NULL_PTR, infoType, info));
+}
+
diff --git a/lib/dns/sec/dnssafe/aichgen.h b/lib/dns/sec/dnssafe/aichgen.h
new file mode 100644
index 00000000..eebd9b72
--- /dev/null
+++ b/lib/dns/sec/dnssafe/aichgen.h
@@ -0,0 +1,17 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _AICHGEN_H_
+#define _AICHGEN_H_ 1
+
+#include "ainfotyp.h"
+
+struct B_TypeCheck *AITChooseGenerateNewHandler PROTO_LIST
+ ((B_AlgorithmInfoType *, B_Algorithm *));
+
+#endif
diff --git a/lib/dns/sec/dnssafe/aichrand.c b/lib/dns/sec/dnssafe/aichrand.c
new file mode 100644
index 00000000..9319a07d
--- /dev/null
+++ b/lib/dns/sec/dnssafe/aichrand.c
@@ -0,0 +1,36 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "ahchrand.h"
+#include "aichrand.h"
+
+B_TypeCheck *AITChooseRandomNullNewHandler PROTO_LIST
+ ((B_AlgorithmInfoType *, B_Algorithm *));
+
+B_AlgorithmInfoTypeVTable AITChooseRandomNull_V_TABLE =
+ {AITNullAddInfo, AITChooseRandomNullNewHandler,
+ B_AlgorithmInfoTypeMakeError};
+
+/* This always uses NULL_PTR for the info.
+ */
+B_TypeCheck *AITChooseRandomNullNewHandler (infoType, algorithm)
+B_AlgorithmInfoType *infoType;
+B_Algorithm *algorithm;
+{
+UNUSED_ARG (algorithm)
+
+ /* Pass in NULL_PTR so that constructor will allocate.
+ */
+ return ((B_TypeCheck *)AHChooseRandomConstructor2
+ ((AHChooseRandom *)NULL_PTR, infoType, NULL_PTR));
+}
+
diff --git a/lib/dns/sec/dnssafe/aichrand.h b/lib/dns/sec/dnssafe/aichrand.h
new file mode 100644
index 00000000..6f188e18
--- /dev/null
+++ b/lib/dns/sec/dnssafe/aichrand.h
@@ -0,0 +1,17 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _AICHRAND_H_
+#define _AICHRAND_H_ 1
+
+#include "ainfotyp.h"
+#include "ainull.h"
+
+extern B_AlgorithmInfoTypeVTable AITChooseRandomNull_V_TABLE;
+
+#endif
diff --git a/lib/dns/sec/dnssafe/aimd5.c b/lib/dns/sec/dnssafe/aimd5.c
new file mode 100644
index 00000000..be2ba4d9
--- /dev/null
+++ b/lib/dns/sec/dnssafe/aimd5.c
@@ -0,0 +1,25 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "aichdig.h"
+
+B_AlgorithmInfoType AIT_MD5 = {&AITChooseDigestNull_V_TABLE};
+
+int AI_MD5 (infoType)
+POINTER *infoType;
+{
+ *infoType = (POINTER)&AIT_MD5;
+
+ /* Return 0 to indicate a B_AlgorithmInfoType, not a B_KeyInfoType */
+ return (0);
+}
+
diff --git a/lib/dns/sec/dnssafe/aimd5ran.c b/lib/dns/sec/dnssafe/aimd5ran.c
new file mode 100644
index 00000000..a51a9b6f
--- /dev/null
+++ b/lib/dns/sec/dnssafe/aimd5ran.c
@@ -0,0 +1,25 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "aichrand.h"
+
+B_AlgorithmInfoType AIT_MD5Random = {&AITChooseRandomNull_V_TABLE};
+
+int AI_MD5Random (infoType)
+POINTER *infoType;
+{
+ *infoType = (POINTER)&AIT_MD5Random;
+
+ /* Return 0 to indicate a B_AlgorithmInfoType, not a B_KeyInfoType */
+ return (0);
+}
+
diff --git a/lib/dns/sec/dnssafe/ainfotyp.c b/lib/dns/sec/dnssafe/ainfotyp.c
new file mode 100644
index 00000000..c71e0281
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ainfotyp.c
@@ -0,0 +1,30 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "ainfotyp.h"
+
+/* This is the default routine which algorithm info types point MakeInfo to
+ if not redefined by a derived class.
+ */
+int B_AlgorithmInfoTypeMakeError (infoType, info, algorithm)
+B_AlgorithmInfoType *infoType;
+POINTER *info;
+B_Algorithm *algorithm;
+{
+UNUSED_ARG (infoType)
+UNUSED_ARG (info)
+UNUSED_ARG (algorithm)
+
+ /* Should already have been found in the cache. */
+ return (BE_WRONG_ALGORITHM_INFO);
+}
+
diff --git a/lib/dns/sec/dnssafe/ainfotyp.h b/lib/dns/sec/dnssafe/ainfotyp.h
new file mode 100644
index 00000000..fa9f4a64
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ainfotyp.h
@@ -0,0 +1,39 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _AINFOTYP_H_
+#define _AINFOTYP_H_ 1
+
+/* Use the THIS_ALGORITHM_INFO_TYPE macro to define the type of object in the
+ virtual function prototype. It defaults to the most base class, but
+ derived modules may define the macro to a more derived class before
+ including this header file.
+ */
+#ifndef THIS_ALGORITHM_INFO_TYPE
+#define THIS_ALGORITHM_INFO_TYPE struct B_AlgorithmInfoType
+#endif
+
+struct B_AlgorithmInfoType;
+
+typedef struct {
+ int (*AddInfo) PROTO_LIST
+ ((THIS_ALGORITHM_INFO_TYPE *, B_Algorithm *, POINTER));
+ struct B_TypeCheck * (*NewHandler) PROTO_LIST
+ ((THIS_ALGORITHM_INFO_TYPE *, B_Algorithm *));
+ int (*MakeInfo) PROTO_LIST
+ ((THIS_ALGORITHM_INFO_TYPE *, POINTER *, B_Algorithm *));
+} B_AlgorithmInfoTypeVTable;
+
+typedef struct B_AlgorithmInfoType {
+ B_AlgorithmInfoTypeVTable *vTable;
+} B_AlgorithmInfoType;
+
+int B_AlgorithmInfoTypeMakeError PROTO_LIST
+ ((THIS_ALGORITHM_INFO_TYPE *, POINTER *, B_Algorithm *));
+
+#endif
diff --git a/lib/dns/sec/dnssafe/ainull.c b/lib/dns/sec/dnssafe/ainull.c
new file mode 100644
index 00000000..66e0e917
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ainull.c
@@ -0,0 +1,26 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "ainfotyp.h"
+#include "ainull.h"
+
+int AITNullAddInfo (infoType, algorithm, info)
+B_AlgorithmInfoType *infoType;
+B_Algorithm *algorithm;
+POINTER info;
+{
+UNUSED_ARG (info)
+ /* Cache null parameters. */
+ return (B_InfoCacheAddInfo
+ (&algorithm->infoCache, (POINTER)infoType, NULL_PTR));
+}
+
diff --git a/lib/dns/sec/dnssafe/ainull.h b/lib/dns/sec/dnssafe/ainull.h
new file mode 100644
index 00000000..3b48901a
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ainull.h
@@ -0,0 +1,10 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+int AITNullAddInfo PROTO_LIST
+ ((THIS_ALGORITHM_INFO_TYPE *, B_Algorithm *, POINTER));
diff --git a/lib/dns/sec/dnssafe/airsaepr.c b/lib/dns/sec/dnssafe/airsaepr.c
new file mode 100644
index 00000000..55a219a4
--- /dev/null
+++ b/lib/dns/sec/dnssafe/airsaepr.c
@@ -0,0 +1,45 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "ainfotyp.h"
+#include "ainull.h"
+#include "ahrsaepr.h"
+
+B_TypeCheck *AIT_PKCS_RSAPrivateNewHandler PROTO_LIST
+ ((B_AlgorithmInfoType *, B_Algorithm *));
+
+static B_AlgorithmInfoTypeVTable V_TABLE =
+ {AITNullAddInfo, AIT_PKCS_RSAPrivateNewHandler,
+ B_AlgorithmInfoTypeMakeError};
+
+B_AlgorithmInfoType AIT_PKCS_RSAPrivate = {&V_TABLE};
+
+int AI_PKCS_RSAPrivate (infoType)
+POINTER *infoType;
+{
+ *infoType = (POINTER)&AIT_PKCS_RSAPrivate;
+
+ /* Return 0 to indicate a B_AlgorithmInfoType, not a B_KeyInfoType */
+ return (0);
+}
+
+B_TypeCheck *AIT_PKCS_RSAPrivateNewHandler (infoType, algorithm)
+B_AlgorithmInfoType *infoType;
+B_Algorithm *algorithm;
+{
+UNUSED_ARG (infoType)
+UNUSED_ARG (algorithm)
+ /* Pass in NULL_PTR so that constructor will allocate. */
+ return ((B_TypeCheck *)AH_RSAEncrypPrivateConstructor
+ ((AH_RSAEncryptionPrivate *)NULL_PTR));
+}
+
diff --git a/lib/dns/sec/dnssafe/airsaepu.c b/lib/dns/sec/dnssafe/airsaepu.c
new file mode 100644
index 00000000..44d0a81b
--- /dev/null
+++ b/lib/dns/sec/dnssafe/airsaepu.c
@@ -0,0 +1,45 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "ainfotyp.h"
+#include "ainull.h"
+#include "ahrsaepu.h"
+
+B_TypeCheck *AIT_PKCS_RSAPublicNewHandler PROTO_LIST
+ ((B_AlgorithmInfoType *, B_Algorithm *));
+
+static B_AlgorithmInfoTypeVTable V_TABLE =
+ {AITNullAddInfo, AIT_PKCS_RSAPublicNewHandler,
+ B_AlgorithmInfoTypeMakeError};
+
+B_AlgorithmInfoType AIT_PKCS_RSAPublic = {&V_TABLE};
+
+int AI_PKCS_RSAPublic (infoType)
+POINTER *infoType;
+{
+ *infoType = (POINTER)&AIT_PKCS_RSAPublic;
+
+ /* Return 0 to indicate a B_AlgorithmInfoType, not a B_KeyInfoType */
+ return (0);
+}
+
+B_TypeCheck *AIT_PKCS_RSAPublicNewHandler (infoType, algorithm)
+B_AlgorithmInfoType *infoType;
+B_Algorithm *algorithm;
+{
+UNUSED_ARG (infoType)
+UNUSED_ARG (algorithm)
+ /* Pass in NULL_PTR so that constructor will allocate. */
+ return ((B_TypeCheck *)AH_RSAEncrypPublicConstructor
+ ((AH_RSAEncryptionPublic *)NULL_PTR));
+}
+
diff --git a/lib/dns/sec/dnssafe/airsakgn.c b/lib/dns/sec/dnssafe/airsakgn.c
new file mode 100644
index 00000000..9856a007
--- /dev/null
+++ b/lib/dns/sec/dnssafe/airsakgn.c
@@ -0,0 +1,60 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "intitem.h"
+#include "aichgen.h"
+
+int AIT_RSAKeyGenAddInfo PROTO_LIST
+ ((THIS_ALGORITHM_INFO_TYPE *, B_Algorithm *, POINTER));
+
+static A_RSA_KEY_GEN_PARAMS STATIC_KEY_GEN_PARAMS;
+static ITEM *KEY_GEN_PARAMS_ITEMS[] = {&STATIC_KEY_GEN_PARAMS.publicExponent};
+
+static B_AlgorithmInfoTypeVTable V_TABLE =
+ {AIT_RSAKeyGenAddInfo, AITChooseGenerateNewHandler,
+ B_AlgorithmInfoTypeMakeError};
+
+B_AlgorithmInfoType AIT_RSAKeyGen = {&V_TABLE};
+
+int AI_RSAKeyGen (infoType)
+POINTER *infoType;
+{
+ *infoType = (POINTER)&AIT_RSAKeyGen;
+
+ /* Return 0 to indicate a B_AlgorithmInfoType, not a B_KeyInfoType */
+ return (0);
+}
+
+int AIT_RSAKeyGenAddInfo (infoType, algorithm, info)
+B_AlgorithmInfoType *infoType;
+B_Algorithm *algorithm;
+POINTER info;
+{
+ A_RSA_KEY_GEN_PARAMS *newInfo;
+ int status;
+
+ if ((status = B_MemoryPoolAlloc
+ (&algorithm->infoCache.memoryPool, (POINTER *)&newInfo,
+ sizeof (A_RSA_KEY_GEN_PARAMS))) != 0)
+ return (status);
+ if ((status = AllocAndCopyIntegerItems
+ ((POINTER)newInfo, info, (POINTER)&STATIC_KEY_GEN_PARAMS,
+ KEY_GEN_PARAMS_ITEMS,
+ sizeof (KEY_GEN_PARAMS_ITEMS) / sizeof (KEY_GEN_PARAMS_ITEMS[0]),
+ &algorithm->infoCache.memoryPool)) != 0)
+ return (status);
+
+ newInfo->modulusBits = ((A_RSA_KEY_GEN_PARAMS *)info)->modulusBits;
+ return (B_InfoCacheAddInfo
+ (&algorithm->infoCache, (POINTER)infoType, (POINTER)newInfo));
+}
+
diff --git a/lib/dns/sec/dnssafe/airsaprv.c b/lib/dns/sec/dnssafe/airsaprv.c
new file mode 100644
index 00000000..81193efc
--- /dev/null
+++ b/lib/dns/sec/dnssafe/airsaprv.c
@@ -0,0 +1,25 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "aichencn.h"
+
+B_AlgorithmInfoType AIT_RSAPrivate = {&AITChooseEncryptNull_V_TABLE};
+
+int AI_RSAPrivate (infoType)
+POINTER *infoType;
+{
+ *infoType = (POINTER)&AIT_RSAPrivate;
+
+ /* Return 0 to indicate a B_AlgorithmInfoType, not a B_KeyInfoType */
+ return (0);
+}
+
diff --git a/lib/dns/sec/dnssafe/airsapub.c b/lib/dns/sec/dnssafe/airsapub.c
new file mode 100644
index 00000000..6167355f
--- /dev/null
+++ b/lib/dns/sec/dnssafe/airsapub.c
@@ -0,0 +1,25 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "aichencn.h"
+
+B_AlgorithmInfoType AIT_RSAPublic = {&AITChooseEncryptNull_V_TABLE};
+
+int AI_RSAPublic (infoType)
+POINTER *infoType;
+{
+ *infoType = (POINTER)&AIT_RSAPublic;
+
+ /* Return 0 to indicate a B_AlgorithmInfoType, not a B_KeyInfoType */
+ return (0);
+}
+
diff --git a/lib/dns/sec/dnssafe/algae.h b/lib/dns/sec/dnssafe/algae.h
new file mode 100644
index 00000000..f1ceb62d
--- /dev/null
+++ b/lib/dns/sec/dnssafe/algae.h
@@ -0,0 +1,66 @@
+/* Copyright (C) RSA Data Security, Inc. created 1992, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _ALGAE_H_
+#define _ALGAE_H_ 1
+
+#ifndef T_CALL
+#define T_CALL
+#endif
+
+/* Used to reduce the stack size in routines with big scratch buffers.
+ If set to 1, this will make ALGAE allocate these buffers on the heap.
+ */
+#ifndef USE_ALLOCED_FRAME
+#define USE_ALLOCED_FRAME 1
+#endif
+
+#include "atypes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AE_CANCEL 0x0001
+#define AE_DATA 0x0002
+#define AE_EXPONENT_EVEN 0x0003
+#define AE_EXPONENT_LEN 0x0004
+#define AE_INPUT_DATA 0x0005
+#define AE_INPUT_LEN 0x0006
+#define AE_MODULUS_LEN 0x0007
+#define AE_NEED_RANDOM 0x0008
+#define AE_NOT_SUPPORTED 0x0009
+#define AE_OUTPUT_LEN 0x000a
+#define AE_NOT_INITIALIZED 0x000b
+#define AE_KEY_LEN 0x000c
+#define AE_KEY_INFO 0x000d
+#define AE_SEQUENCE 0x000e
+#define AE_PARAMS 0x000f
+
+#if USE_ALLOCED_FRAME
+/* Needed only for big number code heap allocation of scratch arrays.
+ */
+#define AE_ALLOC 0x0080
+POINTER T_malloc PROTO_LIST ((unsigned int));
+void T_free PROTO_LIST ((POINTER));
+#endif
+
+/* Routines supplied by the implementor.
+ */
+void T_memset PROTO_LIST ((POINTER, int, unsigned int));
+void T_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
+void T_memmove PROTO_LIST ((POINTER, POINTER, unsigned int));
+int T_memcmp PROTO_LIST ((POINTER, POINTER, unsigned int));
+
+unsigned int A_IntegerBits PROTO_LIST ((unsigned char *, unsigned int));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/dns/sec/dnssafe/algchoic.c b/lib/dns/sec/dnssafe/algchoic.c
new file mode 100644
index 00000000..e8b07699
--- /dev/null
+++ b/lib/dns/sec/dnssafe/algchoic.c
@@ -0,0 +1,167 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "algae.h"
+#include "balgmeth.h"
+#include "bkey.h"
+#include "algchoic.h"
+
+/* In C++:
+ResizeContext::ResizeContext ()
+{
+ T_memset ((POINTER)&z, 0, sizeof (z));
+}
+ */
+void ResizeContextConstructor (resizeContext)
+ResizeContext *resizeContext;
+{
+ T_memset ((POINTER)&resizeContext->z, 0, sizeof (resizeContext->z));
+}
+
+/* In C++:
+ResizeContext::~ResizeContext ()
+{
+ T_memset (z.context, 0, z.contextSize);
+ T_free (z.context);
+}
+ */
+void ResizeContextDestructor (resizeContext)
+ResizeContext *resizeContext;
+{
+ T_memset (resizeContext->z.context, 0, resizeContext->z.contextSize);
+ T_free (resizeContext->z.context);
+}
+
+/* If the resizeContext's context is already the requested size, do nothing.
+ Otherwise, this memsets the existing context to zero, then allocates
+ the context as a buffer of the requested size.
+ If the allocate fails, the context size is set to
+ zero so that later calls will not zeroize non-existing buffers.
+ */
+int ResizeContextMakeNewContext (resizeContext, contextSize)
+ResizeContext *resizeContext;
+unsigned int contextSize;
+{
+ if (resizeContext->z.contextSize == contextSize)
+ return (0);
+
+ /* Take care of zeroizing the previous context.
+ */
+ T_memset (resizeContext->z.context, 0, resizeContext->z.contextSize);
+
+ if ((resizeContext->z.context = T_realloc
+ (resizeContext->z.context, contextSize)) == NULL_PTR) {
+ resizeContext->z.contextSize = 0;
+ return (BE_ALLOC);
+ }
+
+ resizeContext->z.contextSize = contextSize;
+ return (0);
+}
+
+int AlgaChoiceChoose (algaChoice, encryptFlag, key, chooser, surrenderContext)
+AlgaChoice *algaChoice;
+int encryptFlag;
+B_Key *key;
+B_ALGORITHM_CHOOSER chooser;
+A_SURRENDER_CTX *surrenderContext;
+{
+ POINTER keyInfo;
+ int status, overallStatus;
+
+ /* Each alga init callback returns BE_NOT_SUPPORTED if the Query fails.
+ Each also may return a more specific error like BE_MODULUS_LEN if the
+ method is not supported, so return the more specific error if possible.
+ */
+ overallStatus = BE_METHOD_NOT_IN_CHOOSER;
+
+ for (; *chooser != (B_ALGORITHM_METHOD *)NULL_PTR; chooser++) {
+ if ((*chooser)->algorithmInfoType != algaChoice->_algorithmInfoType ||
+ (*chooser)->encryptFlag != encryptFlag)
+ /* Wrong type of algorithm, or the encryptFlag is wrong */
+ continue;
+
+ if ((*chooser)->keyInfoType != (struct B_KeyInfoType *)NULL_PTR) {
+ if ((status = B_KeyGetInfo
+ (key, &keyInfo, (*chooser)->keyInfoType)) != 0) {
+ if (IS_FATAL_BSAFE_ERROR (status))
+ return (status);
+
+ /* Update the overall status with this more specific error. */
+ overallStatus = status;
+ continue;
+ }
+ }
+ else
+ keyInfo = NULL_PTR;
+
+ if ((status = (*algaChoice->_InitAlga)
+ (algaChoice, keyInfo, *chooser, surrenderContext)) != 0) {
+ if (IS_FATAL_BSAFE_ERROR (status))
+ return (status);
+
+ /* Update the overall status with this more specific error. */
+ overallStatus = status;
+ continue;
+ }
+
+ /* Succeeded */
+ algaChoice->_alga = (*chooser)->alga;
+ return (0);
+ }
+
+ return (overallStatus);
+}
+
+/* Convert the ALGAE error to a BSAFE2 error.
+ This does not check for zero since BSAFE should not bother to call
+ this function if there is no error.
+ */
+int ConvertAlgaeError (type)
+int type;
+{
+ switch (type) {
+ case AE_CANCEL:
+ return (BE_CANCEL);
+ case AE_DATA:
+ return (BE_DATA);
+ case AE_EXPONENT_EVEN:
+ return (BE_EXPONENT_EVEN);
+ case AE_EXPONENT_LEN:
+ return (BE_EXPONENT_LEN);
+ case AE_INPUT_DATA:
+ return (BE_INPUT_DATA);
+ case AE_INPUT_LEN:
+ return (BE_INPUT_LEN);
+ case AE_KEY_INFO:
+ return (BE_KEY_INFO);
+ case AE_KEY_LEN:
+ return (BE_KEY_LEN);
+ case AE_MODULUS_LEN:
+ return (BE_MODULUS_LEN);
+ case AE_NOT_INITIALIZED:
+ return (BE_NOT_INITIALIZED);
+ case AE_NOT_SUPPORTED:
+ return (BE_NOT_SUPPORTED);
+ case AE_OUTPUT_LEN:
+ return (BE_OUTPUT_LEN);
+ case AE_PARAMS:
+ return (BE_ALGORITHM_INFO);
+
+#if USE_ALLOCED_FRAME
+ case AE_ALLOC:
+ return (BE_ALLOC);
+#endif
+
+ default:
+ return (BE_DATA);
+ }
+}
+
diff --git a/lib/dns/sec/dnssafe/algchoic.h b/lib/dns/sec/dnssafe/algchoic.h
new file mode 100644
index 00000000..5743441d
--- /dev/null
+++ b/lib/dns/sec/dnssafe/algchoic.h
@@ -0,0 +1,111 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _ALGCHOICE_H_
+#define _ALGCHOICE_H_ 1
+
+#define IS_FATAL_BSAFE_ERROR(status) \
+ (status == BE_ALLOC || status == BE_HARDWARE || status == BE_CANCEL)
+
+/* Use the THIS_ALGA_CHOICE macro to define the type of object in the
+ INIT_ALGA prototype. It defaults to the AlgaChoice, but
+ derived modules may define the macro to a more derived class before
+ including this header file.
+ */
+struct AlgaChoice;
+#ifndef THIS_ALGA_CHOICE
+#define THIS_ALGA_CHOICE struct AlgaChoice
+#endif
+
+/* In C++:
+class ResizeContext {
+public:
+ ResizeContext ();
+ ~ResizeContext ();
+ int makeNewContext (unsigned int contextSize);
+ POINTER context () {return z.context;}
+
+private:
+ struct {
+ POINTER context;
+ unsigned int contextSize;
+ } z;
+};
+
+class AlgaChoice;
+typedef int (*INIT_ALGA)
+ (THIS_ALGA_CHOICE *algaChoice, POINTER keyInfo,
+ struct B_ALGORITHM_METHOD *algorithmMethod,
+ A_SURRENDER_CTX *surrenderContext);
+
+class AlgaChoice {
+public:
+ AlgaChoice (INIT_ALGA InitAlga) : _InitAlga (InitAlga) {}
+ ~AlgaChoice () {}
+ int choose
+ (int encryptFlag, B_Key *key, B_ALGORITHM_CHOOSER chooser,
+ A_SURRENDER_CTX *surrenderContext);
+ int makeNewContext (unsigned int contextSize) {
+ context.makeNewContext (contextSize); }
+ POINTER alga () {return _alga;}
+ POINTER algorithmInfo () {return _algorithmInfo;}
+ POINTER context () {return context.context ();}
+ void setAlgorithmInfoType (B_AlgorithmInfoType *algorithmInfoType) {
+ _algorithmInfoType = algorithmInfoType;
+ }
+ void setAlgorithmInfo (POINTER algorithmInfo) {
+ _algorithmInfo = algorithmInfo;
+ }
+
+private:
+ POINTER _alga;
+ B_AlgorithmInfoType *_algorithmInfoType;
+ POINTER _algorithmInfo;
+ INIT_ALGA _InitAlga;
+
+ ResizeContext context;
+};
+ */
+struct B_AlgorithmInfoType;
+
+typedef struct ResizeContext {
+ struct {
+ POINTER context;
+ unsigned int contextSize;
+ } z; /* zeriozed by constructor */
+} ResizeContext;
+
+typedef int (*INIT_ALGA) PROTO_LIST
+ ((THIS_ALGA_CHOICE *, POINTER, struct B_ALGORITHM_METHOD *,
+ A_SURRENDER_CTX *));
+
+typedef struct AlgaChoice {
+ POINTER _alga;
+ struct B_AlgorithmInfoType *_algorithmInfoType;
+ POINTER _algorithmInfo;
+ INIT_ALGA _InitAlga;
+
+ ResizeContext context;
+} AlgaChoice;
+
+void ResizeContextConstructor PROTO_LIST ((ResizeContext *));
+void ResizeContextDestructor PROTO_LIST ((ResizeContext *));
+int ResizeContextMakeNewContext PROTO_LIST ((ResizeContext *, unsigned int));
+
+#define ALGA_CHOICE_Constructor(algaChoice, InitAlga)\
+ (ResizeContextConstructor (&(algaChoice)->context), \
+ (algaChoice)->_InitAlga = (InitAlga))
+#define ALGA_CHOICE_Destructor(algaChoice)\
+ (ResizeContextDestructor (&(algaChoice)->context))
+
+int AlgaChoiceChoose PROTO_LIST
+ ((AlgaChoice *, int, B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *));
+
+int ConvertAlgaeError PROTO_LIST ((int));
+
+#endif
diff --git a/lib/dns/sec/dnssafe/algobj.c b/lib/dns/sec/dnssafe/algobj.c
new file mode 100644
index 00000000..d872d248
--- /dev/null
+++ b/lib/dns/sec/dnssafe/algobj.c
@@ -0,0 +1,121 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "ainfotyp.h"
+#include "keyobj.h"
+#include "algobj.h"
+
+static char ALGORITHM_TYPE_TAG = 0;
+
+int B_CreateAlgorithmObject (algorithmObject)
+B_ALGORITHM_OBJ *algorithmObject;
+{
+ AlgorithmWrap *algorithmWrap;
+
+ if ((*algorithmObject = T_malloc (sizeof (*algorithmWrap))) == NULL_PTR)
+ return (BE_ALLOC);
+
+ algorithmWrap = (AlgorithmWrap *)*algorithmObject;
+
+ /* First construct base class */
+ B_AlgorithmConstructor (&algorithmWrap->algorithm);
+
+ algorithmWrap->typeTag = &ALGORITHM_TYPE_TAG;
+ algorithmWrap->selfCheck = algorithmWrap;
+ return (0);
+}
+
+void B_DestroyAlgorithmObject (algorithmObject)
+B_ALGORITHM_OBJ *algorithmObject;
+{
+ AlgorithmWrap *algorithmWrap = (AlgorithmWrap *)*algorithmObject;
+
+ if (AlgorithmWrapCheck (algorithmWrap) == 0) {
+ /* zeroize self check to invalidate memory. */
+ algorithmWrap->selfCheck = (AlgorithmWrap *)NULL_PTR;
+
+ /* Call base class descructor */
+ B_AlgorithmDestructor (&algorithmWrap->algorithm);
+
+ T_free ((POINTER)algorithmWrap);
+ }
+
+ *algorithmObject = NULL_PTR;
+}
+
+int B_SetAlgorithmInfo (algorithmObject, infoType, info)
+B_ALGORITHM_OBJ algorithmObject;
+B_INFO_TYPE infoType;
+POINTER info;
+{
+ B_AlgorithmInfoType *algorithmInfoType;
+ int status;
+
+ if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0)
+ return (status);
+
+ /* Get the AlgorithmInfoType from the B_INFO_TYPE, which returns
+ zero for an AlgorithmInfoType, non-zero for KeyInfoType
+ */
+ if ((*infoType) ((POINTER *)&algorithmInfoType) != 0)
+ return (BE_KEY_OPERATION_UNKNOWN);
+
+ return (B_AlgorithmSetInfo
+ (&THE_ALG_WRAP->algorithm, algorithmInfoType, info));
+}
+
+int B_GetAlgorithmInfo (info, algorithmObject, infoType)
+POINTER *info;
+B_ALGORITHM_OBJ algorithmObject;
+B_INFO_TYPE infoType;
+{
+ B_AlgorithmInfoType *algorithmInfoType;
+ int status;
+
+ if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0)
+ return (status);
+
+ /* Get the AlgorithmInfoType from the B_INFO_TYPE, which returns
+ zero for an AlgorithmInfoType, non-zero for KeyInfoType
+ */
+ if ((*infoType) ((POINTER *)&algorithmInfoType) != 0)
+ return (BE_KEY_OPERATION_UNKNOWN);
+
+ return (B_AlgorithmGetInfo
+ (&THE_ALG_WRAP->algorithm, info, algorithmInfoType));
+}
+
+/* Return 0 if this is a valid AlgorithmWrap object. Return BE_ALGORITHM_OBJ if
+ algorithmWrap is NULL_PTR or invalid.
+ */
+int AlgorithmWrapCheck (algorithmWrap)
+AlgorithmWrap *algorithmWrap;
+{
+ return ((algorithmWrap != (AlgorithmWrap *)NULL_PTR &&
+ algorithmWrap->selfCheck == algorithmWrap &&
+ algorithmWrap->typeTag == &ALGORITHM_TYPE_TAG) ?
+ 0 : BE_ALGORITHM_OBJ);
+}
+
+/* Like AlgorithmWrapCheck except returns BE_RANDOM_OBJ for error.
+ Also, return OK status if randomAlgorithm is NULL_PTR.
+ */
+int RandomAlgorithmCheck (randomAlgorithm)
+B_ALGORITHM_OBJ randomAlgorithm;
+{
+ if (randomAlgorithm == NULL_PTR)
+ return (0);
+
+ return (AlgorithmWrapCheck ((AlgorithmWrap *)randomAlgorithm) ?
+ BE_RANDOM_OBJ : 0);
+}
+
diff --git a/lib/dns/sec/dnssafe/algobj.h b/lib/dns/sec/dnssafe/algobj.h
new file mode 100644
index 00000000..7f87cfae
--- /dev/null
+++ b/lib/dns/sec/dnssafe/algobj.h
@@ -0,0 +1,19 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#define THE_ALG_WRAP ((AlgorithmWrap *)algorithmObject)
+
+typedef struct AlgorithmWrap {
+ B_Algorithm algorithm;
+ char *typeTag;
+ struct AlgorithmWrap *selfCheck;
+} AlgorithmWrap;
+
+int AlgorithmWrapCheck PROTO_LIST ((AlgorithmWrap *));
+int RandomAlgorithmCheck PROTO_LIST ((B_ALGORITHM_OBJ));
+
diff --git a/lib/dns/sec/dnssafe/amcrte.c b/lib/dns/sec/dnssafe/amcrte.c
new file mode 100644
index 00000000..d1e1c2a8
--- /dev/null
+++ b/lib/dns/sec/dnssafe/amcrte.c
@@ -0,0 +1,117 @@
+/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "algae.h"
+#include "bsafe2.h"
+#include "balgmeth.h"
+#include "crt2.h"
+#include "amencdec.h"
+
+static int RSA_CRT2Query PROTO_LIST ((unsigned int *, POINTER, POINTER));
+static int RSA_CRT2Init PROTO_LIST
+ ((POINTER, POINTER, POINTER, A_SURRENDER_CTX *));
+static int RSA_CRT2Update PROTO_LIST
+ ((POINTER, unsigned char *, unsigned int *, unsigned int,
+ unsigned char *, unsigned int, A_SURRENDER_CTX *));
+static int RSA_CRT2Final PROTO_LIST
+ ((POINTER, unsigned char *, unsigned int *, unsigned int,
+ A_SURRENDER_CTX *));
+static int RSA_CRT2GetMaxOutputLen PROTO_LIST
+ ((POINTER, unsigned int *, unsigned int));
+static int RSA_CRT2GetBlockLen PROTO_LIST ((POINTER, unsigned int *));
+
+extern struct B_AlgorithmInfoType AIT_RSAPrivate;
+extern struct B_KeyInfoType KIT_RSA_CRT;
+
+static A_ENCRYPT_DECRYPT_ALGA A_RSA_CRT2_CRYPT = {
+ RSA_CRT2Query, RSA_CRT2Init, RSA_CRT2Update, RSA_CRT2Final,
+ RSA_CRT2GetMaxOutputLen, RSA_CRT2GetBlockLen
+};
+
+B_ALGORITHM_METHOD AM_RSA_CRT_DECRYPT =
+ {&AIT_RSAPrivate, 0, &KIT_RSA_CRT, (POINTER)&A_RSA_CRT2_CRYPT};
+B_ALGORITHM_METHOD AM_RSA_CRT_ENCRYPT =
+ {&AIT_RSAPrivate, 1, &KIT_RSA_CRT, (POINTER)&A_RSA_CRT2_CRYPT};
+
+static int RSA_CRT2Query (contextLen, key, params)
+unsigned int *contextLen;
+POINTER key;
+POINTER params;
+{
+UNUSED_ARG (params)
+
+ if (A_IntegerBits
+ (((A_RSA_CRT_KEY *)key)->modulus.data,
+ ((A_RSA_CRT_KEY *)key)->modulus.len) > MAX_RSA_MODULUS_BITS)
+ /* Key size is too big to handle. */
+ return (AE_MODULUS_LEN);
+
+ *contextLen = sizeof (A_RSA_CRT2_CTX);
+ return (0);
+}
+
+static int RSA_CRT2Init (context, key, params, surrenderContext)
+POINTER context;
+POINTER key;
+POINTER params;
+A_SURRENDER_CTX *surrenderContext;
+{
+UNUSED_ARG (params)
+UNUSED_ARG (surrenderContext)
+
+ return (A_RSA_CRT2Init ((A_RSA_CRT2_CTX *)context, (A_RSA_CRT_KEY *)key));
+}
+
+static int RSA_CRT2Update
+ (context, output, outputLen, maxOutputLen, input, inputLen, surrenderContext)
+POINTER context;
+unsigned char *output;
+unsigned int *outputLen;
+unsigned int maxOutputLen;
+unsigned char *input;
+unsigned int inputLen;
+A_SURRENDER_CTX *surrenderContext;
+{
+ return (A_RSA_CRT2Update
+ ((A_RSA_CRT2_CTX *)context, output, outputLen, maxOutputLen, input,
+ inputLen, surrenderContext));
+}
+
+static int RSA_CRT2Final
+ (context, output, outputLen, maxOutputLen, surrenderContext)
+POINTER context;
+unsigned char *output;
+unsigned int *outputLen;
+unsigned int maxOutputLen;
+A_SURRENDER_CTX * surrenderContext;
+{
+UNUSED_ARG (output)
+UNUSED_ARG (maxOutputLen)
+UNUSED_ARG (surrenderContext)
+
+ *outputLen = 0;
+ return (A_RSA_CRT2Final ((A_RSA_CRT2_CTX *)context));
+}
+
+static int RSA_CRT2GetMaxOutputLen (context, outputLen, inputLen)
+POINTER context;
+unsigned int *outputLen;
+unsigned int inputLen;
+{
+ *outputLen = A_RSA_CRT2_MAX_OUTPUT_LEN ((A_RSA_CRT2_CTX *)context, inputLen);
+ return (0);
+}
+
+static int RSA_CRT2GetBlockLen (context, blockLen)
+POINTER context;
+unsigned int *blockLen;
+{
+ *blockLen = A_RSA_CRT2_BLOCK_LEN ((A_RSA_CRT2_CTX *)context);
+ return(0);
+}
diff --git a/lib/dns/sec/dnssafe/amdigest.h b/lib/dns/sec/dnssafe/amdigest.h
new file mode 100644
index 00000000..5b8f5662
--- /dev/null
+++ b/lib/dns/sec/dnssafe/amdigest.h
@@ -0,0 +1,19 @@
+/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+typedef struct {
+ int (*Query) PROTO_LIST ((unsigned int *, POINTER));
+ int (*Init) PROTO_LIST ((POINTER, POINTER, A_SURRENDER_CTX *));
+ int (*Update) PROTO_LIST
+ ((POINTER, unsigned char *, unsigned int, A_SURRENDER_CTX *));
+ int (*Final) PROTO_LIST
+ ((POINTER, unsigned char *, unsigned int *, unsigned int,
+ A_SURRENDER_CTX *));
+ int (*GetMaxOutputLen) PROTO_LIST ((POINTER, unsigned int *));
+} A_DIGEST_ALGA;
+
diff --git a/lib/dns/sec/dnssafe/amencdec.h b/lib/dns/sec/dnssafe/amencdec.h
new file mode 100644
index 00000000..8f91a0fa
--- /dev/null
+++ b/lib/dns/sec/dnssafe/amencdec.h
@@ -0,0 +1,21 @@
+/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+typedef struct {
+ int (*Query) PROTO_LIST ((unsigned int *, POINTER, POINTER));
+ int (*Init) PROTO_LIST ((POINTER, POINTER, POINTER, A_SURRENDER_CTX *));
+ int (*Update) PROTO_LIST
+ ((POINTER, unsigned char *, unsigned int *, unsigned int,
+ unsigned char *, unsigned int, A_SURRENDER_CTX *));
+ int (*Final) PROTO_LIST
+ ((POINTER, unsigned char *, unsigned int *, unsigned int,
+ A_SURRENDER_CTX *));
+ int (*GetMaxOutputLen) PROTO_LIST ((POINTER, unsigned int *, unsigned int));
+ int (*GetBlockLen) PROTO_LIST ((POINTER, unsigned int *));
+} A_ENCRYPT_DECRYPT_ALGA;
+
diff --git a/lib/dns/sec/dnssafe/amgen.h b/lib/dns/sec/dnssafe/amgen.h
new file mode 100644
index 00000000..ffdf4576
--- /dev/null
+++ b/lib/dns/sec/dnssafe/amgen.h
@@ -0,0 +1,19 @@
+/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+struct B_KeyInfoType;
+
+typedef struct {
+ int (*Query) PROTO_LIST
+ ((unsigned int *, unsigned int *, unsigned int *, struct B_KeyInfoType **,
+ POINTER));
+ int (*Init) PROTO_LIST ((POINTER, POINTER, POINTER, A_SURRENDER_CTX *));
+ int (*Generate) PROTO_LIST
+ ((POINTER, POINTER *, unsigned char *, A_SURRENDER_CTX *));
+} A_GENERATE_ALGA;
+
diff --git a/lib/dns/sec/dnssafe/ammd5.c b/lib/dns/sec/dnssafe/ammd5.c
new file mode 100644
index 00000000..ac8ac48c
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ammd5.c
@@ -0,0 +1,100 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "algae.h"
+#include "bsafe2.h"
+#include "balgmeth.h"
+#include "md5.h"
+#include "amdigest.h"
+
+static int MD5Query PROTO_LIST ((unsigned int *, POINTER));
+static int MD5Init PROTO_LIST ((POINTER, POINTER, A_SURRENDER_CTX*));
+static int MD5Update PROTO_LIST
+ ((POINTER, unsigned char *, unsigned int, A_SURRENDER_CTX*));
+static int MD5Final PROTO_LIST
+ ((POINTER, unsigned char *, unsigned int *, unsigned int, A_SURRENDER_CTX*));
+static int MD5GetMaxOutputLen PROTO_LIST ((POINTER, unsigned int *));
+
+static A_DIGEST_ALGA A_MD5_DIGEST = {
+ MD5Query, MD5Init, MD5Update, MD5Final, MD5GetMaxOutputLen
+};
+
+extern struct B_AlgorithmInfoType AIT_MD5;
+
+B_ALGORITHM_METHOD AM_MD5 =
+ {&AIT_MD5, 0, (struct B_KeyInfoType *)NULL_PTR, (POINTER)&A_MD5_DIGEST};
+
+/* Returns 0.
+ */
+static int MD5Query (contextLen, params)
+unsigned int *contextLen;
+POINTER params;
+{
+UNUSED_ARG (params)
+
+ *contextLen = sizeof (A_MD5_CTX);
+ return (0);
+}
+
+/* Returns 0.
+ */
+static int MD5Init (context, params, surrenderContext)
+POINTER context;
+POINTER params;
+A_SURRENDER_CTX *surrenderContext;
+{
+UNUSED_ARG (params)
+UNUSED_ARG (surrenderContext)
+
+ A_MD5Init ((A_MD5_CTX *)context);
+ return (0);
+}
+
+/* Returns 0.
+ */
+static int MD5Update (context, input, inputLen, surrenderContext)
+POINTER context;
+unsigned char *input;
+unsigned int inputLen;
+A_SURRENDER_CTX *surrenderContext;
+{
+UNUSED_ARG (surrenderContext)
+
+ A_MD5Update ((A_MD5_CTX *)context, input, inputLen);
+ return (0);
+}
+
+/* Returns 0, AE_OUTPUT_LEN if maxDigestLen is too small.
+ */
+static int MD5Final
+ (context, digest, digestLen, maxDigestLen, surrenderContext)
+POINTER context;
+unsigned char *digest;
+unsigned int *digestLen;
+unsigned int maxDigestLen;
+A_SURRENDER_CTX *surrenderContext;
+{
+UNUSED_ARG (surrenderContext)
+
+ if ((*digestLen = A_MD5_DIGEST_LEN) > maxDigestLen)
+ return (AE_OUTPUT_LEN);
+
+ A_MD5Final ((A_MD5_CTX *)context, digest);
+ return (0);
+}
+
+static int MD5GetMaxOutputLen (context, outputLen)
+POINTER context;
+unsigned int *outputLen;
+{
+UNUSED_ARG (context)
+
+ *outputLen = A_MD5_DIGEST_LEN;
+ return(0);
+}
diff --git a/lib/dns/sec/dnssafe/ammd5r.c b/lib/dns/sec/dnssafe/ammd5r.c
new file mode 100644
index 00000000..728bd7a3
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ammd5r.c
@@ -0,0 +1,77 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "algae.h"
+#include "bsafe2.h"
+#include "balgmeth.h"
+#include "md5rand.h"
+#include "amrandom.h"
+
+static int MD5RandomQuery PROTO_LIST ((unsigned int *, POINTER));
+static int MD5RandomInit PROTO_LIST ((POINTER, POINTER, A_SURRENDER_CTX *));
+static int MD5RandomUpdate PROTO_LIST
+ ((POINTER, unsigned char *, unsigned int, A_SURRENDER_CTX *));
+static int MD5RandomGenerateBytes PROTO_LIST
+ ((POINTER, unsigned char *, unsigned int, A_SURRENDER_CTX *));
+
+extern struct B_AlgorithmInfoType AIT_MD5Random;
+
+static A_RANDOM_ALGA A_MD5_RANDOM =
+ {MD5RandomQuery, MD5RandomInit, MD5RandomUpdate, MD5RandomGenerateBytes};
+
+B_ALGORITHM_METHOD AM_MD5_RANDOM =
+ {&AIT_MD5Random, 0, (struct B_KeyInfoType *)NULL_PTR,
+ (POINTER)&A_MD5_RANDOM};
+
+static int MD5RandomQuery (contextLen, params)
+unsigned int *contextLen;
+POINTER params;
+{
+UNUSED_ARG (params)
+
+ *contextLen = sizeof (A_MD5_RANDOM_CTX);
+ return (0);
+}
+
+static int MD5RandomInit (context, params, surrenderContext)
+POINTER context;
+POINTER params;
+A_SURRENDER_CTX *surrenderContext;
+{
+UNUSED_ARG (params)
+UNUSED_ARG (surrenderContext)
+
+ A_MD5RandomInit ((A_MD5_RANDOM_CTX *)context);
+ return (0);
+}
+
+static int MD5RandomUpdate (context, input, inputLen, surrenderContext)
+POINTER context;
+unsigned char *input;
+unsigned int inputLen;
+A_SURRENDER_CTX *surrenderContext;
+{
+UNUSED_ARG (surrenderContext)
+
+ A_MD5RandomUpdate ((A_MD5_RANDOM_CTX *)context, input, inputLen);
+ return (0);
+}
+
+static int MD5RandomGenerateBytes
+ (context, output, outputLen, surrenderContext)
+POINTER context;
+unsigned char *output;
+unsigned int outputLen;
+A_SURRENDER_CTX *surrenderContext;
+{
+UNUSED_ARG (surrenderContext)
+
+ A_MD5RandomGenerateBytes ((A_MD5_RANDOM_CTX *)context, output, outputLen);
+ return (0);
+}
diff --git a/lib/dns/sec/dnssafe/amrandom.h b/lib/dns/sec/dnssafe/amrandom.h
new file mode 100644
index 00000000..3b9539a0
--- /dev/null
+++ b/lib/dns/sec/dnssafe/amrandom.h
@@ -0,0 +1,17 @@
+/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+typedef struct {
+ int (*Query) PROTO_LIST ((unsigned int *, POINTER));
+ int (*Init) PROTO_LIST ((POINTER, POINTER, A_SURRENDER_CTX *));
+ int (*Update) PROTO_LIST
+ ((POINTER, unsigned char *, unsigned int, A_SURRENDER_CTX *));
+ int (*Generate) PROTO_LIST
+ ((POINTER, unsigned char *, unsigned int, A_SURRENDER_CTX *));
+} A_RANDOM_ALGA;
+
diff --git a/lib/dns/sec/dnssafe/amrkg.c b/lib/dns/sec/dnssafe/amrkg.c
new file mode 100644
index 00000000..59b6e111
--- /dev/null
+++ b/lib/dns/sec/dnssafe/amrkg.c
@@ -0,0 +1,81 @@
+/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "algae.h"
+#include "rsakeygn.h"
+#include "balgmeth.h"
+#include "amgen.h"
+
+#define THE_GEN_PARAMS ((A_RSA_KEY_GEN_PARAMS *)params)
+
+extern struct B_AlgorithmInfoType AIT_RSAKeyGen;
+extern struct B_KeyInfoType KIT_PKCS_RSAPrivate;
+
+static int RSAKeyGenQuery PROTO_LIST
+ ((unsigned int *, unsigned int *, unsigned int *, struct B_KeyInfoType **,
+ POINTER));
+static int RSAKeyGenInit PROTO_LIST
+ ((POINTER, POINTER, POINTER, A_SURRENDER_CTX *));
+static int RSAKeyGen PROTO_LIST
+ ((POINTER, POINTER *, unsigned char *, A_SURRENDER_CTX *));
+
+static A_GENERATE_ALGA A_RSA_KEY_GEN =
+ {RSAKeyGenQuery, RSAKeyGenInit, RSAKeyGen};
+
+B_ALGORITHM_METHOD AM_RSA_KEY_GEN =
+ {&AIT_RSAKeyGen, 0, (struct B_KeyInfoType *)NULL_PTR,
+ (POINTER)&A_RSA_KEY_GEN};
+
+static int RSAKeyGenQuery
+ (contextLen, secondContextLen, randomBlockLen, resultInfoType, params)
+unsigned int *contextLen;
+unsigned int *secondContextLen;
+unsigned int *randomBlockLen;
+struct B_KeyInfoType **resultInfoType;
+POINTER params;
+{
+ if ((THE_GEN_PARAMS->modulusBits > MAX_RSA_MODULUS_BITS) ||
+ (THE_GEN_PARAMS->modulusBits < MIN_RSA_MODULUS_BITS))
+ /* Can't support a keypair of this size. */
+ return (AE_MODULUS_LEN);
+
+ *contextLen = sizeof (A_RSA_KEY_GEN_CTX);
+ *secondContextLen = 0;
+ *randomBlockLen =
+ A_RSA_KEY_GEN_RANDOM_BLOCK_LEN (THE_GEN_PARAMS->modulusBits);
+ *resultInfoType = &KIT_PKCS_RSAPrivate;
+
+ return (0);
+}
+
+static int RSAKeyGenInit (context, secondContext, params, surrenderContext)
+POINTER context;
+POINTER secondContext;
+POINTER params;
+A_SURRENDER_CTX *surrenderContext;
+{
+UNUSED_ARG (secondContext)
+UNUSED_ARG (surrenderContext)
+
+ return (A_RSAKeyGenInit
+ ((A_RSA_KEY_GEN_CTX *)context, (A_RSA_KEY_GEN_PARAMS *)params));
+}
+
+static int RSAKeyGen (context, result, randomBlock, surrenderContext)
+POINTER context;
+POINTER *result;
+unsigned char *randomBlock;
+A_SURRENDER_CTX *surrenderContext;
+{
+ return (A_RSAKeyGen
+ ((A_RSA_KEY_GEN_CTX *)context, (A_PKCS_RSA_PRIVATE_KEY **)result,
+ randomBlock, surrenderContext));
+}
+
diff --git a/lib/dns/sec/dnssafe/amrsae.c b/lib/dns/sec/dnssafe/amrsae.c
new file mode 100644
index 00000000..674cb253
--- /dev/null
+++ b/lib/dns/sec/dnssafe/amrsae.c
@@ -0,0 +1,115 @@
+/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "algae.h"
+#include "bsafe2.h"
+#include "balgmeth.h"
+#include "rsa.h"
+#include "amencdec.h"
+
+static int RSAQuery PROTO_LIST ((unsigned int *, POINTER, POINTER));
+static int RSAInit PROTO_LIST ((POINTER, POINTER, POINTER, A_SURRENDER_CTX *));
+static int RSAUpdate PROTO_LIST
+ ((POINTER, unsigned char *, unsigned int *, unsigned int,
+ unsigned char *, unsigned int, A_SURRENDER_CTX *));
+static int RSAFinal PROTO_LIST
+ ((POINTER, unsigned char *, unsigned int *, unsigned int,
+ A_SURRENDER_CTX *));
+static int RSAGetMaxOutputLen PROTO_LIST
+ ((POINTER, unsigned int *, unsigned int));
+static int RSAGetBlockLen PROTO_LIST ((POINTER, unsigned int *));
+
+extern struct B_AlgorithmInfoType AIT_RSAPublic;
+extern struct B_KeyInfoType KIT_RSAPublic;
+
+static A_ENCRYPT_DECRYPT_ALGA A_RSA_CRYPT = {
+ RSAQuery, RSAInit, RSAUpdate, RSAFinal, RSAGetMaxOutputLen, RSAGetBlockLen
+};
+
+B_ALGORITHM_METHOD AM_RSA_DECRYPT =
+ {&AIT_RSAPublic, 0, &KIT_RSAPublic, (POINTER)&A_RSA_CRYPT};
+B_ALGORITHM_METHOD AM_RSA_ENCRYPT =
+ {&AIT_RSAPublic, 1, &KIT_RSAPublic, (POINTER)&A_RSA_CRYPT};
+
+static int RSAQuery (contextLen, key, params)
+unsigned int *contextLen;
+POINTER key;
+POINTER params;
+{
+UNUSED_ARG (params)
+
+ if (A_IntegerBits
+ (((A_RSA_KEY *)key)->modulus.data, ((A_RSA_KEY *)key)->modulus.len)
+ > MAX_RSA_MODULUS_BITS)
+ /* Key size is too big to handle. */
+ return (AE_MODULUS_LEN);
+
+ *contextLen = sizeof (A_RSA_CTX);
+ return (0);
+}
+
+static int RSAInit (context, key, params, surrenderContext)
+POINTER context;
+POINTER key;
+POINTER params;
+A_SURRENDER_CTX *surrenderContext;
+{
+UNUSED_ARG (params)
+UNUSED_ARG (surrenderContext)
+
+ return (A_RSAInit ((A_RSA_CTX *)context, (A_RSA_KEY *)key));
+}
+
+static int RSAUpdate
+ (context, output, outputLen, maxOutputLen, input, inputLen, surrenderContext)
+POINTER context;
+unsigned char *output;
+unsigned int *outputLen;
+unsigned int maxOutputLen;
+unsigned char *input;
+unsigned int inputLen;
+A_SURRENDER_CTX *surrenderContext;
+{
+ return (A_RSAUpdate
+ ((A_RSA_CTX *)context, output, outputLen, maxOutputLen, input,
+ inputLen, surrenderContext));
+}
+
+static int RSAFinal
+ (context, output, outputLen, maxOutputLen, surrenderContext)
+POINTER context;
+unsigned char *output;
+unsigned int *outputLen;
+unsigned int maxOutputLen;
+A_SURRENDER_CTX * surrenderContext;
+{
+UNUSED_ARG (output)
+UNUSED_ARG (maxOutputLen)
+UNUSED_ARG (surrenderContext)
+
+ *outputLen = 0;
+ return (A_RSAFinal ((A_RSA_CTX *)context));
+}
+
+static int RSAGetMaxOutputLen (context, outputLen, inputLen)
+POINTER context;
+unsigned int *outputLen;
+unsigned int inputLen;
+{
+ *outputLen = A_RSA_MAX_OUTPUT_LEN ((A_RSA_CTX *)context, inputLen);
+ return (0);
+}
+
+static int RSAGetBlockLen (context, blockLen)
+POINTER context;
+unsigned int *blockLen;
+{
+ *blockLen = A_RSA_BLOCK_LEN ((A_RSA_CTX *)context);
+ return(0);
+}
diff --git a/lib/dns/sec/dnssafe/atypes.h b/lib/dns/sec/dnssafe/atypes.h
new file mode 100644
index 00000000..e1af4eac
--- /dev/null
+++ b/lib/dns/sec/dnssafe/atypes.h
@@ -0,0 +1,60 @@
+/* Copyright (C) RSA Data Security, Inc. created 1992, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _ATYPES_H_
+#define _ATYPES_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ITEM_
+#define _ITEM_ 1
+typedef struct {
+ unsigned char *data;
+ unsigned int len;
+} ITEM;
+#endif
+
+typedef struct {
+ int (T_CALL *Surrender) PROTO_LIST ((POINTER));
+ POINTER handle;
+ POINTER reserved;
+} A_SURRENDER_CTX;
+
+typedef struct {
+ ITEM modulus;
+ ITEM publicExponent;
+ ITEM privateExponent;
+ ITEM prime[2]; /* prime factors */
+ ITEM primeExponent[2]; /* exponents for prime factors */
+ ITEM coefficient; /* CRT coefficient */
+} A_PKCS_RSA_PRIVATE_KEY;
+
+typedef struct {
+ ITEM modulus;
+ ITEM prime[2]; /* prime factors */
+ ITEM primeExponent[2]; /* exponents for prime factors */
+ ITEM coefficient; /* CRT coefficient */
+} A_RSA_CRT_KEY;
+
+typedef struct {
+ ITEM modulus; /* modulus */
+ ITEM exponent; /* exponent */
+} A_RSA_KEY;
+
+typedef struct {
+ unsigned int modulusBits;
+ ITEM publicExponent;
+} A_RSA_KEY_GEN_PARAMS;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/dns/sec/dnssafe/balg.c b/lib/dns/sec/dnssafe/balg.c
new file mode 100644
index 00000000..b0b9bbb7
--- /dev/null
+++ b/lib/dns/sec/dnssafe/balg.c
@@ -0,0 +1,115 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "btypechk.h"
+#include "ainfotyp.h"
+
+void B_AlgorithmConstructor (algorithm)
+B_Algorithm *algorithm;
+{
+ /* Construct immediate base class. */
+ B_InfoCacheConstructor (&algorithm->infoCache);
+
+ T_memset ((POINTER)&algorithm->z, 0, sizeof (algorithm->z));
+}
+
+void B_AlgorithmDestructor (algorithm)
+B_Algorithm *algorithm;
+{
+ if (algorithm->z.handler != (B_TypeCheck *)NULL_PTR) {
+ B_TYPE_CHECK_Destructor (algorithm->z.handler);
+ T_free ((POINTER)algorithm->z.handler);
+ }
+
+ /* Destroy base class */
+ B_INFO_CACHE_Destructor (&algorithm->infoCache);
+}
+
+int B_AlgorithmCheckType (algorithm, Destructor)
+B_Algorithm *algorithm;
+B_TYPE_CHECK_DESTRUCTOR Destructor;
+{
+ if (algorithm->z.handler == (B_TypeCheck *)NULL_PTR)
+ return (BE_ALGORITHM_NOT_SET);
+
+ if (algorithm->z.handler->_Destructor != Destructor)
+ return (BE_ALG_OPERATION_UNKNOWN);
+
+ return (0);
+}
+
+int B_AlgorithmCheckTypeAndInitFlag (algorithm, Destructor)
+B_Algorithm *algorithm;
+B_TYPE_CHECK_DESTRUCTOR Destructor;
+{
+ int status;
+
+ /* Check the type first. */
+ if ((status = B_AlgorithmCheckType (algorithm, Destructor)) != 0)
+ return (status);
+
+ if (!algorithm->z.initFlag)
+ return (BE_ALGORITHM_NOT_INITIALIZED);
+
+ return (0);
+}
+
+int B_AlgorithmSetInfo (algorithm, algorithmInfoType, info)
+B_Algorithm *algorithm;
+B_AlgorithmInfoType *algorithmInfoType;
+POINTER info;
+{
+ int status;
+
+ if (algorithm->infoCache.z.infoCount > 0)
+ return (BE_ALGORITHM_ALREADY_SET);
+
+ /* This will cache the encoding. */
+ if ((status = (*algorithmInfoType->vTable->AddInfo)
+ (algorithmInfoType, algorithm, info)) != 0)
+ return (status);
+
+ /* Allocate the algorithm handler. NewHandler returns NULL_PTR for error.
+ */
+ if ((algorithm->z.handler = (*algorithmInfoType->vTable->NewHandler)
+ (algorithmInfoType, algorithm)) == (B_TypeCheck *)NULL_PTR)
+ return (BE_ALLOC);
+
+ return (0);
+}
+
+int B_AlgorithmGetInfo (algorithm, info, algorithmInfoType)
+B_Algorithm *algorithm;
+POINTER *info;
+B_AlgorithmInfoType *algorithmInfoType;
+{
+ int status;
+
+ if (algorithm->infoCache.z.infoCount == 0)
+ return (BE_ALGORITHM_NOT_SET);
+
+ /* First check if the encoding is already in the encoding cache.
+ */
+ if (B_InfoCacheFindInfo
+ (&algorithm->infoCache, info, (POINTER)algorithmInfoType) == 0)
+ return (0);
+
+ /* Info is not in the cache, go ahead and encode.
+ */
+ if ((status = (*algorithmInfoType->vTable->MakeInfo)
+ (algorithmInfoType, info, algorithm)) != 0)
+ return (status);
+
+ return (B_InfoCacheAddInfo
+ (&algorithm->infoCache, (POINTER)algorithmInfoType, *info));
+}
+
diff --git a/lib/dns/sec/dnssafe/balg.h b/lib/dns/sec/dnssafe/balg.h
new file mode 100644
index 00000000..fdbc269b
--- /dev/null
+++ b/lib/dns/sec/dnssafe/balg.h
@@ -0,0 +1,116 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _BALG_H_
+#define _BALG_H_ 1
+
+#include "binfocsh.h"
+#include "btypechk.h"
+
+typedef struct {
+ B_InfoCache infoCache; /* inherited */
+
+ struct {
+ B_TypeCheck *handler;
+ int initFlag;
+ /* POINTER reserved; */
+ } z;
+} B_Algorithm;
+
+void B_AlgorithmConstructor PROTO_LIST ((B_Algorithm *));
+void B_AlgorithmDestructor PROTO_LIST ((B_Algorithm *));
+
+int B_AlgorithmCheckType PROTO_LIST ((B_Algorithm *, B_TYPE_CHECK_DESTRUCTOR));
+int B_AlgorithmCheckTypeAndInitFlag PROTO_LIST
+ ((B_Algorithm *, B_TYPE_CHECK_DESTRUCTOR));
+
+struct B_AlgorithmInfoType;
+int B_AlgorithmSetInfo PROTO_LIST
+ ((B_Algorithm *, struct B_AlgorithmInfoType *, POINTER));
+int B_AlgorithmGetInfo PROTO_LIST
+ ((B_Algorithm *, POINTER *, struct B_AlgorithmInfoType *));
+
+int B_AlgorithmRandomInit PROTO_LIST
+ ((B_Algorithm *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *));
+int B_AlgorithmRandomUpdate PROTO_LIST
+ ((B_Algorithm *, unsigned char *, unsigned int, A_SURRENDER_CTX *));
+int B_AlgorithmGenerateRandomBytes PROTO_LIST
+ ((B_Algorithm *, unsigned char *, unsigned int, A_SURRENDER_CTX *));
+
+int B_AlgorithmDigestInit PROTO_LIST
+ ((B_Algorithm *, B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *));
+int B_AlgorithmDigestUpdate PROTO_LIST
+ ((B_Algorithm *, unsigned char *, unsigned int, A_SURRENDER_CTX *));
+int B_AlgorithmDigestFinal PROTO_LIST
+ ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int,
+ A_SURRENDER_CTX *));
+
+int B_AlgorithmEncryptInit PROTO_LIST
+ ((B_Algorithm *, B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *));
+int B_AlgorithmDecryptInit PROTO_LIST
+ ((B_Algorithm *, B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *));
+int B_AlgorithmEncryptUpdate PROTO_LIST
+ ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int,
+ unsigned char *, unsigned int, B_Algorithm *, A_SURRENDER_CTX *));
+int B_AlgorithmDecryptUpdate PROTO_LIST
+ ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int,
+ unsigned char *, unsigned int, B_Algorithm *, A_SURRENDER_CTX *));
+int B_AlgorithmEncryptFinal PROTO_LIST
+ ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int,
+ B_Algorithm *, A_SURRENDER_CTX *));
+int B_AlgorithmDecryptFinal PROTO_LIST
+ ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int,
+ B_Algorithm *, A_SURRENDER_CTX *));
+
+int B_AlgorithmEncodeInit PROTO_LIST ((B_Algorithm *));
+int B_AlgorithmDecodeInit PROTO_LIST ((B_Algorithm *));
+int B_AlgorithmEncodeUpdate PROTO_LIST
+ ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int,
+ unsigned char *, unsigned int));
+int B_AlgorithmDecodeUpdate PROTO_LIST
+ ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int,
+ unsigned char *, unsigned int));
+int B_AlgorithmEncodeFinal PROTO_LIST
+ ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int));
+int B_AlgorithmDecodeFinal PROTO_LIST
+ ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int));
+
+int B_AlgorithmSignInit PROTO_LIST
+ ((B_Algorithm *, B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *));
+int B_AlgorithmSignUpdate PROTO_LIST
+ ((B_Algorithm *, unsigned char *, unsigned int, A_SURRENDER_CTX *));
+int B_AlgorithmSignFinal PROTO_LIST
+ ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int,
+ B_Algorithm *, A_SURRENDER_CTX *));
+
+int B_AlgorithmVerifyInit PROTO_LIST
+ ((B_Algorithm *, B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *));
+int B_AlgorithmVerifyUpdate PROTO_LIST
+ ((B_Algorithm *, unsigned char *, unsigned int, A_SURRENDER_CTX *));
+int B_AlgorithmVerifyFinal PROTO_LIST
+ ((B_Algorithm *, unsigned char *, unsigned int, B_Algorithm *,
+ A_SURRENDER_CTX *));
+
+int B_AlgorithmKeyAgreeInit PROTO_LIST
+ ((B_Algorithm *, B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *));
+int B_AlgorithmKeyAgreePhase1 PROTO_LIST
+ ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int,
+ B_Algorithm *, A_SURRENDER_CTX *));
+int B_AlgorithmKeyAgreePhase2 PROTO_LIST
+ ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int,
+ unsigned char *, unsigned int, A_SURRENDER_CTX *));
+
+int B_AlgorithmGenerateInit PROTO_LIST
+ ((B_Algorithm *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *));
+int B_AlgorithmGenerateKeypair PROTO_LIST
+ ((B_Algorithm *, B_Key *, B_Key *, B_Algorithm *,
+ A_SURRENDER_CTX *));
+int B_AlgorithmGenerateParameters PROTO_LIST
+ ((B_Algorithm *, B_Algorithm *, B_Algorithm *, A_SURRENDER_CTX *));
+
+#endif
diff --git a/lib/dns/sec/dnssafe/balgmeth.h b/lib/dns/sec/dnssafe/balgmeth.h
new file mode 100644
index 00000000..c73e3ad4
--- /dev/null
+++ b/lib/dns/sec/dnssafe/balgmeth.h
@@ -0,0 +1,18 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+struct B_AlgorithmInfoType;
+struct B_KeyInfoType;
+
+struct B_ALGORITHM_METHOD {
+ struct B_AlgorithmInfoType *algorithmInfoType;
+ int encryptFlag;
+ struct B_KeyInfoType *keyInfoType;
+ POINTER alga;
+};
+
diff --git a/lib/dns/sec/dnssafe/bgclrbit.c b/lib/dns/sec/dnssafe/bgclrbit.c
new file mode 100644
index 00000000..36565f41
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bgclrbit.c
@@ -0,0 +1,28 @@
+/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+
+/* BigClrbit (a, v) -- clears v-th bit of a, where v is nonnegative.
+ */
+void BigClrbit (a, v)
+UINT2 *a;
+unsigned int v;
+{
+ a[v/16] &= ~ (1 << (v % 16));
+}
+
+/* BigSetbit (a, v) -- sets v-th bit of a, where v is nonnegative.
+ */
+void BigSetbit (a, v)
+UINT2 *a;
+unsigned int v;
+{
+ a[v/16] |= (1 << (v % 16));
+}
diff --git a/lib/dns/sec/dnssafe/bgmdmpyx.c b/lib/dns/sec/dnssafe/bgmdmpyx.c
new file mode 100644
index 00000000..83a0a761
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bgmdmpyx.c
@@ -0,0 +1,26 @@
+/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+
+/* BigModMpyx (a, b, c, d, dInv, n) -- a = (b * c) mod d !! EXPRESS.
+ -- assumes a, b, c, d of length n, dInv of length n+2.
+ -- assumes dInv previously computed by BigInv.
+ */
+void BigModMpyx (a, b, c, d, dInv, n)
+UINT2 *a, *b, *c, *d, *dInv;
+unsigned int n;
+{
+ UINT2 prod[2 * MAX_RSA_MODULUS_WORDS];
+
+ BigPmpy (prod, b, c, n);
+ BigModx (a, prod, d, dInv, n);
+
+ T_memset ((POINTER)prod, 0, sizeof (prod));
+}
diff --git a/lib/dns/sec/dnssafe/bgmdsqx.c b/lib/dns/sec/dnssafe/bgmdsqx.c
new file mode 100644
index 00000000..e8f0e226
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bgmdsqx.c
@@ -0,0 +1,24 @@
+/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+
+/* BigModSqx (a, b, d, dInv, n) -- a = (b * b) mod d !! EXPRESS.
+ */
+void BigModSqx (a, b, d, dInv, n)
+UINT2 *a, *b, *d, *dInv;
+unsigned int n;
+{
+ UINT2 prod[2 * MAX_RSA_MODULUS_WORDS];
+
+ BigPsq (prod, b, n);
+ BigModx (a, prod, d, dInv, n);
+
+ T_memset ((POINTER)prod, 0, sizeof (prod));
+}
diff --git a/lib/dns/sec/dnssafe/bgmodexp.c b/lib/dns/sec/dnssafe/bgmodexp.c
new file mode 100644
index 00000000..1f1a65f4
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bgmodexp.c
@@ -0,0 +1,132 @@
+/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+#include "surrendr.h"
+
+/* BigModExp (a, b, c, d, n): a = b**c (mod d)
+ Assumes a, b, c, d of length n.
+ Returns 0, AE_CANCEL.
+ */
+int BigModExp (a, b, c, d, n, surrenderContext)
+UINT2 *a, *b, *c, *d;
+unsigned int n;
+A_SURRENDER_CTX *surrenderContext;
+{
+ struct BigModExpFrame {
+ UINT2 dInv[MAX_RSA_MODULUS_WORDS + 2], result[MAX_RSA_MODULUS_WORDS],
+ tab[16][MAX_RSA_MODULUS_WORDS];
+ } *frame = (struct BigModExpFrame *)NULL_PTR;
+#if !USE_ALLOCED_FRAME
+ struct BigModExpFrame stackFrame;
+#endif
+ int i, didAMultiply, status;
+ unsigned int cLen, w, setup[64], power, mask;
+
+ /* Initialize.
+ */
+ do {
+#if USE_ALLOCED_FRAME
+ if ((frame = (struct BigModExpFrame *)T_malloc (sizeof (*frame)))
+ == (struct BigModExpFrame *)NULL_PTR) {
+ status = AE_ALLOC;
+ break;
+ }
+#else
+ /* Just use the buffers allocated on the stack. */
+ frame = &stackFrame;
+#endif
+
+ /* precompute inverse of d to enable express mod-outs */
+ BigInv (frame->dInv, d, n);
+ if ((status = CheckSurrender (surrenderContext)) != 0)
+ break;
+
+ /* precompute small (size 2**w) table of powers of b */
+ cLen = BigLen (c, n);
+ if (cLen < 4)
+ w = 1;
+ else if (cLen < 16)
+ w = 2;
+ else if (cLen < 64)
+ w = 3;
+ else
+ w = 4;
+
+ /* zeroth power is one */
+ BigConst (frame->tab[0], 1, n);
+
+ /* first power is b */
+ BigCopy (frame->tab[1], b, n);
+ setup[0] = 1;
+ setup[1] = 1;
+ for (i = 2; i < 64; i++)
+ setup[i] = 0;
+
+ /* Loop over elements of exponent c in appropriate radix.
+ */
+ power = 0;
+ didAMultiply = 0;
+ mask = 1 << ((cLen) % 16);
+ for (i = cLen; i >= 0; i--) {
+ if (didAMultiply) {
+ BigModSqx (frame->result, frame->result, d, frame->dInv, n);
+ if ((status = CheckSurrender (surrenderContext)) != 0)
+ break;
+ }
+
+ power = power << 1;
+ if (setup[power] == 0) {
+ BigModSqx (frame->tab[power], frame->tab[power/2], d, frame->dInv, n);
+ if ((status = CheckSurrender (surrenderContext)) != 0)
+ break;
+ setup[power] = 1;
+ }
+ if (c[i/16] & mask)
+ power = power + 1;
+ if (mask == 1)
+ mask = 0x8000;
+ else
+ mask = (mask >> 1) & 0x7FFF;
+ if (setup[power] == 0) {
+ BigModMpyx
+ (frame->tab[power], frame->tab[power-1], b, d, frame->dInv, n);
+ if ((status = CheckSurrender (surrenderContext)) != 0)
+ break;
+ setup[power] = 1;
+ }
+ if ((i == 0) || (power >= (unsigned int)(1 << (w-1)))) {
+ if (didAMultiply) {
+ BigModMpyx
+ (frame->result, frame->result, frame->tab[power], d, frame->dInv,
+ n);
+ if ((status = CheckSurrender (surrenderContext)) != 0)
+ break;
+ }
+ else
+ BigCopy (frame->result, frame->tab[power], n);
+
+ power = 0;
+ didAMultiply = 1;
+ }
+ }
+ if (status)
+ break;
+
+ BigCopy (a, frame->result, n);
+ } while (0);
+
+ if (frame != (struct BigModExpFrame *)NULL_PTR) {
+ T_memset ((POINTER)frame, 0, sizeof (*frame));
+#if USE_ALLOCED_FRAME
+ T_free ((POINTER)frame);
+#endif
+ }
+ return (status);
+}
diff --git a/lib/dns/sec/dnssafe/bgpegcd.c b/lib/dns/sec/dnssafe/bgpegcd.c
new file mode 100644
index 00000000..2201b7e9
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bgpegcd.c
@@ -0,0 +1,78 @@
+/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+
+/* BigPegcd
+ input
+ u, v bignums
+ k int size of u, v regs
+ restriction u, v positive
+ output
+ u3=GCD (u, v) (pos)
+ u1=inv (u)modv (pos)
+ u2=inv (v)modu (pos)
+ if GCD (u, v)!=1 then u1, u2 st
+ u3=u * u1mod (v) & u3=v * u2mod (u)
+ (see KNUTH vol 2)
+ */
+void BigPegcd (u3, u1, u2, u, v, k)
+UINT2 *u3, *u2, *u1, *u, *v;
+unsigned int k;
+{
+ UINT2 v1[2 * MAX_RSA_PRIME_WORDS], v2[2 * MAX_RSA_PRIME_WORDS],
+ v3[2 * MAX_RSA_PRIME_WORDS], q[2 * MAX_RSA_PRIME_WORDS],
+ r[2 * MAX_RSA_PRIME_WORDS], t1[2 * MAX_RSA_PRIME_WORDS],
+ t2[2 * MAX_RSA_PRIME_WORDS], t3[2 * MAX_RSA_PRIME_WORDS];
+
+ BigConst (u1, 1, k);
+ BigConst (u2, 0, k);
+ BigCopy (u3, u, k);
+ BigConst (v1, 0, k);
+ BigConst (v2, 1, k);
+ BigCopy (v3, v, k);
+
+ /* Begin calc.
+ */
+ do {
+ if (BigSign (v3, k) == 0)
+ break;
+ BigPdiv (q, r, u3, v3, k, k);
+ BigPmpyl (t1, v1, q, k);
+ BigPmpyl (t2, v2, q, k);
+ BigPmpyl (t3, v3, q, k);
+ BigSub (t1, u1, t1, k);
+ BigSub (t2, u2, t2, k);
+ BigSub (t3, u3, t3, k);
+
+ BigCopy (u1, v1, k);
+ BigCopy (u2, v2, k);
+ BigCopy (u3, v3, k);
+ BigCopy (v1, t1, k);
+ BigCopy (v2, t2, k);
+ BigCopy (v3, t3, k);
+ } while (1);
+
+ if (BigSign (u1, k) == -1)
+ /* make positive */
+ BigAdd (u1, u1, v, k);
+
+ if (BigSign (u2, k) == -1)
+ /* make positive */
+ BigAdd (u2, u2, u, k);
+
+ T_memset ((POINTER)v1, 0, sizeof (v1));
+ T_memset ((POINTER)v2, 0, sizeof (v2));
+ T_memset ((POINTER)v3, 0, sizeof (v3));
+ T_memset ((POINTER)q, 0, sizeof (q));
+ T_memset ((POINTER)r, 0, sizeof (r));
+ T_memset ((POINTER)t1, 0, sizeof (t1));
+ T_memset ((POINTER)t2, 0, sizeof (t2));
+ T_memset ((POINTER)t3, 0, sizeof (t3));
+}
diff --git a/lib/dns/sec/dnssafe/big2exp.c b/lib/dns/sec/dnssafe/big2exp.c
new file mode 100644
index 00000000..85026db2
--- /dev/null
+++ b/lib/dns/sec/dnssafe/big2exp.c
@@ -0,0 +1,25 @@
+/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+
+/* Big2Exp (a, v, n) -- a = 2**v, where v is nonnegative int.
+ Sets a to be 2**v.
+ */
+void Big2Exp (a, v, n)
+UINT2 *a;
+unsigned v;
+unsigned int n;
+{
+ register unsigned int i;
+
+ for (i = 0; i < n; i++)
+ a[i] = 0;
+ a[v/16] = 1 << (v % 16);
+}
diff --git a/lib/dns/sec/dnssafe/bigabs.c b/lib/dns/sec/dnssafe/bigabs.c
new file mode 100644
index 00000000..8b4bcb70
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bigabs.c
@@ -0,0 +1,22 @@
+/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+
+/* BigAbs (a, b, n) -- a = ABS (b).
+ */
+void BigAbs (a, b, n)
+UINT2 *a, *b;
+unsigned int n;
+{
+ if (BigSign (b, n) >= 0)
+ BigCopy (a, b, n);
+ else
+ BigNeg (a, b, n);
+}
diff --git a/lib/dns/sec/dnssafe/bigacc.c b/lib/dns/sec/dnssafe/bigacc.c
new file mode 100644
index 00000000..c4f09749
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bigacc.c
@@ -0,0 +1,34 @@
+/* Copyright (C) RSA Data Security, Inc. created 1987, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+
+/* Returns carry: vector a = b * vector c.
+ */
+UINT2 BigAcc (a, b, c, n)
+UINT2 *a;
+unsigned int b;
+UINT2 *c;
+unsigned int n;
+{
+ UINT4 bTemp, result = (UINT4)0;
+ register unsigned int i;
+
+ if (!b)
+ return (0);
+
+ bTemp = b;
+ for (i = 0; i < n; i++) {
+ result += bTemp * ((UINT4) c[i]);
+ result += ((UINT4) a[i]);
+ a[i] = (UINT2) result;
+ result >>= 16;
+ }
+ return ((UINT2)result);
+}
diff --git a/lib/dns/sec/dnssafe/bigarith.c b/lib/dns/sec/dnssafe/bigarith.c
new file mode 100644
index 00000000..64af71c6
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bigarith.c
@@ -0,0 +1,138 @@
+/* Copyright (C) RSA Data Security, Inc. created 1987, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+
+void BigZero (a, n)
+UINT2 *a;
+unsigned int n;
+{
+ register unsigned int i;
+
+ for (i = 0; i < n; i++)
+ a[i] = 0;
+}
+
+void BigAdd (a, b, c, n)
+UINT2 *a, *b, *c;
+unsigned int n;
+{
+ UINT4 result = (UINT4)0;
+ register unsigned int i;
+
+ for (i = 0; i < n; i++) {
+ result += (UINT4) b[i];
+ result += (UINT4) c[i];
+ a[i] = (UINT2) result;
+ result >>= 16;
+ }
+}
+
+void BigSub (a, b, c, n)
+UINT2 *a, *b, *c;
+unsigned int n;
+{
+ UINT4 result = (UINT4)1; /* carry bit for negation of c */
+ register unsigned int i;
+
+ for (i = 0; i < n; i++) {
+ result += (UINT4) b[i];
+ result += (((UINT4) ~c[i]) & 0x0000FFFFL);
+ a[i] = (UINT2)result;
+ result >>= 16;
+ }
+}
+
+void BigNeg (a, b, n)
+UINT2 *a, *b;
+unsigned int n;
+{
+ register unsigned int i;
+ unsigned int carry = 1;
+
+ for (i = 0; i < n-1; i++) {
+ a[i] = ~b[i] + carry;
+ if (a[i])
+ carry = 0;
+ }
+
+ a[i] = ~b[i] + carry;
+}
+
+void BigInc (a, n)
+UINT2 *a;
+unsigned int n;
+{
+ register unsigned int i;
+ unsigned int carry = 1; /* carry to start */
+
+ for (i = 0; i < n-1 && carry; i++) {
+ a[i]++;
+ if (a[i])
+ carry = 0;
+ }
+
+ if (carry)
+ a[i]++;
+}
+
+void BigDec (a, n)
+UINT2 *a;
+unsigned int n;
+{
+ register unsigned int i;
+ unsigned int borrow = 1; /* borrow to start */
+
+ for (i = 0; i < n-1 && borrow; i++) {
+ a[i]--;
+ if (a[i] != 0xFFFF)
+ borrow = 0;
+ }
+
+ if (borrow)
+ a[i]--;
+}
+
+int BigSign (a, n)
+UINT2 *a;
+unsigned int n;
+{
+ register int i;
+
+ if (a[n-1] & 0x8000)
+ return (-1);
+ for (i = n-1; i >= 0; i--)
+ if (a[i])
+ return (1);
+ return (0);
+}
+
+void BigCopy (a, b, n)
+UINT2 *a, *b;
+unsigned int n;
+{
+ register unsigned int i;
+
+ for (i = 0; i < n; i++)
+ a[i] = b[i];
+}
+
+/* Assumes a is nonnegative.
+ */
+unsigned int BigLenw (a, n)
+UINT2 *a;
+unsigned int n;
+{
+ register int i;
+
+ for (i = n-1; i >= 0; i--)
+ if (a[i])
+ return (i+1);
+ return (0);
+}
diff --git a/lib/dns/sec/dnssafe/bigcmp.c b/lib/dns/sec/dnssafe/bigcmp.c
new file mode 100644
index 00000000..953be154
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bigcmp.c
@@ -0,0 +1,34 @@
+/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+
+/* Comparison operator.
+ BigCmp (a, b, n) -- returns sign of a-b.
+ */
+int BigCmp (a, b, n)
+UINT2 *a, *b;
+unsigned int n;
+{
+ register int i;
+ int aSign = BigSign (a, n), bSign = BigSign (b, n);
+
+ if (aSign > bSign)
+ return (1);
+ if (aSign < bSign)
+ return (-1);
+
+ for (i = n-1; i >= 0 && a[i] == b[i]; i--);
+
+ if (i == -1)
+ return (0);
+ if (a[i] > b[i])
+ return (1);
+ return (-1);
+}
diff --git a/lib/dns/sec/dnssafe/bigconst.c b/lib/dns/sec/dnssafe/bigconst.c
new file mode 100644
index 00000000..6bc50009
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bigconst.c
@@ -0,0 +1,26 @@
+/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+
+/* BigConst (a, v, n) -- a = v, where v is an int. Initialize bignum a to
+ value v.
+ */
+void BigConst (a, v, n)
+UINT2 *a;
+unsigned int v;
+unsigned int n;
+{
+ UINT2 signWord = (((UINT2)v & 0x8000) ? ~0 : 0);
+ register unsigned int i;
+
+ a[0] = (UINT2)v;
+ for (i = 1; i < n; i++)
+ a[i] = signWord;
+}
diff --git a/lib/dns/sec/dnssafe/biginv.c b/lib/dns/sec/dnssafe/biginv.c
new file mode 100644
index 00000000..7c69fd9f
--- /dev/null
+++ b/lib/dns/sec/dnssafe/biginv.c
@@ -0,0 +1,103 @@
+/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+
+static unsigned int Log2 PROTO_LIST ((unsigned int));
+
+/* BigInv (a, b, n) -- compute a as an "inverse" to b, suitable for
+ modding out integers which are < b**2.
+ -- assumes a has n+2 words, b has n words.
+ -- assumes b is a positive integer.
+ */
+void BigInv (a, b, n)
+UINT2 *a, *b;
+unsigned int n;
+{
+ UINT2 p[2 * (MAX_RSA_MODULUS_WORDS + 2)],
+ q[2 * (MAX_RSA_MODULUS_WORDS + 3)], t1[MAX_RSA_MODULUS_WORDS + 3];
+ register int i;
+ unsigned int bl, u, uw, sw;
+
+ /* Do initializations.
+ */
+ /* 2** (bl-1) <= b < 2 ** bl */
+ bl = BigLen (b, n);
+ u = BigU (2 * bl);
+
+ /* uw and sw are in words */
+ uw = u/16;
+ sw = (bl - 2) / 16;
+
+ /* since a = floor ((2**u)/b), 2**(u-bl) < a <= 2**(u-bl+1) */
+
+ /* Initialize a to 1+2**(u-bl) -- we will converge from below.
+ */
+ Big2Exp (a, u - bl, n + 2);
+ BigInc (a, n + 2);
+
+ /* Copy b to local register.
+ */
+ BigZero (t1, n + 3);
+ BigCopy (t1, b, n);
+
+ /* Convergence is quadratic, so iterate log (len (a)) times.
+ */
+ for (i = 1 + Log2 (u - bl + 1); i > 0; i--) {
+ /* use fast squaring routine to compute p = a**2
+ 2**(2 * (u-bl)) < p <= 2**(2 * (u-bl+1)) */
+ BigPsq (p, a, n + 2);
+
+ /* compute q = b * floor (p/ (2**s))
+ 2**(2 * (u-bl)-s+bl-1) <= q <= 2**(2 * (u-bl+1)-s+bl
+ 2**(2 * u-bl-s-1) <= q <= 2**(2 * u-bl-s+2) */
+ BigPmpy (q, t1, &p[sw], n + 3);
+
+ /* double a
+ 2**(u-bl+1) < a <= 2**(u-bl+2) */
+ BigAdd (a, a, a, n + 2);
+ /* a = a - floor (q/(2**(u-s)))
+ 2**(u-bl) < a <= 2**(u-bl+1) + epsilon */
+ BigSub (a, a, &q[uw-sw], n + 2);
+ }
+
+ /* now we are guaranteed that a is not too small */
+ BigInc (a, n + 2);
+
+ do {
+ BigPmpy (p, a, t1, n + 2);
+ /* makes comparison to 2**u easier */
+ BigDec (p, 2 * (n + 2));
+
+ /* a is desired result */
+ if (BigLen (p, 2 * (n + 2)) <= u)
+ break;
+
+ /* a was too big, reduce and try again */
+ BigDec (a, n + 2);
+ } while (1);
+
+ T_memset ((POINTER)p, 0, sizeof (p));
+ T_memset ((POINTER)q, 0, sizeof (q));
+ T_memset ((POINTER)t1, 0, sizeof (t1));
+}
+
+/* Log2 (x) -- ceiling of log base 2 of x > 0. Auxiliary function.
+ */
+static unsigned int Log2 (x)
+unsigned int x;
+{
+ unsigned int i;
+
+ x = x - 1;
+ /* now Log2 is equal to len in bits of x */
+ for (i = 0; x > 0; i++, x >>= 1);
+
+ return (i);
+}
diff --git a/lib/dns/sec/dnssafe/biglen.c b/lib/dns/sec/dnssafe/biglen.c
new file mode 100644
index 00000000..6b5acb9a
--- /dev/null
+++ b/lib/dns/sec/dnssafe/biglen.c
@@ -0,0 +1,28 @@
+/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+
+unsigned int BigLen (a, n)
+UINT2 *a;
+unsigned int n;
+{
+ UINT2 signWord = ((a[n-1] & 0x8000) ? ~0 : 0);
+ int i, j;
+ unsigned int k;
+
+ for (i = n-1; i >= 0 && a[i] == signWord; i--);
+ if (i == -1)
+ return (1); /* len of 0 or -1 */
+
+ for (j = 16, k = 0x8000;
+ j >= 0 && 0 == (k & (signWord ^ a[i]));
+ j--, k >>= 1);
+ return (16 * i + j);
+}
diff --git a/lib/dns/sec/dnssafe/bigmath.h b/lib/dns/sec/dnssafe/bigmath.h
new file mode 100644
index 00000000..351b55b2
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bigmath.h
@@ -0,0 +1,71 @@
+/* Copyright (C) RSA Data Security, Inc. created 1992, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _BIGMATH_H_
+#define _BIGMATH_H_ 1
+
+#include "algae.h"
+#include "bigmaxes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void Big2Exp PROTO_LIST ((UINT2 *, unsigned int, unsigned int));
+void BigAbs PROTO_LIST ((UINT2 *, UINT2 *, unsigned int));
+UINT2 BigAcc PROTO_LIST ((UINT2 *, unsigned int, UINT2 *, unsigned int));
+void BigZero PROTO_LIST ((UINT2 *, unsigned int));
+void BigAdd PROTO_LIST ((UINT2 *, UINT2 *, UINT2 *, unsigned int));
+void BigSub PROTO_LIST ((UINT2 *, UINT2 *, UINT2 *, unsigned int));
+void BigNeg PROTO_LIST ((UINT2 *, UINT2 *, unsigned int));
+void BigInc PROTO_LIST ((UINT2 *, unsigned int));
+void BigDec PROTO_LIST ((UINT2 *, unsigned int));
+int BigSign PROTO_LIST ((UINT2 *, unsigned int));
+void BigCopy PROTO_LIST ((UINT2 *, UINT2 *, unsigned int));
+unsigned int BigLenw PROTO_LIST ((UINT2 *, unsigned int));
+void BigClrbit PROTO_LIST ((UINT2 *, unsigned int));
+void BigSetbit PROTO_LIST ((UINT2 *, unsigned int));
+int BigCmp PROTO_LIST ((UINT2 *, UINT2 *, unsigned int));
+void BigConst PROTO_LIST ((UINT2 *, unsigned int, unsigned int));
+void BigInv PROTO_LIST ((UINT2 *, UINT2 *, unsigned int));
+unsigned int BigLen PROTO_LIST ((UINT2 *, unsigned int));
+void BigModMpyx PROTO_LIST
+ ((UINT2 *, UINT2 *, UINT2 *, UINT2 *, UINT2 *, unsigned int));
+void BigModSqx PROTO_LIST
+ ((UINT2 *, UINT2 *, UINT2 *, UINT2 *, unsigned int));
+int BigModExp PROTO_LIST
+ ((UINT2 *, UINT2 *, UINT2 *, UINT2 *, unsigned int, A_SURRENDER_CTX *));
+void BigModx PROTO_LIST
+ ((UINT2 *, UINT2 *, UINT2 *, UINT2 *, unsigned int));
+void BigMpy PROTO_LIST ((UINT2 *, UINT2 *, UINT2 *, unsigned int));
+void BigPdiv PROTO_LIST
+ ((UINT2 *, UINT2 *, UINT2 *, UINT2 *, unsigned int , unsigned int));
+void BigPegcd PROTO_LIST
+ ((UINT2 *, UINT2 *, UINT2 *, UINT2 *, UINT2 *, unsigned int));
+void BigPmpy PROTO_LIST ((UINT2 *, UINT2 *, UINT2 *, unsigned int));
+void BigPmpyh PROTO_LIST
+ ((UINT2 *, UINT2 *, UINT2 *, unsigned int, unsigned int));
+void BigPmpyl PROTO_LIST ((UINT2 *, UINT2 *, UINT2 *, unsigned int));
+void BigPsq PROTO_LIST ((UINT2 *, UINT2 *, unsigned int));
+void BigQrx PROTO_LIST
+ ((UINT2 *, UINT2 *, UINT2 *, UINT2 *, UINT2 *, unsigned int));
+UINT2 BigSmod PROTO_LIST ((UINT2 *, unsigned int, unsigned int));
+int BigToCanonical PROTO_LIST
+ ((unsigned char *, unsigned int, UINT2 *, unsigned int));
+unsigned int BigU PROTO_LIST ((unsigned int));
+int BigUnexp PROTO_LIST
+ ((UINT2 *, UINT2 *, UINT2 *, UINT2 *, UINT2 *, UINT2 *, UINT2 *,
+ unsigned int, A_SURRENDER_CTX *));
+int CanonicalToBig PROTO_LIST
+ ((UINT2 *, unsigned int, unsigned char *, unsigned int));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/dns/sec/dnssafe/bigmaxes.h b/lib/dns/sec/dnssafe/bigmaxes.h
new file mode 100644
index 00000000..49992f67
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bigmaxes.h
@@ -0,0 +1,47 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _BIGMAXES_H_
+#define _BIGMAXES_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAX_RSA_MODULUS_BITS 1024
+
+#define BITS_TO_LEN(modulusBits) (((modulusBits) + 7) / 8)
+#define RSA_PRIME_BITS(modulusBits) (((modulusBits) + 1) / 2)
+#define RSA_PRIME_LEN(modulusBits) ((RSA_PRIME_BITS (modulusBits) + 7) / 8)
+#define BITS_TO_WORDS(bits) ((bits >> 4) + 1)
+#define LEN_TO_WORDS(len) ((len >> 1) + 1)
+
+/* MAX_RSA_PRIME_BITS -- length in bits of the maximum allowed RSA prime
+ MAX_RSA_MODULUS_LEN -- length in bytes of the maximum allowed RSA modulus,
+ in canonical format (no sign bit)
+ MAX_RSA_PRIME_LEN -- length in bytes of the maximum allowed RSA prime, in
+ canonical format (no sign bit)
+ */
+#define MAX_RSA_PRIME_BITS RSA_PRIME_BITS (MAX_RSA_MODULUS_BITS)
+#define MAX_RSA_PRIME_LEN RSA_PRIME_LEN (MAX_RSA_MODULUS_BITS)
+#define MAX_RSA_MODULUS_LEN BITS_TO_LEN (MAX_RSA_MODULUS_BITS)
+
+/* MAX_RSA_MODULUS_WORDS -- length in 16-bit words of the maximum allowed RSA
+ modulus, in bignum format (including sign bit)
+ MAX_RSA_PRIME_WORDS -- length in 16-bit words of the maximum allowed RSA
+ prime, in bignum format (including sign bit)
+ */
+
+#define MAX_RSA_MODULUS_WORDS BITS_TO_WORDS (MAX_RSA_MODULUS_BITS)
+#define MAX_RSA_PRIME_WORDS BITS_TO_WORDS (MAX_RSA_PRIME_BITS)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/dns/sec/dnssafe/bigmodx.c b/lib/dns/sec/dnssafe/bigmodx.c
new file mode 100644
index 00000000..3559962a
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bigmodx.c
@@ -0,0 +1,25 @@
+/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+
+/* BigModx (a, b, c, cInv, n) -- compute a as (b mod c).
+ -- assumes a and c of length n, cInv of length n + 2, b of length 2n.
+ -- assumes cInv computed with BigInv, and that b < c**2.
+ */
+void BigModx (a, b, c, cInv, n)
+UINT2 *a, *b, *c, *cInv;
+unsigned int n;
+{
+ UINT2 q[MAX_RSA_MODULUS_WORDS];
+
+ BigQrx (q, a, b, c, cInv, n);
+
+ T_memset ((POINTER)q, 0, sizeof (q));
+}
diff --git a/lib/dns/sec/dnssafe/bigmpy.c b/lib/dns/sec/dnssafe/bigmpy.c
new file mode 100644
index 00000000..9a17b06a
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bigmpy.c
@@ -0,0 +1,36 @@
+/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+
+/* BigMpy (a, b, c, n) -- a = b * c
+ -- assumes b and c have n words, a has 2*n words
+ -- inputs may be positive or negative.
+ */
+void BigMpy (a, b, c, n)
+UINT2 *a, *b, *c;
+unsigned int n;
+{
+ UINT2 prod[2 * MAX_RSA_PRIME_WORDS], absb[MAX_RSA_PRIME_WORDS],
+ absc[MAX_RSA_PRIME_WORDS];
+ int bSign = BigSign (b, n), cSign = BigSign (c, n);
+
+ BigAbs (absb, b, n);
+ BigAbs (absc, c, n);
+ BigPmpy (prod, absb, absc, n);
+
+ if (bSign * cSign >= 0)
+ BigCopy (a, prod, 2 * n);
+ else
+ BigNeg (a, prod, 2 * n);
+
+ T_memset ((POINTER)prod, 0, sizeof (prod));
+ T_memset ((POINTER)absb, 0, sizeof (absb));
+ T_memset ((POINTER)absc, 0, sizeof (absc));
+}
diff --git a/lib/dns/sec/dnssafe/bigpdiv.c b/lib/dns/sec/dnssafe/bigpdiv.c
new file mode 100644
index 00000000..23c3f8bc
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bigpdiv.c
@@ -0,0 +1,159 @@
+/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+
+/* BigPdiv POSITIVE DIVIDE
+ uu=vv * qi+ri
+ uu in reg of ll cells
+ vv in reg of kk cells
+ qi assumed to be ll cells
+ ri assumed to be kk cells
+ restriction uu>=0, vv>0
+
+ input uu in reg of ll cells
+ input vv in reg of kk cells
+ output qi assumed to be ll cells
+ output ri assumed to be kk cells
+ restriction uu>=0, vv>0
+ uu=vv * qi+ri
+ */
+#define UJN (u[(j+n)/2] & mk[(j+n)%2])
+#define VN (v[n/2] & mk[n%2])
+#define UT (u[t/2] & mk[t%2])
+void BigPdiv (qi, ri, uu, vv, ll, kk)
+UINT2 *qi, *ri, *uu, *vv;
+unsigned int ll, kk;
+{
+ UINT2 u[2 * MAX_RSA_PRIME_WORDS + 2], us[2 * MAX_RSA_PRIME_WORDS + 2],
+ v[2 * MAX_RSA_PRIME_WORDS + 2], vs[2 * MAX_RSA_PRIME_WORDS + 2],
+ q[2 * MAX_RSA_PRIME_WORDS + 2], r[2 * MAX_RSA_PRIME_WORDS + 2],
+ t1[2 * MAX_RSA_PRIME_WORDS + 2], t2[2 * MAX_RSA_PRIME_WORDS + 2],
+ t3[2 * MAX_RSA_PRIME_WORDS + 2], mk[2];
+ int j, l, n, m, t, x;
+ unsigned int a, b, c, d, e, vh, qq;
+
+ if (ll >= kk)
+ l = ll + 2;
+ else
+ l = kk + 2;
+
+ mk[0] = 0x00FF;
+ mk[1] = 0xFF00;
+ b = 0x0100;
+
+ BigConst (u, 0, l);
+ BigConst (v, 0, l);
+ BigCopy (u, uu, ll);
+ BigCopy (us, u, l);
+ BigCopy (v, vv, kk);
+ BigCopy (vs, v, l);
+
+ /* zero q */
+ BigConst (q, 0, l);
+
+ /* Calculate len of v=n.
+ */
+ for (n = (2 * l) - 1; n >= 0; n--) {
+ if (VN == 0)
+ continue;
+ break;
+ }
+
+ /* Normalize.
+ */
+ a = VN;
+ if (n % 2 == 1)
+ a = a >> 8;
+ d = b / (a+1);
+ BigConst (t1, d, l);
+ BigPmpyl (t2, t1, v, l);
+ BigCopy (v, t2, l);
+
+ /* vh=high order digit of normalized v */
+ vh = VN;
+ if (n % 2 == 1)
+ vh = vh >> 8;
+ BigPmpyl (t2, t1, u, l);
+ BigCopy (u, t2, l);
+
+ /* Calculate len of u=t.
+ */
+ for (t = (2 * l)-1; t >= 0; t--) {
+ if (UT == 0)
+ continue;
+ break;
+ }
+
+ /* calc t = n + m */
+ m = t - n;
+
+ /* Divide u by v.
+ */
+ for (j = m + 1 + n; j > n; j--) {
+ if (j % 2 == 1)
+ c = u[j / 2];
+ else {
+ a = u[j/2];
+ a = a << 8;
+ e = u[(j - 1) / 2];
+ e = e >> 8;
+ c = a + e;
+ }
+ a = c >> 8;
+ if (vh == a)
+ qq = b - 1;
+ else
+ qq = c / vh;
+
+ BigConst (t1, qq, l);
+ BigPmpyl (t2, v, t1, l);
+ Big2Exp (t3, (j - 1 - n) * 8, l);
+ BigPmpyl (t1, t3, t2, l);
+ BigSub (t2, u, t1, l);
+
+ /* Adjust q.
+ */
+ for (x = 0; ; qq --, x ++) {
+ if (BigSign (t2, l) != -1)
+ break;
+ BigPmpyl (t1, t3, v, l);
+ BigAdd (t2, t2, t1, l);
+ }
+
+ BigCopy (u, t2, l);
+ BigConst (t3, qq, l);
+ Big2Exp (t2, 8, l);
+ BigPmpyl (t1, q, t2, l);
+ BigAdd (q, t3, t1, l);
+ }
+
+ /* Check result.
+ */
+
+ BigPmpyl (t1, vs, q, l);
+ /* t2 has remainder */
+ BigSub (t2, us, t1, l);
+
+ BigSub (t3, vs, t2, l);
+
+ /* transfer results to input registers */
+ BigCopy (qi, q, ll);
+ BigCopy (ri, t2, kk);
+
+ T_memset ((POINTER)u, 0, sizeof (u));
+ T_memset ((POINTER)us, 0, sizeof (us));
+ T_memset ((POINTER)v, 0, sizeof (v));
+ T_memset ((POINTER)vs, 0, sizeof (vs));
+ T_memset ((POINTER)q, 0, sizeof (q));
+ T_memset ((POINTER)r, 0, sizeof (r));
+ T_memset ((POINTER)t1, 0, sizeof (t1));
+ T_memset ((POINTER)t2, 0, sizeof (t2));
+ T_memset ((POINTER)t3, 0, sizeof (t3));
+}
diff --git a/lib/dns/sec/dnssafe/bigpmpy.c b/lib/dns/sec/dnssafe/bigpmpy.c
new file mode 100644
index 00000000..8ef3b4cd
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bigpmpy.c
@@ -0,0 +1,25 @@
+/* Copyright (C) RSA Data Security, Inc. created 1987, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+
+/* a = b * c.
+ */
+void BigPmpy (a, b, c, n)
+UINT2 *a, *b, *c;
+unsigned int n;
+{
+ register unsigned int i;
+ unsigned int cLen;
+
+ BigZero (a, 2*n);
+ cLen = BigLenw (c, n);
+ for (i = 0; i < n; i++)
+ a[cLen+i] = BigAcc (&a[i], (unsigned int)b[i], c, cLen);
+}
diff --git a/lib/dns/sec/dnssafe/bigpmpyh.c b/lib/dns/sec/dnssafe/bigpmpyh.c
new file mode 100644
index 00000000..20bb7312
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bigpmpyh.c
@@ -0,0 +1,30 @@
+/* Copyright (C) RSA Data Security, Inc. created 1987, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+
+/* Returns high order t bytes of result.
+ */
+void BigPmpyh (a, b, c, t, n)
+UINT2 *a, *b, *c;
+unsigned int t, n;
+{
+ register unsigned int i;
+ unsigned int iStart, cLen, j;
+
+ BigZero (a, 2*n);
+ cLen = BigLenw (c, n);
+ iStart = (t >= n-1) ? t - (n-1) : 0;
+
+ for (i = iStart; i < n; i++) {
+ j = (t >= i) ? t - i : 0;
+ a[cLen+i] = BigAcc
+ (&a[i+j], (unsigned int)b[i], &c[j], (cLen >= j) ? cLen-j : 0);
+ }
+}
diff --git a/lib/dns/sec/dnssafe/bigpmpyl.c b/lib/dns/sec/dnssafe/bigpmpyl.c
new file mode 100644
index 00000000..a05dfc20
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bigpmpyl.c
@@ -0,0 +1,30 @@
+/* Copyright (C) RSA Data Security, Inc. created 1987, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+
+/* Single precision multiply, a is same len as b and c.
+ Returns low order n bytes of result.
+ */
+void BigPmpyl (a, b, c, n)
+UINT2 *a, *b, *c;
+unsigned int n;
+{
+ register unsigned int i;
+ unsigned int cLen;
+
+ BigZero (a, n);
+ cLen = BigLenw (c, n);
+ for (i = 0; i < n; i++) {
+ if (cLen < n-i)
+ a[cLen+i] = BigAcc (&a[i], (unsigned int)b[i], c, cLen);
+ else
+ BigAcc (&a[i], (unsigned int)b[i], c, n-i);
+ }
+}
diff --git a/lib/dns/sec/dnssafe/bigpsq.c b/lib/dns/sec/dnssafe/bigpsq.c
new file mode 100644
index 00000000..87de1ab2
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bigpsq.c
@@ -0,0 +1,42 @@
+/* Copyright (C) RSA Data Security, Inc. created 1987, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+
+/* Similar to BigPmpy (a, b, b, n) but faster.
+ */
+void BigPsq (a, b, n)
+UINT2 *a, *b;
+unsigned int n;
+{
+ UINT4 result = (UINT4)0;
+ register unsigned int i;
+ unsigned int bLen;
+
+ BigZero (a, 2*n);
+ bLen = BigLenw (b, n);
+ if (!bLen)
+ return;
+
+ for (i = 0; i < bLen-1; i++)
+ a[bLen+i] = BigAcc (&a[2*i+1], (unsigned int)b[i], &b[i+1], bLen-i-1);
+ BigAdd (a, a, a, 2*n);
+
+ /* add in trace b[i] * b[i] */
+ for (i = 0; i < bLen; i++) {
+ result += ((UINT4)b[i]) * ((UINT4)b[i]);
+ result += (UINT4)a[2*i];
+ a[2*i] = (UINT2)result;
+ result >>= 16;
+ result += (UINT4)a[2*i+1];
+ a[2*i+1] = (UINT2)result;
+ result >>= 16;
+ }
+ a[2*i] = (UINT2)result;
+}
diff --git a/lib/dns/sec/dnssafe/bigqrx.c b/lib/dns/sec/dnssafe/bigqrx.c
new file mode 100644
index 00000000..5bce01e8
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bigqrx.c
@@ -0,0 +1,85 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+
+
+/* BigQrx (q, r, b, c, cInv, n) -- compute quotient and remainder fast.
+ -- computes q and r s.t. b = q * c + r with 0 <= r < c.
+ -- assumes b and c are positive integers.
+ -- assumes q, r, c have n words, cInv has n+2 words, b has 2*n words.
+ -- assumes cInv previously computed with BigInv.
+ */
+void BigQrx (q, r, b, c, cInv, n)
+UINT2 *q, *r, *b, *c, *cInv;
+unsigned int n;
+{
+ UINT2 qc[2 * (MAX_RSA_MODULUS_WORDS + 2)], /* current product of q and c */
+ qsc[2 * (MAX_RSA_MODULUS_WORDS + 2)], /* temporary q scaled by 2**(u-s) */
+ t1[2 * MAX_RSA_MODULUS_WORDS + 2];
+ int uwsw3;
+ register unsigned int i;
+ unsigned int u, uw, cl, sw;
+
+ /* 2**(cl-1) <= c < 2**cl
+ 2**(u-cl) <= cInv <= 2**(u-cl+1) */
+ cl = BigLen (c, n);
+
+ /* u is in bits, uw is in words */
+ u = BigU (2 * cl);
+ uw = u/16;
+
+ /* sw is in words, s is is bits */
+ sw = (cl - 2) / 16;
+
+ uwsw3 = uw - sw - 3;
+
+ if (uwsw3 < 0)
+ uwsw3 = 0;
+
+ /* Copy b to local register.
+ */
+ BigZero (t1, 2 * n + 2);
+ BigCopy (t1, b, 2 * n);
+
+ /* Compute qsc = cInv * floor (b/ (2**s)).
+ qsc an approximation to (b/c) * (2**(u-s))
+ 2**((u-cl)+ (bl-1-s)) <= qsc 2**((u-cl+1)+ (bl-s))
+ 2**(u-cl+bl-s-1) <= qsc <= 2 ** (u-cl+bl-s+1)
+ (Actually, we only compute a "high-order" approximation
+ to qsc, by using BigPmpyh.)
+ */
+ BigPmpyh (qsc, cInv, &t1[sw], uwsw3, n + 2);
+
+ /* Divide by 2**(u-s) to get initial estimate for quotient q
+ 2**(bl-cl-1) <= q <= 2**(bl-cl+1) (unless q = 0).
+ */
+ for (i = 0; i < n; i++)
+ q[i] = qsc[i+ (uw - sw)];
+
+ /* compute qc = low-order part of q * c
+ 2 ** (bl - 2) <= qc <= 2 ** (bl + 1) */
+ BigPmpyl (qc, q, c, n);
+
+ /* subtract qc from b to get initial estimate for remainder r */
+ BigSub (r, b, qc, n);
+
+ /* Adjust to be exactly right by repeated subtraction.
+ */
+ while (BigCmp (r, c, n) >= 0) {
+ BigSub (r, r, c, n);
+ BigInc (q, n);
+ }
+
+ T_memset ((POINTER)qc, 0, sizeof (qc));
+ T_memset ((POINTER)qsc, 0, sizeof (qsc));
+ T_memset ((POINTER)t1, 0, sizeof (t1));
+}
+
+
diff --git a/lib/dns/sec/dnssafe/bigsmod.c b/lib/dns/sec/dnssafe/bigsmod.c
new file mode 100644
index 00000000..b4ae68eb
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bigsmod.c
@@ -0,0 +1,28 @@
+/* Copyright (C) RSA Data Security, Inc. created 1987, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+
+UINT2 BigSmod (a, v, n)
+UINT2 *a;
+unsigned int v;
+unsigned int n;
+{
+ UINT4 r = (UINT4)0;
+ register int i;
+ unsigned int scale;
+
+ scale = (unsigned int)((UINT4)65536 % (UINT4)v);
+
+ for (i = n-1; i >= 0; i--) {
+ r = (r*scale) + (UINT4)a[i];
+ r = r % (UINT4)v;
+ }
+ return ((UINT2)r);
+}
diff --git a/lib/dns/sec/dnssafe/bigtocan.c b/lib/dns/sec/dnssafe/bigtocan.c
new file mode 100644
index 00000000..13e8315d
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bigtocan.c
@@ -0,0 +1,60 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "algae.h"
+#include "bigmath.h"
+
+
+/* BigToCanonical () copies a word vector to a byte vector while REVERSING the
+ order of significance. The word vector is input LSWord first and the
+ byte vector is written out MSByte first. It also removes a leading zero
+ sign bit. (The byte vector must represent a nonnegative number.)
+ Returns 0, AE_DATA.
+ */
+int BigToCanonical (bytePointer, numBytes, wordPointer, wordCount)
+unsigned char *bytePointer;
+unsigned int numBytes;
+UINT2 *wordPointer;
+unsigned int wordCount;
+{
+ unsigned int copyCount;
+
+ if (BigSign (wordPointer, wordCount) < 0 ||
+ (BigLen (wordPointer, wordCount) + 7) / 8 > numBytes)
+ return (AE_DATA);
+
+ /* start at end of byte vector */
+ bytePointer += numBytes-1;
+
+ /* copy as much as possible */
+ copyCount = (wordCount < numBytes / 2) ? wordCount : numBytes / 2;
+ wordCount -= copyCount;
+ numBytes -= 2 * copyCount;
+ while (copyCount--) {
+ /* Copy two bytes.*/
+ *bytePointer-- = (unsigned char)*wordPointer;
+ *bytePointer-- = (unsigned char)(*wordPointer >> 8);
+ wordPointer++;
+ }
+
+ if (wordCount && numBytes & 1) {
+ /* The number of output bytes was odd. Copy one last byte */
+ *bytePointer-- = (unsigned char)*wordPointer++;
+ wordCount--;
+ numBytes--;
+ }
+
+ /* zero fill remainder of byte vector */
+ while (numBytes--)
+ *bytePointer-- = 0;
+
+ return (0);
+}
+
+
diff --git a/lib/dns/sec/dnssafe/bigu.c b/lib/dns/sec/dnssafe/bigu.c
new file mode 100644
index 00000000..34c592a5
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bigu.c
@@ -0,0 +1,21 @@
+/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+
+/* BigU (t) -- returns length u where floor (2**u/b) is used as scaled version
+ of (1/b) when modding out modulo b, and where (positive) integers to be
+ reduced are < 2**t; i.e. they are at most t bits in length.
+ Result is (t+1) rounded up if necessary to next multiple of 16.
+*/
+unsigned int BigU (t)
+unsigned int t;
+{
+ return (16 * (((t+1) + 15)/16));
+}
diff --git a/lib/dns/sec/dnssafe/bigunexp.c b/lib/dns/sec/dnssafe/bigunexp.c
new file mode 100644
index 00000000..6bedbf51
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bigunexp.c
@@ -0,0 +1,98 @@
+/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bigmath.h"
+#include "surrendr.h"
+
+/* BigUnexp - decrypt ciphertext c into message m using Chinese remainder.
+ Assumes m, c of length 2*pSize, pp, qq, dp, dq and cr of length pSize.
+ Returns 0, AE_CANCEL.
+ */
+int BigUnexp (m, c, pp, qq, dp, dq, cr, pSize, surrenderContext)
+UINT2 *m; /* output message size 2*pSize words */
+UINT2 *c; /* input `ciphertext' size 2*pSize */
+UINT2 *pp; /* first prime size pSize */
+UINT2 *qq; /* second prime; size pSize */
+UINT2 *dp; /* decryption exponent mod p size pSize */
+UINT2 *dq; /* decryption exponent mod q size pSize */
+UINT2 *cr; /* CRT coef (inverse of q mod p) cr has len pSize */
+unsigned int pSize; /* length of p in words */
+A_SURRENDER_CTX *surrenderContext;
+{
+ struct BigUnexpFrame {
+ UINT2 t1[2 * MAX_RSA_PRIME_WORDS], t2[2 * MAX_RSA_PRIME_WORDS],
+ t3[2 * MAX_RSA_PRIME_WORDS], u1[2 * MAX_RSA_PRIME_WORDS],
+ u2[2 * MAX_RSA_PRIME_WORDS], u3[2 * MAX_RSA_PRIME_WORDS];
+ } *frame = (struct BigUnexpFrame *)NULL_PTR;
+#if !USE_ALLOCED_FRAME
+ struct BigUnexpFrame stackFrame;
+#endif
+ int status;
+
+ do {
+#if USE_ALLOCED_FRAME
+ if ((frame = (struct BigUnexpFrame *)T_malloc (sizeof (*frame)))
+ == (struct BigUnexpFrame *)NULL_PTR) {
+ status = AE_ALLOC;
+ break;
+ }
+#else
+ /* Just use the buffers allocated on the stack. */
+ frame = &stackFrame;
+#endif
+
+ BigConst (frame->t1, 0, 2 * pSize);
+ BigConst (frame->t2, 0, 2 * pSize);
+
+ /* u2=c mod p */
+ BigPdiv (frame->u1, frame->u2, c, pp, 2 * pSize, pSize);
+ if ((status = CheckSurrender (surrenderContext)) != 0)
+ break;
+
+ /* t1=c**dp modP */
+ if ((status = BigModExp
+ (frame->t1, frame->u2, dp, pp, pSize, surrenderContext)) != 0)
+ break;
+
+ /* u3=CmodQ */
+ BigPdiv (frame->u2, frame->u3, c, qq, 2 * pSize, pSize);
+ if ((status = CheckSurrender (surrenderContext)) != 0)
+ break;
+
+ /* t2=c**DQmodQ */
+ if ((status = BigModExp
+ (frame->t2, frame->u3, dq, qq, pSize, surrenderContext)) != 0)
+ break;
+
+ /* CRT.
+ */
+ BigSub (frame->u1, frame->t1, frame->t2, pSize);
+
+ while (-1 == BigSign (frame->u1, pSize))
+ BigAdd (frame->u1, frame->u1, pp, pSize);
+
+ BigMpy (frame->u2, frame->u1, cr, pSize);
+ if ((status = CheckSurrender (surrenderContext)) != 0)
+ break;
+ BigPdiv (frame->u3, frame->u1, frame->u2, pp, 2 * pSize, pSize);
+ if ((status = CheckSurrender (surrenderContext)) != 0)
+ break;
+ BigMpy (m, frame->u1, qq, pSize);
+
+ BigAdd (m, m, frame->t2, 2 * pSize);
+ } while (0);
+
+ if (frame != (struct BigUnexpFrame *)NULL_PTR) {
+ T_memset ((POINTER)frame, 0, sizeof (*frame));
+#if USE_ALLOCED_FRAME
+ T_free ((POINTER)frame);
+#endif
+ }
+ return (status);
+}
diff --git a/lib/dns/sec/dnssafe/binfocsh.c b/lib/dns/sec/dnssafe/binfocsh.c
new file mode 100644
index 00000000..f5c458e3
--- /dev/null
+++ b/lib/dns/sec/dnssafe/binfocsh.c
@@ -0,0 +1,63 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "binfocsh.h"
+
+void B_InfoCacheConstructor (infoCache)
+B_InfoCache *infoCache;
+{
+ /* Construct immediate base class. */
+ B_MemoryPoolConstructor (&infoCache->memoryPool);
+
+ T_memset ((POINTER)&infoCache->z, 0, sizeof (infoCache->z));
+}
+
+/* Returns 0, BE_ALLOC.
+ */
+int B_InfoCacheAddInfo (infoCache, infoType, info)
+B_InfoCache *infoCache;
+POINTER infoType;
+POINTER info;
+{
+ int status;
+
+ if ((status = B_MemoryPoolRealloc
+ (&infoCache->memoryPool, (POINTER *)&infoCache->z.infos,
+ (infoCache->z.infoCount + 1) * sizeof (infoCache->z.infos[0]))) != 0)
+ return (status);
+
+ infoCache->z.infos[infoCache->z.infoCount].infoType = infoType;
+ infoCache->z.infos[infoCache->z.infoCount].info = info;
+ infoCache->z.infoCount++;
+
+ return (0);
+}
+
+/* Set info to the entry in the cache for the given infoType.
+ Returns 0, or BE_NOT_SUPPORTED if infoType is not in the cache.
+ */
+int B_InfoCacheFindInfo (infoCache, info, infoType)
+B_InfoCache *infoCache;
+POINTER *info;
+POINTER infoType;
+{
+ unsigned int i;
+
+ for (i = 0; i < infoCache->z.infoCount; ++i) {
+ if (infoCache->z.infos[i].infoType == infoType) {
+ /* The info has already been constructed. */
+ *info = infoCache->z.infos[i].info;
+ return (0);
+ }
+ }
+
+ return (BE_NOT_SUPPORTED);
+}
+
diff --git a/lib/dns/sec/dnssafe/binfocsh.h b/lib/dns/sec/dnssafe/binfocsh.h
new file mode 100644
index 00000000..32778765
--- /dev/null
+++ b/lib/dns/sec/dnssafe/binfocsh.h
@@ -0,0 +1,33 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _BINFOCSH_H_
+#define _BINFOCSH_H_ 1
+
+#include "bmempool.h"
+
+typedef struct B_InfoCache {
+ B_MemoryPool memoryPool; /* inherited */
+ struct {
+ unsigned int infoCount;
+ struct {
+ POINTER infoType;
+ POINTER info;
+ } *infos;
+ /* POINTER reserved; */
+ } z; /* z gives the members that are zeroized by the constructor */
+} B_InfoCache;
+
+void B_InfoCacheConstructor PROTO_LIST ((B_InfoCache *));
+#define B_INFO_CACHE_Destructor(infoCache) \
+ B_MemoryPoolDestructor (&(infoCache)->memoryPool)
+
+int B_InfoCacheAddInfo PROTO_LIST ((B_InfoCache *, POINTER, POINTER));
+int B_InfoCacheFindInfo PROTO_LIST ((B_InfoCache *, POINTER *, POINTER));
+
+#endif
diff --git a/lib/dns/sec/dnssafe/bkey.c b/lib/dns/sec/dnssafe/bkey.c
new file mode 100644
index 00000000..ddd23460
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bkey.c
@@ -0,0 +1,101 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "kinfotyp.h"
+#include "kiitem.h"
+
+int B_KeySetInfo (key, keyInfoType, info)
+B_Key *key;
+B_KeyInfoType *keyInfoType;
+POINTER info;
+{
+ if (key == (B_Key *)NULL_PTR)
+ return (BE_KEY_OBJ);
+
+ if (key->infoCache.z.infoCount > 0)
+ return (BE_KEY_ALREADY_SET);
+
+ /* This will cache the encoding. */
+ return ((*keyInfoType->AddInfo) (key, info));
+}
+
+int B_KeyGetInfo (key, info, keyInfoType)
+B_Key *key;
+POINTER *info;
+B_KeyInfoType *keyInfoType;
+{
+ int status;
+
+ if (key == (B_Key *)NULL_PTR)
+ return (BE_KEY_OBJ);
+
+ if (key->infoCache.z.infoCount == 0)
+ return (BE_KEY_NOT_SET);
+
+ /* First check if the encoding is already in the encoding cache.
+ */
+ if (B_InfoCacheFindInfo (&key->infoCache, info, (POINTER)keyInfoType) == 0)
+ return (0);
+
+ /* Info is not in the cache, go ahead and encode.
+ */
+ if ((status = (*keyInfoType->MakeInfo) (info, key)) != 0)
+ return (status);
+
+ return (B_InfoCacheAddInfo (&key->infoCache, (POINTER)keyInfoType, *info));
+}
+
+/* Create an ITEM out of the data and len and cache it as KITItem.
+ The data is already alloced in the info cache.
+ Returns 0, BE_ALLOC.
+ */
+int B_KeyAddItemInfo (key, data, len)
+B_Key *key;
+unsigned char *data;
+unsigned int len;
+{
+ ITEM *newInfo;
+ int status;
+
+ if ((status = B_MemoryPoolAlloc
+ (&key->infoCache.memoryPool, (POINTER *)&newInfo, sizeof (*newInfo)))
+ != 0)
+ return (status);
+
+ newInfo->data = data;
+ newInfo->len = len;
+
+ return (B_InfoCacheAddInfo
+ (&key->infoCache, (POINTER)&KITItem, (POINTER)newInfo));
+}
+
+/* Return the number of bits in the canonical, positive integer.
+ B_IntegerBits (0) = 0.
+ */
+unsigned int B_IntegerBits (integer, integerLen)
+unsigned char *integer;
+unsigned int integerLen;
+{
+ unsigned char mask, byte;
+ unsigned int bytes, bits;
+
+ for (bytes = 0; bytes < integerLen && integer[bytes] == 0; bytes++);
+ if (bytes == integerLen)
+ return (0);
+
+ /* Get byte to test and increment byte count for final calculation */
+ byte = integer[bytes++];
+
+ /* Get number of bits in most significant byte */
+ for (bits = 8, mask = 0x80; (byte & mask) == 0; bits--, mask >>= 1);
+ return (8 * (integerLen - bytes) + bits);
+}
+
diff --git a/lib/dns/sec/dnssafe/bkey.h b/lib/dns/sec/dnssafe/bkey.h
new file mode 100644
index 00000000..bfcaca7a
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bkey.h
@@ -0,0 +1,32 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _BKEY_H_
+#define _BKEY_H_ 1
+
+#include "binfocsh.h"
+
+typedef struct {
+ B_InfoCache infoCache; /* inherited */
+
+ /* For now we don't need to worry about a reserved field.
+ struct {
+ POINTER reserved;
+ } z;
+ */
+} B_Key;
+
+#define B_KEY_Constructor(key) (B_InfoCacheConstructor (&(key)->infoCache))
+#define B_KEY_Destructor(key) (B_INFO_CACHE_Destructor (&(key)->infoCache))
+
+struct B_KeyInfoType;
+int B_KeySetInfo PROTO_LIST ((B_Key *, struct B_KeyInfoType *, POINTER));
+int B_KeyGetInfo PROTO_LIST ((B_Key *, POINTER *, struct B_KeyInfoType *));
+int B_KeyAddItemInfo PROTO_LIST ((B_Key *, unsigned char *, unsigned int));
+
+#endif
diff --git a/lib/dns/sec/dnssafe/bmempool.c b/lib/dns/sec/dnssafe/bmempool.c
new file mode 100644
index 00000000..37510a46
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bmempool.c
@@ -0,0 +1,275 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bmempool.h"
+
+#define ALLOCED_LIST_SLACK 10
+
+void B_MemoryPoolConstructor (memoryPool)
+B_MemoryPool *memoryPool;
+{
+ T_memset ((POINTER)&memoryPool->z, 0, sizeof (memoryPool->z));
+}
+
+void B_MemoryPoolDestructor (memoryPool)
+B_MemoryPool *memoryPool;
+{
+ B_MemoryPoolReset (memoryPool);
+ T_free ((POINTER)memoryPool->z.allocedList);
+}
+
+/* For each item on the alloced list, call the DeleteFuncion if
+ there is one, otherwise zerioze and free.
+ Leave the list itself allocated with all NULL entries.
+ */
+void B_MemoryPoolReset (memoryPool)
+B_MemoryPool *memoryPool;
+{
+ B_ALLOCED_DATA *allocedData;
+ unsigned int i;
+
+ for (i = memoryPool->z.allocedCount,
+ allocedData = memoryPool->z.allocedList;
+ i-- > 0;
+ ++allocedData) {
+ /* Only process this entry if the data is not NULL_PTR.
+ */
+ if (allocedData->object != NULL_PTR) {
+ if (allocedData->DeleteFunction !=
+ (B_MEMORY_POOL_DELETE_FUNCTION)NULL_PTR)
+ /* There is a destroy function, so call. */
+ (*allocedData->DeleteFunction) (allocedData->object);
+ else {
+ T_memset (allocedData->object, 0, allocedData->size);
+ T_free (allocedData->object);
+ }
+ allocedData->object = NULL_PTR;
+ }
+ }
+
+ memoryPool->z.allocedCount = 0;
+ /* Note that maxAllocedCount still indicates the size of the alloced list. */
+}
+
+/* On any error return, NULL_PTR is returned for the data.
+ Returns 0 if successful, or BE_ALLOC if cannot alloc the memory.
+ */
+int B_MemoryPoolAlloc (memoryPool, data, size)
+B_MemoryPool *memoryPool;
+POINTER *data;
+unsigned int size;
+{
+ if ((*data = T_malloc (size)) == NULL_PTR)
+ return (BE_ALLOC);
+ return (B_MemoryPoolAdoptData (memoryPool, data, size));
+}
+
+/* Use alloc to allocate the newData of length size and T_memcpy data into it.
+ On any error return, NULL_PTR is returned for the newData.
+ Returns 0 if successful or BE_ALLOC if cannot alloc the memory.
+ */
+int B_MemoryPoolAllocAndCopy (memoryPool, newData, data, size)
+B_MemoryPool *memoryPool;
+POINTER *newData;
+POINTER data;
+unsigned int size;
+{
+ int status;
+
+ if ((status = B_MemoryPoolAlloc (memoryPool, newData, size)) != 0)
+ return (status);
+
+ T_memcpy (*newData, data, size);
+ return (0);
+}
+
+/* Put the given data on the memory pool's alloced list.
+ The size of the alloced data buffer must be passed in so that it can
+ be zeroized when the object is reset (Pass in a size of zero if
+ the buffer does not need to be zeroized.)
+ The data is passed by reference, so that if there is an error,
+ the data is zeroized and freed, and the pointer to the data is set
+ to NULL_PTR.
+ This routine should be used with caution - it is meant be called
+ immediately after an alloc.
+ No check is made as to whether the data is already on the memory pool's
+ alloced list (which would be a problem since it will get freed twice).
+ Returns 0 if successful or BE_ALLOC if cannot expand the alloced list.
+ */
+int B_MemoryPoolAdoptData (memoryPool, data, size)
+B_MemoryPool *memoryPool;
+POINTER *data;
+unsigned int size;
+{
+ int status;
+
+ if ((status = B_MemoryPoolAdoptHelper
+ (memoryPool, *data, size, (B_MEMORY_POOL_DELETE_FUNCTION)NULL_PTR))
+ != 0) {
+ T_memset (*data, 0, size);
+ T_free (*data);
+ *data = NULL_PTR;
+ return (status);
+ }
+
+ return (0);
+}
+
+/* Put the given object on the memory pool's alloced list.
+ The size of the alloced object must be passed in so that it can
+ be zeroized when the object is reset (Pass in a size of zero if
+ the buffer does not need to be zeroized, especially if it
+ is an object and not a data buffer.)
+ The object is not passed by reference. If there is an error,
+ the calling routine should clean up the object, such as zeroizing
+ and freeing.
+ No check is made as to whether the object is already on the memory pool's
+ alloced list (which would be a problem since it will get freed twice).
+ Returns 0 if successful or BE_ALLOC if cannot expand the alloced list.
+ */
+int B_MemoryPoolAdoptHelper (memoryPool, object, size, DeleteFunction)
+B_MemoryPool *memoryPool;
+POINTER object;
+unsigned int size;
+B_MEMORY_POOL_DELETE_FUNCTION DeleteFunction;
+{
+ POINTER newList;
+ unsigned int newMaxCount;
+
+ if (memoryPool->z.allocedCount + 1 > memoryPool->z.maxAllocedCount) {
+ /* Make extra room on the alloced list.
+ */
+ newMaxCount = memoryPool->z.allocedCount + ALLOCED_LIST_SLACK;
+ if ((newList = T_malloc (newMaxCount * sizeof (B_ALLOCED_DATA)))
+ == NULL_PTR)
+ /* alloc errorm so caller should clean up the object it passed. */
+ return (BE_ALLOC);
+
+ /* move in new list and free old list */
+ T_memcpy
+ (newList, (POINTER)memoryPool->z.allocedList,
+ memoryPool->z.allocedCount * sizeof (B_ALLOCED_DATA));
+ T_free ((POINTER)memoryPool->z.allocedList);
+ memoryPool->z.allocedList = (B_ALLOCED_DATA *)newList;
+ memoryPool->z.maxAllocedCount = newMaxCount;
+ }
+
+ /* Put object on alloced list and increment count.
+ */
+ memoryPool->z.allocedList[memoryPool->z.allocedCount].object = object;
+ memoryPool->z.allocedList[memoryPool->z.allocedCount].size = size;
+ memoryPool->z.allocedList[memoryPool->z.allocedCount++].DeleteFunction =
+ DeleteFunction;
+ return (0);
+}
+
+/* 'data' points to the pointer to realloc and also is used to
+ return the realloced memory.
+ If data points to NULL_PTR, behaves like B_MemoryPoolAlloc.
+ Find 'data' on the allocedList and realloc it to the given size,
+ replacing the entry on the alloced list with the new memory.
+ If it is not on the allocedList, the adopt the reallocated memory.
+ If the buffer must be moved during the realloc, the old buffer is not
+ zeroized (unless T_realloc does the zeroizing).
+ This assumes that the (POINTER *)data is not (POINTER *)NULL_PTR.
+ This assumes there is no DesroyFunction for this entry. That is,
+ you should not try to resize an object.
+ On any error return, NULL_PTR is returned for the data.
+ Returns 0 if successful or BE_ALLOC if cannot alloc the memory.
+ */
+int B_MemoryPoolRealloc (memoryPool, data, size)
+B_MemoryPool *memoryPool;
+POINTER *data;
+unsigned int size;
+{
+ B_ALLOCED_DATA *allocedData;
+
+ allocedData = B_MemoryPoolFindAllocedObject (memoryPool, *data);
+
+ if ((*data = T_realloc (*data, size)) == NULL_PTR) {
+ if (allocedData != (B_ALLOCED_DATA *)NULL_PTR)
+ /* Could not reallocate, so nullify this entry. */
+ allocedData->object = NULL_PTR;
+
+ return (BE_ALLOC);
+ }
+
+ /* Realloc was successful.
+ */
+ if (allocedData == (B_ALLOCED_DATA *)NULL_PTR)
+ /* The data was not in the memory pool to start with, so adopt it.
+ Note that this also happens when the data is initially NULL_PTR. */
+ return (B_MemoryPoolAdoptData (memoryPool, data, size));
+
+ /* Replace the entry on the alloced list with the new memory.
+ */
+ allocedData->object = *data;
+ allocedData->size = size;
+ return (0);
+}
+
+/* Find the object in the alloced list, call the DeleteFunction if
+ there is one, zeroize it and free it, nullifying that alloced list entry.
+ The object to be freed is passed by pointer and is set to NULL_PTR to
+ enforce the fact that the address no longer points to valid memory.
+ This assumes that the (POINTER *)data is not (POINTER *)NULL_PTR.
+ If the address is not found on the alloced list, only set the address
+ to NULL_PTR.
+ */
+void B_MemoryPoolFree (memoryPool, object)
+B_MemoryPool *memoryPool;
+POINTER *object;
+{
+ B_ALLOCED_DATA *allocedData;
+
+ if ((allocedData = B_MemoryPoolFindAllocedObject (memoryPool, *object))
+ != (B_ALLOCED_DATA *)NULL_PTR) {
+ if (allocedData->DeleteFunction !=
+ (B_MEMORY_POOL_DELETE_FUNCTION)NULL_PTR)
+ /* There is a destroy function, so call. */
+ (*allocedData->DeleteFunction) (allocedData->object);
+ else {
+ T_memset (*object, 0, allocedData->size);
+ T_free (*object);
+ }
+
+ /* Set this entry to NULL_PTR so that reset will not process it. */
+ allocedData->object = NULL_PTR;
+ }
+
+ *object = NULL_PTR;
+}
+
+/* Return a pointer to the alloced object entry in the memoryPool.
+ Return (ALLOCED_DATA *)NULL_PTR if object is NULL_PTR or object is not
+ in the memoryPool.
+ */
+B_ALLOCED_DATA *B_MemoryPoolFindAllocedObject (memoryPool, object)
+B_MemoryPool *memoryPool;
+POINTER object;
+{
+ B_ALLOCED_DATA *allocedData;
+ unsigned int i;
+
+ if (object == NULL_PTR)
+ return ((B_ALLOCED_DATA *)NULL_PTR);
+
+ for (i = memoryPool->z.allocedCount,
+ allocedData = memoryPool->z.allocedList;
+ i-- > 0;
+ ++allocedData) {
+ if (allocedData->object == object)
+ return (allocedData);
+ }
+
+ /* data not found. */
+ return ((B_ALLOCED_DATA *)NULL_PTR);
+}
+
diff --git a/lib/dns/sec/dnssafe/bmempool.h b/lib/dns/sec/dnssafe/bmempool.h
new file mode 100644
index 00000000..b5216dd2
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bmempool.h
@@ -0,0 +1,53 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _BMEMPOOL_H_
+#define _BMEMPOOL_H_ 1
+
+typedef void (*B_MEMORY_POOL_DELETE_FUNCTION) PROTO_LIST ((POINTER));
+
+typedef struct {
+ POINTER object;
+ unsigned int size;
+ B_MEMORY_POOL_DELETE_FUNCTION DeleteFunction;
+} B_ALLOCED_DATA;
+
+typedef struct {
+ struct {
+ unsigned int allocedCount;
+ unsigned int maxAllocedCount; /* Size of the actuall allocated list */
+ B_ALLOCED_DATA *allocedList;
+ /* POINTER reserved; */
+ } z; /* z gives the members that are zeroized by the constructor */
+} B_MemoryPool;
+
+void B_MemoryPoolConstructor PROTO_LIST ((B_MemoryPool *));
+void B_MemoryPoolDestructor PROTO_LIST ((B_MemoryPool *));
+
+void B_MemoryPoolReset PROTO_LIST ((B_MemoryPool *));
+int B_MemoryPoolAlloc PROTO_LIST ((B_MemoryPool *, POINTER *, unsigned int));
+int B_MemoryPoolAllocAndCopy PROTO_LIST
+ ((B_MemoryPool *, POINTER *, POINTER, unsigned int));
+int B_MemoryPoolAdoptData PROTO_LIST
+ ((B_MemoryPool *, POINTER *, unsigned int));
+int B_MemoryPoolAdoptObject PROTO_LIST
+ ((B_MemoryPool *, POINTER *, B_MEMORY_POOL_DELETE_FUNCTION));
+int B_MemoryPoolRealloc PROTO_LIST ((B_MemoryPool *, POINTER *, unsigned int));
+int B_MemoryPoolSafeRealloc PROTO_LIST
+ ((B_MemoryPool *, POINTER *, unsigned int));
+void B_MemoryPoolFree PROTO_LIST ((B_MemoryPool *, POINTER *));
+void B_MemoryPoolResetExceptObject PROTO_LIST ((B_MemoryPool *, POINTER));
+
+/* These are "private member functions ".
+ */
+B_ALLOCED_DATA *B_MemoryPoolFindAllocedObject PROTO_LIST
+ ((B_MemoryPool *, POINTER));
+int B_MemoryPoolAdoptHelper PROTO_LIST
+ ((B_MemoryPool *, POINTER, unsigned int, B_MEMORY_POOL_DELETE_FUNCTION));
+
+#endif
diff --git a/lib/dns/sec/dnssafe/bsafe2.h b/lib/dns/sec/dnssafe/bsafe2.h
new file mode 100644
index 00000000..4eb4ef55
--- /dev/null
+++ b/lib/dns/sec/dnssafe/bsafe2.h
@@ -0,0 +1,194 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _BSAFE_H_
+#define _BSAFE_H_ 1
+
+#ifndef T_CALL
+#define T_CALL
+#endif
+
+#include "atypes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BE_ALGORITHM_ALREADY_SET 0x0200
+#define BE_ALGORITHM_INFO 0x0201
+#define BE_ALGORITHM_NOT_INITIALIZED 0x0202
+#define BE_ALGORITHM_NOT_SET 0x0203
+#define BE_ALGORITHM_OBJ 0x0204
+#define BE_ALG_OPERATION_UNKNOWN 0x0205
+#define BE_ALLOC 0x0206
+#define BE_CANCEL 0x0207
+#define BE_DATA 0x0208
+#define BE_EXPONENT_EVEN 0x0209
+#define BE_EXPONENT_LEN 0x020a
+#define BE_HARDWARE 0x020b
+#define BE_INPUT_DATA 0x020c
+#define BE_INPUT_LEN 0x020d
+#define BE_KEY_ALREADY_SET 0x020e
+#define BE_KEY_INFO 0x020f
+#define BE_KEY_LEN 0x0210
+#define BE_KEY_NOT_SET 0x0211
+#define BE_KEY_OBJ 0x0212
+#define BE_KEY_OPERATION_UNKNOWN 0x0213
+#define BE_MEMORY_OBJ 0x0214
+#define BE_MODULUS_LEN 0x0215
+#define BE_NOT_INITIALIZED 0x0216
+#define BE_NOT_SUPPORTED 0x0217
+#define BE_OUTPUT_LEN 0x0218
+#define BE_OVER_32K 0x0219
+#define BE_RANDOM_NOT_INITIALIZED 0x021a
+#define BE_RANDOM_OBJ 0x021b
+#define BE_SIGNATURE 0x021c
+#define BE_WRONG_ALGORITHM_INFO 0x021d
+#define BE_WRONG_KEY_INFO 0x021e
+#define BE_INPUT_COUNT 0x021f
+#define BE_OUTPUT_COUNT 0x0220
+#define BE_METHOD_NOT_IN_CHOOSER 0x221
+
+typedef POINTER B_KEY_OBJ;
+typedef POINTER B_ALGORITHM_OBJ;
+
+typedef int (T_CALL *B_INFO_TYPE) PROTO_LIST ((POINTER *));
+
+typedef struct B_ALGORITHM_METHOD B_ALGORITHM_METHOD;
+typedef B_ALGORITHM_METHOD **B_ALGORITHM_CHOOSER;
+
+/* Routines supplied by the implementor.
+ */
+void T_CALL T_memset PROTO_LIST ((POINTER, int, unsigned int));
+void T_CALL T_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
+void T_CALL T_memmove PROTO_LIST ((POINTER, POINTER, unsigned int));
+int T_CALL T_memcmp PROTO_LIST ((POINTER, POINTER, unsigned int));
+POINTER T_CALL T_malloc PROTO_LIST ((unsigned int));
+POINTER T_CALL T_realloc PROTO_LIST ((POINTER, unsigned int));
+void T_CALL T_free PROTO_LIST ((POINTER));
+
+/* The key object.
+ */
+int T_CALL B_CreateKeyObject PROTO_LIST ((B_KEY_OBJ *));
+void T_CALL B_DestroyKeyObject PROTO_LIST ((B_KEY_OBJ *));
+int T_CALL B_SetKeyInfo PROTO_LIST ((B_KEY_OBJ, B_INFO_TYPE, POINTER));
+int T_CALL B_GetKeyInfo PROTO_LIST ((POINTER *, B_KEY_OBJ, B_INFO_TYPE));
+
+/* The algorithm object.
+ */
+int T_CALL B_CreateAlgorithmObject PROTO_LIST ((B_ALGORITHM_OBJ *));
+void T_CALL B_DestroyAlgorithmObject PROTO_LIST ((B_ALGORITHM_OBJ *));
+int T_CALL B_SetAlgorithmInfo PROTO_LIST
+ ((B_ALGORITHM_OBJ, B_INFO_TYPE, POINTER));
+int T_CALL B_GetAlgorithmInfo PROTO_LIST
+ ((POINTER *, B_ALGORITHM_OBJ, B_INFO_TYPE));
+
+unsigned int B_IntegerBits PROTO_LIST ((unsigned char *, unsigned int));
+
+/* Algorithm operations.
+ */
+int T_CALL B_RandomInit PROTO_LIST
+ ((B_ALGORITHM_OBJ, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *));
+int T_CALL B_RandomUpdate PROTO_LIST
+ ((B_ALGORITHM_OBJ, unsigned char *, unsigned int, A_SURRENDER_CTX *));
+int T_CALL B_GenerateRandomBytes PROTO_LIST
+ ((B_ALGORITHM_OBJ, unsigned char *, unsigned int, A_SURRENDER_CTX *));
+
+int T_CALL B_DigestInit PROTO_LIST
+ ((B_ALGORITHM_OBJ, B_KEY_OBJ, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *));
+int T_CALL B_DigestUpdate PROTO_LIST
+ ((B_ALGORITHM_OBJ, unsigned char *, unsigned int, A_SURRENDER_CTX *));
+int T_CALL B_DigestFinal PROTO_LIST
+ ((B_ALGORITHM_OBJ, unsigned char *, unsigned int *, unsigned int,
+ A_SURRENDER_CTX *));
+
+int T_CALL B_EncryptInit PROTO_LIST
+ ((B_ALGORITHM_OBJ, B_KEY_OBJ, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *));
+int T_CALL B_EncryptUpdate PROTO_LIST
+ ((B_ALGORITHM_OBJ, unsigned char *, unsigned int *, unsigned int,
+ unsigned char *, unsigned int, B_ALGORITHM_OBJ, A_SURRENDER_CTX *));
+int T_CALL B_EncryptFinal PROTO_LIST
+ ((B_ALGORITHM_OBJ, unsigned char *, unsigned int *, unsigned int,
+ B_ALGORITHM_OBJ, A_SURRENDER_CTX *));
+
+int T_CALL B_DecryptInit PROTO_LIST
+ ((B_ALGORITHM_OBJ, B_KEY_OBJ, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *));
+int T_CALL B_DecryptUpdate PROTO_LIST
+ ((B_ALGORITHM_OBJ, unsigned char *, unsigned int *, unsigned int,
+ unsigned char *, unsigned int, B_ALGORITHM_OBJ, A_SURRENDER_CTX *));
+int T_CALL B_DecryptFinal PROTO_LIST
+ ((B_ALGORITHM_OBJ, unsigned char *, unsigned int *, unsigned int,
+ B_ALGORITHM_OBJ, A_SURRENDER_CTX *));
+
+
+
+int T_CALL B_GenerateInit PROTO_LIST
+ ((B_ALGORITHM_OBJ, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *));
+int T_CALL B_GenerateKeypair PROTO_LIST
+ ((B_ALGORITHM_OBJ, B_KEY_OBJ, B_KEY_OBJ, B_ALGORITHM_OBJ,
+ A_SURRENDER_CTX *));
+int T_CALL B_GenerateParameters PROTO_LIST
+ ((B_ALGORITHM_OBJ, B_ALGORITHM_OBJ, B_ALGORITHM_OBJ, A_SURRENDER_CTX *));
+
+
+/* Information for password-based encryption (PBE) algorithms.
+ */
+typedef struct {
+ unsigned char *salt; /* salt value */
+ unsigned int iterationCount; /* iteration count */
+} B_PBE_PARAMS;
+
+/* Information for MAC algorithm.
+ */
+typedef struct {
+ unsigned int macLen; /* length of MAC value */
+} B_MAC_PARAMS;
+
+
+/* Information for BSAFE 1.x compatible encryption algorithms.
+ */
+
+
+typedef struct {
+ unsigned int threshold; /* share threshold */
+} B_SECRET_SHARING_PARAMS;
+
+/* Key Info Types.
+ */
+int T_CALL KI_8Byte PROTO_LIST ((POINTER *));
+int T_CALL KI_Item PROTO_LIST ((POINTER *));
+int T_CALL KI_PKCS_RSAPrivate PROTO_LIST ((POINTER *));
+int T_CALL KI_RSAPublic PROTO_LIST ((POINTER *));
+int T_CALL KI_RSA_CRT PROTO_LIST ((POINTER *));
+
+/* Algorithm Info Types.
+ */
+int T_CALL AI_MD5 PROTO_LIST ((POINTER *));
+int T_CALL AI_MD5Random PROTO_LIST ((POINTER *));
+int T_CALL AI_PKCS_RSAPrivate PROTO_LIST ((POINTER *));
+int T_CALL AI_PKCS_RSAPublic PROTO_LIST ((POINTER *));
+int T_CALL AI_RSAKeyGen PROTO_LIST ((POINTER *));
+int T_CALL AI_RSAPrivate PROTO_LIST ((POINTER *));
+int T_CALL AI_RSAPublic PROTO_LIST ((POINTER *));
+
+
+/* Algorithm methods for use int the algorithm chooser.
+ */
+extern B_ALGORITHM_METHOD T_CALL AM_MD5;
+extern B_ALGORITHM_METHOD T_CALL AM_MD5_RANDOM;
+extern B_ALGORITHM_METHOD T_CALL AM_RSA_CRT_DECRYPT;
+extern B_ALGORITHM_METHOD T_CALL AM_RSA_CRT_ENCRYPT;
+extern B_ALGORITHM_METHOD T_CALL AM_RSA_DECRYPT;
+extern B_ALGORITHM_METHOD T_CALL AM_RSA_ENCRYPT;
+extern B_ALGORITHM_METHOD T_CALL AM_RSA_KEY_GEN;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/dns/sec/dnssafe/btypechk.h b/lib/dns/sec/dnssafe/btypechk.h
new file mode 100644
index 00000000..93f5a97b
--- /dev/null
+++ b/lib/dns/sec/dnssafe/btypechk.h
@@ -0,0 +1,25 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _BTYPECHK_H_
+#define _BTYPECHK_H_ 1
+
+struct B_TypeCheck;
+
+typedef void (*B_TYPE_CHECK_DESTRUCTOR) PROTO_LIST ((struct B_TypeCheck *));
+
+typedef struct B_TypeCheck {
+ B_TYPE_CHECK_DESTRUCTOR _Destructor;
+} B_TypeCheck;
+
+#define B_TYPE_CHECK_Constructor(typeCheck, Destructor)\
+ (typeCheck)->_Destructor = (Destructor)
+#define B_TYPE_CHECK_Destructor(typeCheck)\
+ (*(typeCheck)->_Destructor) (typeCheck)
+
+#endif
diff --git a/lib/dns/sec/dnssafe/cantobig.c b/lib/dns/sec/dnssafe/cantobig.c
new file mode 100644
index 00000000..79b760f7
--- /dev/null
+++ b/lib/dns/sec/dnssafe/cantobig.c
@@ -0,0 +1,57 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "algae.h"
+#include "bigmath.h"
+
+/* CanonicalToBig () copies a byte vector into a word vector while REVERSING
+ the order of significance. The byte vector is input MSByte first while
+ the word vector is written out LSWord first. It also adds a leading zero
+ sign bit if necessary.
+ Returns 0, AE_DATA.
+ */
+int CanonicalToBig (wordPointer, wordCount, bytePointer, numBytes)
+UINT2 *wordPointer;
+unsigned int wordCount;
+unsigned char *bytePointer;
+unsigned int numBytes;
+{
+ unsigned int copyCount;
+
+ if (A_IntegerBits (bytePointer, numBytes) / 16 + 1 > wordCount)
+ return (AE_DATA);
+
+ /* start at end of byte vector */
+ bytePointer += numBytes-1;
+
+ /* copy as much as possible */
+ copyCount = (wordCount < numBytes / 2) ? wordCount : numBytes / 2;
+ wordCount -= copyCount;
+ numBytes -= 2 * copyCount;
+ while (copyCount--) {
+ /* Copy two bytes.*/
+ *wordPointer++ = (UINT2)*bytePointer + (*(bytePointer - 1) << 8);
+ bytePointer -= 2;
+ }
+
+ if (wordCount && numBytes & 1) {
+ /* If the number of input bytes was odd. Copy one last byte.*/
+ *wordPointer++ = (UINT2)*bytePointer--;
+ wordCount--;
+ numBytes--;
+ }
+
+ /* zero fill remainder of word vector */
+ while (wordCount--)
+ *wordPointer++ = 0;
+
+ return (0);
+}
+
+
diff --git a/lib/dns/sec/dnssafe/crt2.c b/lib/dns/sec/dnssafe/crt2.c
new file mode 100644
index 00000000..36b9d01f
--- /dev/null
+++ b/lib/dns/sec/dnssafe/crt2.c
@@ -0,0 +1,228 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "algae.h"
+#include "crt2.h"
+#include "bigmath.h"
+
+/* RSA encryption/decryption with Chinese Remainder Theorem.
+ */
+
+#define GENERATE_BREAK(type) { \
+ status = type; \
+ break; \
+ }
+
+static int RSA_CRT2 PROTO_LIST
+ ((A_RSA_CRT2_CTX *, unsigned char *, unsigned int *, unsigned int,
+ unsigned char *, A_SURRENDER_CTX *));
+
+int A_RSA_CRT2Init (context, key)
+A_RSA_CRT2_CTX *context;
+A_RSA_CRT_KEY *key;
+{
+ if (A_IntegerBits (key->modulus.data, key->modulus.len)
+ > MAX_RSA_MODULUS_BITS)
+ /* Key len is too big to handle. */
+ return (AE_MODULUS_LEN);
+
+ /* Set the block update blockLen to be big enough to hold the modulus.
+ */
+ context->blockLen =
+ BITS_TO_LEN (A_IntegerBits (key->modulus.data, key->modulus.len));
+
+ context->inputLen = 0;
+
+ /* convert first prime to bignum format */
+ if (CanonicalToBig
+ (context->primeP, MAX_RSA_PRIME_WORDS, key->prime[0].data,
+ key->prime[0].len))
+ return (AE_KEY_INFO);
+
+ /* compute significant length of first prime */
+ context->primeWords = BITS_TO_WORDS
+ (BigLen (context->primeP, MAX_RSA_PRIME_WORDS));
+
+ /* convert other private key parameters to bignum format */
+ if (CanonicalToBig
+ (context->primeQ, context->primeWords, key->prime[1].data,
+ key->prime[1].len) ||
+ CanonicalToBig
+ (context->exponentP, context->primeWords,
+ key->primeExponent[0].data, key->primeExponent[0].len) ||
+ CanonicalToBig
+ (context->exponentQ, context->primeWords,
+ key->primeExponent[1].data, key->primeExponent[1].len) ||
+ CanonicalToBig
+ (context->coefficient, context->primeWords,
+ key->coefficient.data, key->coefficient.len))
+ return (AE_KEY_INFO);
+
+ /* convert modulus to bignum format */
+ if (CanonicalToBig
+ (context->modulus, 2 * context->primeWords,
+ key->modulus.data, key->modulus.len))
+ return (AE_KEY_INFO);
+
+ return (0);
+}
+
+int A_RSA_CRT2Update
+ (context, partOut, partOutLen, maxPartOutLen, partIn, partInLen,
+ surrenderContext)
+A_RSA_CRT2_CTX *context;
+unsigned char *partOut;
+unsigned int *partOutLen;
+unsigned int maxPartOutLen;
+unsigned char *partIn;
+unsigned int partInLen;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+ unsigned int partialLen, localPartOutLen;
+
+ /* Initialize partOutLen to zero. */
+ *partOutLen = 0;
+
+ if (context->inputLen + partInLen < context->blockLen) {
+ /* Not enough to encrypt - just accumulate.
+ */
+ T_memcpy
+ ((POINTER)(context->input + context->inputLen), (POINTER)partIn,
+ partInLen);
+ context->inputLen += partInLen;
+ return (0);
+ }
+
+ if (context->inputLen > 0) {
+ /* Need to accumulate the rest of the block bytes into the input and
+ encrypt from there (otherwise it's OK to encrypt straight from
+ the partIn).
+ */
+ partialLen = context->blockLen - context->inputLen;
+ T_memcpy
+ ((POINTER)(context->input + context->inputLen), (POINTER)partIn,
+ partialLen);
+ partIn += partialLen;
+ partInLen -= partialLen;
+
+ if ((status = RSA_CRT2
+ (context, partOut, &localPartOutLen, maxPartOutLen, context->input,
+ surrenderContext)) != 0)
+ return (status);
+ (*partOutLen) += localPartOutLen;
+ partOut += localPartOutLen;
+ maxPartOutLen -= localPartOutLen;
+ }
+
+ /* Encrypt as many blocks of input as provided.
+ */
+ while (partInLen >= context->blockLen) {
+ if ((status = RSA_CRT2
+ (context, partOut, &localPartOutLen, maxPartOutLen, partIn,
+ surrenderContext)) != 0)
+ return (status);
+
+ partIn += context->blockLen;
+ partInLen -= context->blockLen;
+ (*partOutLen) += localPartOutLen;
+ partOut += localPartOutLen;
+ maxPartOutLen -= localPartOutLen;
+ }
+
+ /* Copy remaining input bytes to the context's input buffer.
+ */
+ T_memcpy
+ ((POINTER)context->input, partIn, partInLen);
+ context->inputLen = partInLen;
+ return (0);
+}
+
+int A_RSA_CRT2Final (context)
+A_RSA_CRT2_CTX *context;
+{
+ if (context->inputLen != 0)
+ return (AE_INPUT_LEN);
+
+ /* Restart context to accumulate a new block.
+ */
+ context->inputLen = 0;
+ return (0);
+}
+
+/* Assume input length is context->blockLen.
+ */
+static int RSA_CRT2
+ (context, output, outputLen, maxOutputLen, input, surrenderContext)
+A_RSA_CRT2_CTX *context;
+unsigned char *output;
+unsigned int *outputLen;
+unsigned int maxOutputLen;
+unsigned char *input;
+A_SURRENDER_CTX *surrenderContext;
+{
+ struct ModExpCRTFrame {
+ UINT2 bigInBuf[2 * MAX_RSA_PRIME_WORDS],
+ bigOutBuf[2 * MAX_RSA_PRIME_WORDS];
+ } *frame = (struct ModExpCRTFrame *)NULL_PTR;
+#if !USE_ALLOCED_FRAME
+ struct ModExpCRTFrame stackFrame;
+#endif
+ int status;
+
+ status = 0;
+ do {
+ if ((*outputLen = context->blockLen) > maxOutputLen)
+ return (AE_OUTPUT_LEN);
+
+#if USE_ALLOCED_FRAME
+ if ((frame = (struct ModExpCRTFrame *)T_malloc (sizeof (*frame)))
+ == (struct ModExpCRTFrame *)NULL_PTR) {
+ status = AE_ALLOC;
+ break;
+ }
+#else
+ /* Just use the buffers allocated on the stack. */
+ frame = &stackFrame;
+#endif
+
+ /* Convert input to bignum representation.
+ This won't return AE_DATA since input length was checked at Update.
+ */
+ CanonicalToBig
+ (frame->bigInBuf, 2 * context->primeWords, input, context->blockLen);
+
+ /* Check for overflow. */
+ if (BigCmp
+ (frame->bigInBuf, context->modulus, 2 * context->primeWords) >= 0)
+ GENERATE_BREAK (AE_INPUT_DATA);
+
+ /* Chinese remainder exponentiation. */
+ if ((status = BigUnexp
+ (frame->bigOutBuf, frame->bigInBuf, context->primeP, context->primeQ,
+ context->exponentP, context->exponentQ, context->coefficient,
+ context->primeWords, surrenderContext)) != 0)
+ break;
+
+ /* Convert output to canonical representation.
+ This won't return AE_DATA since outputLen was set above.
+ */
+ BigToCanonical
+ (output, *outputLen, frame->bigOutBuf, 2 * context->primeWords);
+ } while (0);
+
+ if (frame != (struct ModExpCRTFrame *)NULL_PTR) {
+ T_memset ((POINTER)frame, 0, sizeof (*frame));
+#if USE_ALLOCED_FRAME
+ T_free ((POINTER)frame);
+#endif
+ }
+ return (status);
+}
+
diff --git a/lib/dns/sec/dnssafe/crt2.h b/lib/dns/sec/dnssafe/crt2.h
new file mode 100644
index 00000000..4c5c0f7d
--- /dev/null
+++ b/lib/dns/sec/dnssafe/crt2.h
@@ -0,0 +1,50 @@
+/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _RSA_H_
+#define _RSA_H_ 1
+
+#include "bigmaxes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Note, these are only valid after a call to A_RSA_CRT2Init.
+ */
+#define A_RSA_CRT2_BLOCK_LEN(context) ((context)->blockLen)
+#define A_RSA_CRT2_MAX_OUTPUT_LEN(context, inputLen)\
+ (inputLen) + (((inputLen) % (context)->blockLen) ?\
+ (context)->blockLen - ((inputLen) % (context)->blockLen) : 0)
+
+typedef struct {
+ unsigned int blockLen; /* total size of the block to be computed */
+ unsigned char input[MAX_RSA_MODULUS_LEN];
+ unsigned int inputLen;
+ unsigned int primeWords;
+ UINT2 modulus[2 * MAX_RSA_PRIME_WORDS];
+ UINT2 primeP[MAX_RSA_PRIME_WORDS];
+ UINT2 primeQ[MAX_RSA_PRIME_WORDS];
+ UINT2 exponentP[MAX_RSA_PRIME_WORDS];
+ UINT2 exponentQ[MAX_RSA_PRIME_WORDS];
+ UINT2 coefficient[MAX_RSA_PRIME_WORDS];
+} A_RSA_CRT2_CTX;
+
+int A_RSA_CRT2Init PROTO_LIST ((A_RSA_CRT2_CTX *, A_RSA_CRT_KEY *));
+int A_RSA_CRT2Update PROTO_LIST
+ ((A_RSA_CRT2_CTX *, unsigned char *, unsigned int *, unsigned int,
+ unsigned char *, unsigned int, A_SURRENDER_CTX *));
+int A_RSA_CRT2Final PROTO_LIST ((A_RSA_CRT2_CTX *));
+void A_RSA_CRT2GetMaxOutputLen PROTO_LIST
+ ((A_RSA_CRT2_CTX *, unsigned int *, unsigned int));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/dns/sec/dnssafe/digest.c b/lib/dns/sec/dnssafe/digest.c
new file mode 100644
index 00000000..823fbc65
--- /dev/null
+++ b/lib/dns/sec/dnssafe/digest.c
@@ -0,0 +1,67 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "keyobj.h"
+#include "algobj.h"
+
+int B_DigestInit
+ (algorithmObject, keyObject, algorithmChooser, surrenderContext)
+B_ALGORITHM_OBJ algorithmObject;
+B_KEY_OBJ keyObject;
+B_ALGORITHM_CHOOSER algorithmChooser;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0)
+ return (status);
+ if ((status = KeyWrapCheck ((KeyWrap *)keyObject)) != 0)
+ return (status);
+
+ return (B_AlgorithmDigestInit
+ (&THE_ALG_WRAP->algorithm, &((KeyWrap *)keyObject)->key,
+ algorithmChooser, surrenderContext));
+}
+
+int B_DigestUpdate (algorithmObject, partIn, partInLen, surrenderContext)
+B_ALGORITHM_OBJ algorithmObject;
+unsigned char *partIn;
+unsigned int partInLen;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0)
+ return (status);
+
+ return (B_AlgorithmDigestUpdate
+ (&THE_ALG_WRAP->algorithm, partIn, partInLen, surrenderContext));
+}
+
+int B_DigestFinal
+ (algorithmObject, digest, digestLen, maxDigestLen, surrenderContext)
+B_ALGORITHM_OBJ algorithmObject;
+unsigned char *digest;
+unsigned int *digestLen;
+unsigned int maxDigestLen;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0)
+ return (status);
+
+ return (B_AlgorithmDigestFinal
+ (&THE_ALG_WRAP->algorithm, digest, digestLen, maxDigestLen,
+ surrenderContext));
+}
+
diff --git a/lib/dns/sec/dnssafe/digrand.c b/lib/dns/sec/dnssafe/digrand.c
new file mode 100644
index 00000000..e6f9016e
--- /dev/null
+++ b/lib/dns/sec/dnssafe/digrand.c
@@ -0,0 +1,88 @@
+/* Copyright (C) RSA Data Security, Inc. created 1992, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "algae.h"
+#include "digrand.h"
+
+/* Calling routine must initialize the digest algorithm and set
+ digestRandom->vTable.
+ digestLen is the length of the output of the digest algorithm (i.e. 16).
+ state must point to an unsigned char * array of 3 * digestLen.
+ */
+void A_DigestRandomInit (digestRandom, digestLen, state)
+A_DigestRandom *digestRandom;
+unsigned int digestLen;
+unsigned char *state;
+{
+ digestRandom->_state = state;
+ digestRandom->_output = state + digestLen;
+ digestRandom->_digest = digestRandom->_output + digestLen;
+
+ digestRandom->_outputAvailable = 0;
+ digestRandom->_digestLen = digestLen;
+
+ T_memset ((POINTER)digestRandom->_state, 0, digestLen);
+}
+
+void A_DigestRandomUpdate (digestRandom, input, inputLen)
+A_DigestRandom *digestRandom;
+unsigned char *input;
+unsigned int inputLen;
+{
+ unsigned int i, j, x;
+
+ (*digestRandom->vTable->DigestUpdate) (digestRandom, input, inputLen);
+ (*digestRandom->vTable->DigestFinal) (digestRandom, digestRandom->_digest);
+
+ /* add digest to state */
+ x = 0;
+ for (i = 0; i < digestRandom->_digestLen; i++) {
+ j = digestRandom->_digestLen-1-i;
+ x += digestRandom->_state[j] + digestRandom->_digest[j];
+ digestRandom->_state[j] = (unsigned char)x;
+ x >>= 8;
+ }
+}
+
+void A_DigestRandomGenerateBytes (digestRandom, output, outputLen)
+A_DigestRandom *digestRandom;
+unsigned char *output;
+unsigned int outputLen;
+{
+ unsigned int available, i;
+
+ available = digestRandom->_outputAvailable;
+
+ while (outputLen > available) {
+ T_memcpy
+ ((POINTER)output,
+ (POINTER)&digestRandom->_output[digestRandom->_digestLen-available],
+ available);
+ output += available;
+ outputLen -= available;
+
+ /* generate new output */
+ (*digestRandom->vTable->DigestUpdate)
+ (digestRandom, digestRandom->_state, digestRandom->_digestLen);
+ (*digestRandom->vTable->DigestFinal) (digestRandom, digestRandom->_output);
+ available = digestRandom->_digestLen;
+
+ /* increment state */
+ for (i = 0; i < digestRandom->_digestLen; i++)
+ if (digestRandom->_state[digestRandom->_digestLen-1-i]++)
+ break;
+ }
+
+ T_memcpy
+ ((POINTER)output,
+ (POINTER)&digestRandom->_output[digestRandom->_digestLen-available],
+ outputLen);
+ digestRandom->_outputAvailable = available - outputLen;
+}
+
diff --git a/lib/dns/sec/dnssafe/digrand.h b/lib/dns/sec/dnssafe/digrand.h
new file mode 100644
index 00000000..6753c9cf
--- /dev/null
+++ b/lib/dns/sec/dnssafe/digrand.h
@@ -0,0 +1,53 @@
+/* Copyright (C) RSA Data Security, Inc. created 1992, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _DIGRAND_H_
+#define _DIGRAND_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Use the THIS_DIGEST_RANDOM macro to define the type of object in the
+ virtual function prototype. It defaults to the most base class, but
+ derived modules may define the macro to a more derived class before
+ including this header file.
+ */
+#ifndef THIS_DIGEST_RANDOM
+#define THIS_DIGEST_RANDOM struct A_DigestRandom
+#endif
+
+struct A_DigestRandom;
+
+typedef struct {
+ void (*DigestUpdate) PROTO_LIST
+ ((THIS_DIGEST_RANDOM *, unsigned char *, unsigned int));
+ void (*DigestFinal) PROTO_LIST ((THIS_DIGEST_RANDOM *, unsigned char *));
+} A_DigestRandomVTable;
+
+typedef struct A_DigestRandom {
+ unsigned char *_state; /* input to digest */
+ unsigned char *_output; /* current output of digest */
+ unsigned int _outputAvailable;
+ unsigned char *_digest;
+ unsigned int _digestLen;
+ A_DigestRandomVTable *vTable;
+} A_DigestRandom;
+
+void A_DigestRandomInit PROTO_LIST
+ ((A_DigestRandom *, unsigned int, unsigned char *));
+void A_DigestRandomUpdate PROTO_LIST
+ ((A_DigestRandom *, unsigned char *, unsigned int));
+void A_DigestRandomGenerateBytes PROTO_LIST
+ ((A_DigestRandom *, unsigned char *, unsigned int));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/dns/sec/dnssafe/encrypt.c b/lib/dns/sec/dnssafe/encrypt.c
new file mode 100644
index 00000000..e7995b4d
--- /dev/null
+++ b/lib/dns/sec/dnssafe/encrypt.c
@@ -0,0 +1,147 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "keyobj.h"
+#include "algobj.h"
+
+int B_EncryptInit
+ (algorithmObject, keyObject, algorithmChooser, surrenderContext)
+B_ALGORITHM_OBJ algorithmObject;
+B_KEY_OBJ keyObject;
+B_ALGORITHM_CHOOSER algorithmChooser;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0)
+ return (status);
+ if ((status = KeyWrapCheck ((KeyWrap *)keyObject)) != 0)
+ return (status);
+
+ return (B_AlgorithmEncryptInit
+ (&THE_ALG_WRAP->algorithm, &((KeyWrap *)keyObject)->key,
+ algorithmChooser, surrenderContext));
+}
+
+int B_EncryptUpdate
+ (algorithmObject, partOut, partOutLen, maxPartOutLen, partIn, partInLen,
+ randomAlgorithm, surrenderContext)
+B_ALGORITHM_OBJ algorithmObject;
+unsigned char *partOut;
+unsigned int *partOutLen;
+unsigned int maxPartOutLen;
+unsigned char *partIn;
+unsigned int partInLen;
+B_ALGORITHM_OBJ randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0)
+ return (status);
+ if ((status = RandomAlgorithmCheck (randomAlgorithm)) != 0)
+ return (status);
+
+ return (B_AlgorithmEncryptUpdate
+ (&THE_ALG_WRAP->algorithm, partOut, partOutLen, maxPartOutLen,
+ partIn, partInLen,
+ &((AlgorithmWrap *)randomAlgorithm)->algorithm, surrenderContext));
+}
+
+int B_EncryptFinal
+ (algorithmObject, partOut, partOutLen, maxPartOutLen, randomAlgorithm,
+ surrenderContext)
+B_ALGORITHM_OBJ algorithmObject;
+unsigned char *partOut;
+unsigned int *partOutLen;
+unsigned int maxPartOutLen;
+B_ALGORITHM_OBJ randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0)
+ return (status);
+ if ((status = RandomAlgorithmCheck (randomAlgorithm)) != 0)
+ return (status);
+
+ return (B_AlgorithmEncryptFinal
+ (&THE_ALG_WRAP->algorithm, partOut, partOutLen, maxPartOutLen,
+ &((AlgorithmWrap *)randomAlgorithm)->algorithm, surrenderContext));
+}
+
+int B_DecryptInit
+ (algorithmObject, keyObject, algorithmChooser, surrenderContext)
+B_ALGORITHM_OBJ algorithmObject;
+B_KEY_OBJ keyObject;
+B_ALGORITHM_CHOOSER algorithmChooser;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0)
+ return (status);
+ if ((status = KeyWrapCheck ((KeyWrap *)keyObject)) != 0)
+ return (status);
+
+ return (B_AlgorithmDecryptInit
+ (&THE_ALG_WRAP->algorithm, &((KeyWrap *)keyObject)->key,
+ algorithmChooser, surrenderContext));
+}
+
+int B_DecryptUpdate
+ (algorithmObject, partOut, partOutLen, maxPartOutLen, partIn, partInLen,
+ randomAlgorithm, surrenderContext)
+B_ALGORITHM_OBJ algorithmObject;
+unsigned char *partOut;
+unsigned int *partOutLen;
+unsigned int maxPartOutLen;
+unsigned char *partIn;
+unsigned int partInLen;
+B_ALGORITHM_OBJ randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0)
+ return (status);
+ if ((status = RandomAlgorithmCheck (randomAlgorithm)) != 0)
+ return (status);
+
+ return (B_AlgorithmDecryptUpdate
+ (&THE_ALG_WRAP->algorithm, partOut, partOutLen, maxPartOutLen,
+ partIn, partInLen,
+ &((AlgorithmWrap *)randomAlgorithm)->algorithm, surrenderContext));
+}
+
+int B_DecryptFinal
+ (algorithmObject, partOut, partOutLen, maxPartOutLen, randomAlgorithm,
+ surrenderContext)
+B_ALGORITHM_OBJ algorithmObject;
+unsigned char *partOut;
+unsigned int *partOutLen;
+unsigned int maxPartOutLen;
+B_ALGORITHM_OBJ randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0)
+ return (status);
+ if ((status = RandomAlgorithmCheck (randomAlgorithm)) != 0)
+ return (status);
+
+ return (B_AlgorithmDecryptFinal
+ (&THE_ALG_WRAP->algorithm, partOut, partOutLen, maxPartOutLen,
+ &((AlgorithmWrap *)randomAlgorithm)->algorithm, surrenderContext));
+}
+
diff --git a/lib/dns/sec/dnssafe/generate.c b/lib/dns/sec/dnssafe/generate.c
new file mode 100644
index 00000000..76069370
--- /dev/null
+++ b/lib/dns/sec/dnssafe/generate.c
@@ -0,0 +1,78 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "ainfotyp.h"
+#include "keyobj.h"
+#include "algobj.h"
+
+int B_GenerateInit (algorithmObject, algorithmChooser, surrenderContext)
+B_ALGORITHM_OBJ algorithmObject;
+B_ALGORITHM_CHOOSER algorithmChooser;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0)
+ return (status);
+
+ return (B_AlgorithmGenerateInit
+ (&THE_ALG_WRAP->algorithm, algorithmChooser, surrenderContext));
+}
+
+int B_GenerateKeypair
+ (algorithmObject, publicKey, privateKey, randomAlgorithm, surrenderContext)
+B_ALGORITHM_OBJ algorithmObject;
+B_KEY_OBJ publicKey;
+B_KEY_OBJ privateKey;
+B_ALGORITHM_OBJ randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0)
+ return (status);
+ if ((status = KeyWrapCheck ((KeyWrap *)publicKey)) != 0)
+ return (status);
+ if ((status = KeyWrapCheck ((KeyWrap *)privateKey)) != 0)
+ return (status);
+ if ((status = RandomAlgorithmCheck (randomAlgorithm)) != 0)
+ return (status);
+
+ return (B_AlgorithmGenerateKeypair
+ (&THE_ALG_WRAP->algorithm, &((KeyWrap *)publicKey)->key,
+ &((KeyWrap *)privateKey)->key,
+ &((AlgorithmWrap *)randomAlgorithm)->algorithm, surrenderContext));
+}
+
+int B_GenerateParameters
+ (algorithmObject, resultAlgorithmObject, randomAlgorithm, surrenderContext)
+B_ALGORITHM_OBJ algorithmObject;
+B_ALGORITHM_OBJ resultAlgorithmObject;
+B_ALGORITHM_OBJ randomAlgorithm;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+
+ if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0)
+ return (status);
+ if ((status = AlgorithmWrapCheck ((AlgorithmWrap *)resultAlgorithmObject))
+ != 0)
+ return (status);
+ if ((status = RandomAlgorithmCheck (randomAlgorithm)) != 0)
+ return (status);
+
+ return (B_AlgorithmGenerateParameters
+ (&THE_ALG_WRAP->algorithm,
+ &((AlgorithmWrap *)resultAlgorithmObject)->algorithm,
+ &((AlgorithmWrap *)randomAlgorithm)->algorithm, surrenderContext));
+}
+
diff --git a/lib/dns/sec/dnssafe/global.h b/lib/dns/sec/dnssafe/global.h
new file mode 100644
index 00000000..e95ac180
--- /dev/null
+++ b/lib/dns/sec/dnssafe/global.h
@@ -0,0 +1,60 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _GLOBAL_H_
+#define _GLOBAL_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* PROTOTYPES should be set to one if and only if the compiler supports
+ function argument prototyping.
+ The following makes PROTOTYPES default to 1 if it has not already been
+ defined as 0 with C compiler flags.
+ */
+#ifndef PROTOTYPES
+#define PROTOTYPES 1
+#endif
+
+#include <config.h>
+#include <isc/int.h>
+#include <sys/types.h>
+
+/* POINTER defines a generic pointer type */
+typedef unsigned char *POINTER;
+
+/* UINT2 defines a two byte word */
+typedef isc_uint16_t UINT2;
+
+/* UINT4 defines a four byte word */
+typedef isc_uint32_t UINT4;
+
+#ifndef NULL_PTR
+#define NULL_PTR ((POINTER)0)
+#endif
+
+#ifndef UNUSED_ARG
+#define UNUSED_ARG(x) x = *(&x);
+#endif
+
+/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
+ If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
+ returns an empty list.
+ */
+#if PROTOTYPES
+#define PROTO_LIST(list) list
+#else
+#define PROTO_LIST(list) ()
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end _GLOBAL_H_ */
diff --git a/lib/dns/sec/dnssafe/intbits.c b/lib/dns/sec/dnssafe/intbits.c
new file mode 100644
index 00000000..6a60e22a
--- /dev/null
+++ b/lib/dns/sec/dnssafe/intbits.c
@@ -0,0 +1,32 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "algae.h"
+
+/* Return the number of bits in the canonical, positive integer.
+ IntgerBits (0) = 0.
+ */
+unsigned int A_IntegerBits (integer, integerLen)
+unsigned char *integer;
+unsigned int integerLen;
+{
+ unsigned char mask, byte;
+ unsigned int bytes, bits;
+
+ for (bytes = 0; bytes < integerLen && integer[bytes] == 0; bytes++);
+ if (bytes == integerLen)
+ return (0);
+
+ /* Get byte to test and increment byte count for final calculation */
+ byte = integer[bytes++];
+
+ /* Get number of bits in most significant byte */
+ for (bits = 8, mask = 0x80; (byte & mask) == 0; bits--, mask >>= 1);
+ return (8 * (integerLen - bytes) + bits);
+}
diff --git a/lib/dns/sec/dnssafe/intitem.c b/lib/dns/sec/dnssafe/intitem.c
new file mode 100644
index 00000000..a9bcc7e8
--- /dev/null
+++ b/lib/dns/sec/dnssafe/intitem.c
@@ -0,0 +1,54 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bmempool.h"
+#include "intitem.h"
+
+/* Copy itemCount ITEMs from source to destination, allocating new
+ memory in the memoryPool.
+ Each ITEM is a canonical integer, and is stripped of leading zeros.
+ Use the list of staticItems as a template. Each of the staticItems
+ points to the ITEM within the staticStruct, which is a structure
+ of the same format as destination and source.
+ Returns 0, BE_ALLOC.
+ */
+int AllocAndCopyIntegerItems
+ (destination, source, staticStruct, staticItems, itemCount, memoryPool)
+POINTER destination;
+POINTER source;
+POINTER staticStruct;
+ITEM **staticItems;
+unsigned int itemCount;
+B_MemoryPool *memoryPool;
+{
+ ITEM sourceItem, *destinationItem;
+ int status;
+ unsigned int i, offset;
+
+ for (i = 0; i < itemCount; i++) {
+ offset = (unsigned int)((char *)staticItems[i] - (char *)staticStruct);
+ sourceItem = *(ITEM *)((char *)source + offset);
+ destinationItem = (ITEM *)((char *)destination + offset);
+
+ while (sourceItem.len > 0 && *sourceItem.data == 0) {
+ sourceItem.len--;
+ sourceItem.data++;
+ }
+
+ if ((status = B_MemoryPoolAllocAndCopy
+ (memoryPool, (POINTER *)&destinationItem->data,
+ (POINTER)sourceItem.data, destinationItem->len = sourceItem.len))
+ != 0)
+ return (status);
+ }
+
+ return (0);
+}
+
diff --git a/lib/dns/sec/dnssafe/intitem.h b/lib/dns/sec/dnssafe/intitem.h
new file mode 100644
index 00000000..05cb2fc1
--- /dev/null
+++ b/lib/dns/sec/dnssafe/intitem.h
@@ -0,0 +1,11 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+int AllocAndCopyIntegerItems PROTO_LIST
+ ((POINTER, POINTER, POINTER, ITEM **, unsigned int, B_MemoryPool *));
+
diff --git a/lib/dns/sec/dnssafe/keyobj.c b/lib/dns/sec/dnssafe/keyobj.c
new file mode 100644
index 00000000..4dd5d77c
--- /dev/null
+++ b/lib/dns/sec/dnssafe/keyobj.c
@@ -0,0 +1,113 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "kinfotyp.h"
+#include "keyobj.h"
+
+#define THE_KEY_WRAP ((KeyWrap *)keyObject)
+
+static char KEY_TYPE_TAG = 0;
+
+int B_CreateKeyObject (keyObject)
+B_KEY_OBJ *keyObject;
+{
+ KeyWrap *keyWrap;
+
+ if ((*keyObject = T_malloc (sizeof (*keyWrap))) == NULL_PTR)
+ return (BE_ALLOC);
+
+ keyWrap = (KeyWrap *)*keyObject;
+
+ /* First construct base class */
+ B_KEY_Constructor (&keyWrap->key);
+
+ keyWrap->typeTag = &KEY_TYPE_TAG;
+ keyWrap->selfCheck = keyWrap;
+ return (0);
+}
+
+void B_DestroyKeyObject (keyObject)
+B_KEY_OBJ *keyObject;
+{
+ KeyWrap *keyWrap = (KeyWrap *)*keyObject;
+
+ /* Need to explicitly check for NULL_PTR since KeyWrapCheck does not.
+ */
+ if (*keyObject == NULL_PTR)
+ return;
+
+ if (KeyWrapCheck (keyWrap) == 0) {
+ /* zeroize self check to invalidate memory. */
+ keyWrap->selfCheck = (KeyWrap *)NULL_PTR;
+
+ /* Call base class descructor */
+ B_KEY_Destructor (&keyWrap->key);
+
+ T_free ((POINTER)keyWrap);
+ }
+
+ *keyObject = NULL_PTR;
+}
+
+int B_SetKeyInfo (keyObject, infoType, info)
+B_KEY_OBJ keyObject;
+B_INFO_TYPE infoType;
+POINTER info;
+{
+ B_KeyInfoType *keyInfoType;
+ int status;
+
+ if ((status = KeyWrapCheck (THE_KEY_WRAP)) != 0)
+ return (status);
+
+ /* Get the KeyInfoType from the B_INFO_TYPE, which returns
+ zero for an AlgorithmInfoType, non-zero for KeyInfoType
+ */
+ if ((*infoType) ((POINTER *)&keyInfoType) == 0)
+ return (BE_ALG_OPERATION_UNKNOWN);
+
+ return (B_KeySetInfo (&THE_KEY_WRAP->key, keyInfoType, info));
+}
+
+int B_GetKeyInfo (info, keyObject, infoType)
+POINTER *info;
+B_KEY_OBJ keyObject;
+B_INFO_TYPE infoType;
+{
+ B_KeyInfoType *keyInfoType;
+ int status;
+
+ if ((status = KeyWrapCheck (THE_KEY_WRAP)) != 0)
+ return (status);
+
+ /* Get the KeyInfoType from the B_INFO_TYPE, which returns
+ zero for an AlgorithmInfoType, non-zero for KeyInfoType
+ */
+ if ((*infoType) ((POINTER *)&keyInfoType) == 0)
+ return (BE_ALG_OPERATION_UNKNOWN);
+
+ return (B_KeyGetInfo (&THE_KEY_WRAP->key, info, keyInfoType));
+}
+
+/* Return 0 if this is a valid KeyWrap object, else BE_KEY_OBJ.
+ If keyWrap is NULL_PTR, return 0 and expect the lower routines
+ to check for NULL.
+ */
+int KeyWrapCheck (keyWrap)
+KeyWrap *keyWrap;
+{
+ if (keyWrap == (KeyWrap *)NULL_PTR)
+ return (0);
+
+ return ((keyWrap->selfCheck == keyWrap && keyWrap->typeTag == &KEY_TYPE_TAG)
+ ? 0 : BE_KEY_OBJ);
+}
+
diff --git a/lib/dns/sec/dnssafe/keyobj.h b/lib/dns/sec/dnssafe/keyobj.h
new file mode 100644
index 00000000..b7f582f8
--- /dev/null
+++ b/lib/dns/sec/dnssafe/keyobj.h
@@ -0,0 +1,16 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+typedef struct KeyWrap {
+ B_Key key;
+ char *typeTag;
+ struct KeyWrap *selfCheck;
+} KeyWrap;
+
+int KeyWrapCheck PROTO_LIST ((KeyWrap *));
+
diff --git a/lib/dns/sec/dnssafe/ki8byte.c b/lib/dns/sec/dnssafe/ki8byte.c
new file mode 100644
index 00000000..306cc7b1
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ki8byte.c
@@ -0,0 +1,70 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "kinfotyp.h"
+#include "kiitem.h"
+#include "ki8byte.h"
+
+int KIT_8ByteAddInfo PROTO_LIST ((B_Key *, POINTER));
+int KIT_8ByteMakeInfo PROTO_LIST ((POINTER *, B_Key *));
+
+B_KeyInfoType KIT_8Byte = {KIT_8ByteAddInfo, KIT_8ByteMakeInfo};
+
+int KI_8Byte (keyInfoType)
+POINTER *keyInfoType;
+{
+ *keyInfoType = (POINTER)&KIT_8Byte;
+
+ /* Return 1 to indicate a KeyInfoType, not an AlgorithmInfoType */
+ return (1);
+}
+
+/* info points to 8 byte key.
+ Cache as a KITItem and a KIT_8Byte.
+ */
+int KIT_8ByteAddInfo (key, info)
+B_Key *key;
+POINTER info;
+{
+ POINTER newData;
+ int status;
+
+ /* Copy the 8 byte key. */
+ if ((status = B_MemoryPoolAllocAndCopy
+ (&key->infoCache.memoryPool, &newData, info, 8)) != 0)
+ return (status);
+
+ /* Cache as a KITItem as well as KIT_8Byte.
+ */
+ if ((status = B_KeyAddItemInfo (key, (unsigned char *)newData, 8)) != 0)
+ return (status);
+ return (B_InfoCacheAddInfo (&key->infoCache, (POINTER)&KIT_8Byte, newData));
+}
+
+int KIT_8ByteMakeInfo (info, key)
+POINTER *info;
+B_Key *key;
+{
+ ITEM *item;
+ int status;
+
+ /* Try to make one from a KI_Item. Since KI_Item doesn't
+ call KI_8Byte, this should not cause an endless loop.
+ */
+ if ((status = B_KeyGetInfo (key, (POINTER *)&item, &KITItem)) != 0)
+ return (status);
+ if (item->len != 8)
+ return (BE_WRONG_KEY_INFO);
+
+ *(unsigned char **)info = item->data;
+ return (0);
+}
+
diff --git a/lib/dns/sec/dnssafe/ki8byte.h b/lib/dns/sec/dnssafe/ki8byte.h
new file mode 100644
index 00000000..1c78bb12
--- /dev/null
+++ b/lib/dns/sec/dnssafe/ki8byte.h
@@ -0,0 +1,9 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+extern B_KeyInfoType KIT_8Byte;
diff --git a/lib/dns/sec/dnssafe/kifulprv.c b/lib/dns/sec/dnssafe/kifulprv.c
new file mode 100644
index 00000000..be358352
--- /dev/null
+++ b/lib/dns/sec/dnssafe/kifulprv.c
@@ -0,0 +1,151 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "kinfotyp.h"
+#include "kifulprv.h"
+
+typedef struct {
+ ITEM modulus; /* modulus */
+ ITEM publicExponent; /* exponent for the public key */
+ ITEM privateExponent; /* exponent for the private key */
+ ITEM prime[2]; /* prime factors */
+ ITEM primeExponent[2]; /* exponents for prime factors */
+ ITEM coefficient; /* CRT coefficient */
+} FULL_PRIVATE_KEY;
+
+static int KITFullPrivateKeyAddInfo PROTO_LIST ((B_Key *, POINTER));
+
+static B_KeyInfoType KITFullPrivate =
+ {KITFullPrivateKeyAddInfo, B_KeyInfoTypeMakeError};
+
+/* Create a FULL_PRIVATE_KEY value and only copy inthe entries
+ that are not (ITEM *)NULL_PTR.
+ primes and primeExponents point to a 2 entry ITEM array.
+ */
+int CacheFullPrivateKey
+ (key, modulus, publicExponent, privateExponent, primes,
+ primeExponents, coefficient)
+B_Key *key;
+ITEM *modulus;
+ITEM *publicExponent;
+ITEM *privateExponent;
+ITEM *primes;
+ITEM *primeExponents;
+ITEM *coefficient;
+{
+ FULL_PRIVATE_KEY *fullKey;
+ int status;
+
+ /* Allocate memory for FULL_PRIVATE_KEY value.
+ */
+ if ((status = B_MemoryPoolAlloc
+ (&key->infoCache.memoryPool, (POINTER *)&fullKey,
+ sizeof (FULL_PRIVATE_KEY))) != 0)
+ return (status);
+
+ /* Pre-zeroize and only copy in values that are not NULL.
+ */
+ T_memset ((POINTER)fullKey, 0, sizeof (*fullKey));
+ if (modulus != (ITEM *)NULL_PTR)
+ fullKey->modulus = *modulus;
+ if (publicExponent != (ITEM *)NULL_PTR)
+ fullKey->publicExponent = *publicExponent;
+ if (privateExponent != (ITEM *)NULL_PTR)
+ fullKey->privateExponent = *privateExponent;
+ if (primes != (ITEM *)NULL_PTR) {
+ fullKey->prime[0] = primes[0];
+ fullKey->prime[1] = primes[1];
+ }
+ if (primeExponents != (ITEM *)NULL_PTR) {
+ fullKey->primeExponent[0] = primeExponents[0];
+ fullKey->primeExponent[1] = primeExponents[1];
+ }
+ if (coefficient != (ITEM *)NULL_PTR)
+ fullKey->coefficient = *coefficient;
+
+ return (B_InfoCacheAddInfo
+ (&key->infoCache, (POINTER)&KITFullPrivate, (POINTER)fullKey));
+}
+
+/* Select the key object's full private key and set all of the supplied
+ fields which are not (ITEM *)NULL_PTR.
+ primes and primeExponents point to a 2 entry ITEM array.
+ If one of the fields is not (ITEM *)NULL_PTR, but the full key's
+ field is null, return BE_WRONG_KEY_INFO.
+ */
+int GetFullPrivateKeyInfo
+ (modulus, publicExponent, privateExponent, primes, primeExponents,
+ coefficient, key)
+ITEM *modulus;
+ITEM *publicExponent;
+ITEM *privateExponent;
+ITEM *primes;
+ITEM *primeExponents;
+ITEM *coefficient;
+B_Key *key;
+{
+ FULL_PRIVATE_KEY *fullKey;
+ int status;
+
+ if ((status = B_KeyGetInfo
+ (key, (POINTER *)&fullKey, &KITFullPrivate)) != 0)
+ return (status);
+
+ if (modulus != (ITEM *)NULL_PTR) {
+ if (fullKey->modulus.data == (unsigned char *)NULL_PTR)
+ return (BE_WRONG_KEY_INFO);
+ *modulus = fullKey->modulus;
+ }
+ if (publicExponent != (ITEM *)NULL_PTR) {
+ if (fullKey->publicExponent.data == (unsigned char *)NULL_PTR)
+ return (BE_WRONG_KEY_INFO);
+ *publicExponent = fullKey->publicExponent;
+ }
+ if (privateExponent != (ITEM *)NULL_PTR) {
+ if (fullKey->privateExponent.data == (unsigned char *)NULL_PTR)
+ return (BE_WRONG_KEY_INFO);
+ *privateExponent = fullKey->privateExponent;
+ }
+ if (primes != (ITEM *)NULL_PTR) {
+ if (fullKey->prime[0].data == (unsigned char *)NULL_PTR ||
+ fullKey->prime[1].data == (unsigned char *)NULL_PTR)
+ return (BE_WRONG_KEY_INFO);
+ primes[0] = fullKey->prime[0];
+ primes[1] = fullKey->prime[1];
+ }
+ if (primeExponents != (ITEM *)NULL_PTR) {
+ if (fullKey->primeExponent[0].data == (unsigned char *)NULL_PTR ||
+ fullKey->primeExponent[1].data == (unsigned char *)NULL_PTR)
+ return (BE_WRONG_KEY_INFO);
+ primeExponents[0] = fullKey->primeExponent[0];
+ primeExponents[1] = fullKey->primeExponent[1];
+ }
+ if (coefficient != (ITEM *)NULL_PTR) {
+ if (fullKey->coefficient.data == (unsigned char *)NULL_PTR)
+ return (BE_WRONG_KEY_INFO);
+ *coefficient = fullKey->coefficient;
+ }
+
+ return (0);
+}
+
+/* This is not intended to be called from B_SetKeyInfo.
+ Get returns BE_WRONG_KEY_INFO.
+ */
+static int KITFullPrivateKeyAddInfo (key, info)
+B_Key *key;
+POINTER info;
+{
+UNUSED_ARG (key)
+UNUSED_ARG (info)
+ return (BE_ALG_OPERATION_UNKNOWN);
+}
+
diff --git a/lib/dns/sec/dnssafe/kifulprv.h b/lib/dns/sec/dnssafe/kifulprv.h
new file mode 100644
index 00000000..8e469ce9
--- /dev/null
+++ b/lib/dns/sec/dnssafe/kifulprv.h
@@ -0,0 +1,12 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+int CacheFullPrivateKey PROTO_LIST
+ ((B_Key *, ITEM *, ITEM *, ITEM *, ITEM *, ITEM *, ITEM *));
+int GetFullPrivateKeyInfo PROTO_LIST
+ ((ITEM *, ITEM *, ITEM *, ITEM *, ITEM *, ITEM *, B_Key *));
diff --git a/lib/dns/sec/dnssafe/kiitem.c b/lib/dns/sec/dnssafe/kiitem.c
new file mode 100644
index 00000000..9c44d8f1
--- /dev/null
+++ b/lib/dns/sec/dnssafe/kiitem.c
@@ -0,0 +1,44 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "kinfotyp.h"
+#include "kiitem.h"
+
+int KITItemAddInfo PROTO_LIST ((B_Key *, POINTER));
+
+B_KeyInfoType KITItem = {KITItemAddInfo, B_KeyInfoTypeMakeError};
+
+int KI_Item (keyInfoType)
+POINTER *keyInfoType;
+{
+ *keyInfoType = (POINTER)&KITItem;
+
+ /* Return 1 to indicate a KeyInfoType, not an AlgorithmInfoType */
+ return (1);
+}
+
+/* info is an ITEM. The ITEM's data is copied into the object.
+ */
+int KITItemAddInfo (key, info)
+B_Key *key;
+POINTER info;
+{
+ unsigned char *newData;
+ int status;
+
+ if ((status = B_MemoryPoolAllocAndCopy
+ (&key->infoCache.memoryPool, (POINTER *)&newData,
+ (POINTER)((ITEM *)info)->data, ((ITEM *)info)->len)) != 0)
+ return (status);
+
+ return (B_KeyAddItemInfo (key, newData, ((ITEM *)info)->len));
+}
+
diff --git a/lib/dns/sec/dnssafe/kiitem.h b/lib/dns/sec/dnssafe/kiitem.h
new file mode 100644
index 00000000..ab80ceee
--- /dev/null
+++ b/lib/dns/sec/dnssafe/kiitem.h
@@ -0,0 +1,9 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+extern B_KeyInfoType KITItem;
diff --git a/lib/dns/sec/dnssafe/kinfotyp.c b/lib/dns/sec/dnssafe/kinfotyp.c
new file mode 100644
index 00000000..fdb3338f
--- /dev/null
+++ b/lib/dns/sec/dnssafe/kinfotyp.c
@@ -0,0 +1,26 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "kinfotyp.h"
+
+/* This is the default routine which key info types can point MakeInfo to.
+ */
+int B_KeyInfoTypeMakeError (info, key)
+POINTER *info;
+B_Key *key;
+{
+UNUSED_ARG (info)
+UNUSED_ARG (key)
+
+ /* Should already have been found in the cache. */
+ return (BE_WRONG_KEY_INFO);
+}
+
diff --git a/lib/dns/sec/dnssafe/kinfotyp.h b/lib/dns/sec/dnssafe/kinfotyp.h
new file mode 100644
index 00000000..3f6ce7c1
--- /dev/null
+++ b/lib/dns/sec/dnssafe/kinfotyp.h
@@ -0,0 +1,57 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+typedef int (*KIT_ADD_INFO) PROTO_LIST ((B_Key *, POINTER));
+typedef int (*KIT_MAKE_INFO) PROTO_LIST ((POINTER *, B_Key *));
+
+/* The definition in C++ is:
+ class B_KeyInfoType {
+ public:
+ B_KeyInfoType (KIT_ADD_INFO AddInfo) {
+ _AddInfo = AddInfo;
+ _MakeInfo = KeyInfoType::makeError;}
+ B_KeyInfoType (KIT_ADD_INFO AddInfo, KIT_MAKE_INFO MakeInfo) {
+ _AddInfo = AddInfo;
+ _MakeInfo = MakeInfo;}
+
+ int addInfo (B_Key *key, POINTER info) {return (*_AddInfo) (key, info);}
+ int makeInfo (POINTER *info, B_Key *key) {return (*_MakeInfo) (info, key);}
+
+ static int makeError (POINTER *info, B_Key *key);
+
+ private:
+ KIT_ADD_INFO _AddInfo;
+ KIT_MAKE_INFO _MakeInfo;
+ };
+
+ Note that a derived class simply calls one of the B_KeyInfoType constructors
+ which set the addInfo or both the addInfo and makeInfo callbacks.
+ There is no need for an extra level involving virtual functions because
+ each key class only has one instance, making a V table a waste of space.
+ An example of a derived class is:
+
+ class KITItem : public B_KeyInfoType {
+ public:
+ // Set addInfo and leave makeInfo as B_KeyInfoType::makeError
+ KITItem () : B_KeyInfoType (KITItem::addInfo) {};
+
+ static int addInfo (B_Key *key, POINTER info);
+ };
+
+
+ There is one global instance which is used by B_Key::setInfo, etc.:
+
+ KITItem KITItem;
+ */
+
+typedef struct B_KeyInfoType {
+ KIT_ADD_INFO AddInfo;
+ KIT_MAKE_INFO MakeInfo;
+} B_KeyInfoType;
+
+int B_KeyInfoTypeMakeError PROTO_LIST ((POINTER *, B_Key *));
diff --git a/lib/dns/sec/dnssafe/kipkcrpr.c b/lib/dns/sec/dnssafe/kipkcrpr.c
new file mode 100644
index 00000000..50c08edb
--- /dev/null
+++ b/lib/dns/sec/dnssafe/kipkcrpr.c
@@ -0,0 +1,100 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "kinfotyp.h"
+#include "intitem.h"
+#include "kifulprv.h"
+#include "kipkcrpr.h"
+
+B_KeyInfoType KIT_PKCS_RSAPrivate =
+ {KIT_PKCS_RSAPrivateAddInfo, KIT_PKCS_RSAPrivateMakeInfo};
+
+static A_PKCS_RSA_PRIVATE_KEY STATIC_PKCS_RSA_PRIVATE_KEY;
+static ITEM *PKCS_RSA_PRIVATE_KEY_ITEMS[] = {
+ &STATIC_PKCS_RSA_PRIVATE_KEY.modulus,
+ &STATIC_PKCS_RSA_PRIVATE_KEY.publicExponent,
+ &STATIC_PKCS_RSA_PRIVATE_KEY.privateExponent,
+ &STATIC_PKCS_RSA_PRIVATE_KEY.prime[0],
+ &STATIC_PKCS_RSA_PRIVATE_KEY.prime[1],
+ &STATIC_PKCS_RSA_PRIVATE_KEY.primeExponent[0],
+ &STATIC_PKCS_RSA_PRIVATE_KEY.primeExponent[1],
+ &STATIC_PKCS_RSA_PRIVATE_KEY.coefficient
+};
+
+int KI_PKCS_RSAPrivate (keyInfoType)
+POINTER *keyInfoType;
+{
+ *keyInfoType = (POINTER)&KIT_PKCS_RSAPrivate;
+
+ /* Return 1 to indicate a KeyInfoType, not an AlgorithmInfoType */
+ return (1);
+}
+
+int KIT_PKCS_RSAPrivateAddInfo (key, info)
+B_Key *key;
+POINTER info;
+{
+ A_PKCS_RSA_PRIVATE_KEY *newValue;
+ int status;
+
+ /* Allocate memory for A_PKCS_RSA_PRIVATE_KEY struct and copy integers
+ from supplied value.
+ */
+ if ((status = B_MemoryPoolAlloc
+ (&key->infoCache.memoryPool, (POINTER *)&newValue,
+ sizeof (A_PKCS_RSA_PRIVATE_KEY))) != 0)
+ return (status);
+ if ((status = AllocAndCopyIntegerItems
+ ((POINTER)newValue, info, (POINTER)&STATIC_PKCS_RSA_PRIVATE_KEY,
+ PKCS_RSA_PRIVATE_KEY_ITEMS, sizeof (PKCS_RSA_PRIVATE_KEY_ITEMS) /
+ sizeof (PKCS_RSA_PRIVATE_KEY_ITEMS[0]), &key->infoCache.memoryPool))
+ != 0)
+ return (status);
+
+ /* Cache the full private key info.
+ */
+ if ((status = CacheFullPrivateKey
+ (key, &newValue->modulus, &newValue->publicExponent,
+ &newValue->privateExponent, newValue->prime, newValue->primeExponent,
+ &newValue->coefficient)) != 0)
+ return (status);
+ return (B_InfoCacheAddInfo
+ (&key->infoCache, (POINTER)&KIT_PKCS_RSAPrivate, (POINTER)newValue));
+}
+
+int KIT_PKCS_RSAPrivateMakeInfo (info, key)
+POINTER *info;
+B_Key *key;
+{
+ A_PKCS_RSA_PRIVATE_KEY keyValue;
+ int status;
+
+ /* If not already found in the cache, try to get values from
+ a full private key info.
+ */
+ if ((status = GetFullPrivateKeyInfo
+ (&keyValue.modulus, &keyValue.publicExponent,
+ &keyValue.privateExponent, keyValue.prime, keyValue.primeExponent,
+ &keyValue.coefficient, key)) != 0)
+ return (status);
+
+ /* Got all the needed fields, so allocate memory for a new
+ A_PKCS_RSA_PRIVATE_KEY struct and copy the key value.
+ */
+ if ((status = B_MemoryPoolAlloc
+ (&key->infoCache.memoryPool, info, sizeof (A_PKCS_RSA_PRIVATE_KEY)))
+ != 0)
+ return (status);
+
+ **(A_PKCS_RSA_PRIVATE_KEY **)info = keyValue;
+ return (0);
+}
+
diff --git a/lib/dns/sec/dnssafe/kipkcrpr.h b/lib/dns/sec/dnssafe/kipkcrpr.h
new file mode 100644
index 00000000..9bcfc02d
--- /dev/null
+++ b/lib/dns/sec/dnssafe/kipkcrpr.h
@@ -0,0 +1,13 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+extern B_KeyInfoType KIT_PKCS_RSAPrivate;
+
+int KIT_PKCS_RSAPrivateAddInfo PROTO_LIST ((B_Key *, POINTER));
+int KIT_PKCS_RSAPrivateMakeInfo PROTO_LIST ((POINTER *, B_Key *));
+
diff --git a/lib/dns/sec/dnssafe/kirsacrt.c b/lib/dns/sec/dnssafe/kirsacrt.c
new file mode 100644
index 00000000..fe1ecb93
--- /dev/null
+++ b/lib/dns/sec/dnssafe/kirsacrt.c
@@ -0,0 +1,101 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "kinfotyp.h"
+#include "intitem.h"
+#include "kifulprv.h"
+
+#define NULL_UCHAR_PTR ((unsigned char *)NULL_PTR)
+
+int KIT_RSA_CRTAddInfo PROTO_LIST ((B_Key *, POINTER));
+int KIT_RSA_CRTMakeInfo PROTO_LIST ((POINTER *, B_Key *));
+
+B_KeyInfoType KIT_RSA_CRT = {KIT_RSA_CRTAddInfo, KIT_RSA_CRTMakeInfo};
+
+static A_RSA_CRT_KEY STATIC_RSA_CRT_KEY;
+static ITEM *RSA_CRT_KEY_ITEMS[] = {
+ &STATIC_RSA_CRT_KEY.modulus, &STATIC_RSA_CRT_KEY.prime[0],
+ &STATIC_RSA_CRT_KEY.prime[1],
+ &STATIC_RSA_CRT_KEY.primeExponent[0],
+ &STATIC_RSA_CRT_KEY.primeExponent[1],
+ &STATIC_RSA_CRT_KEY.coefficient
+};
+
+/* args points to A_RSA_CRT_KEY.
+ */
+int KI_RSA_CRT (keyInfoType)
+POINTER *keyInfoType;
+{
+ *keyInfoType = (POINTER)&KIT_RSA_CRT;
+
+ /* Return 1 to indicate a KeyInfoType, not an AlgorithmInfoType */
+ return (1);
+}
+
+int KIT_RSA_CRTAddInfo (key, info)
+B_Key *key;
+POINTER info;
+{
+ A_RSA_CRT_KEY *newValue;
+ int status;
+
+ /* Allocate memory for A_RSA_CRT_KEY struct and copy integers
+ from supplied value.
+ */
+ if ((status = B_MemoryPoolAlloc
+ (&key->infoCache.memoryPool, (POINTER *)&newValue,
+ sizeof (A_RSA_CRT_KEY))) != 0)
+ return (status);
+ if ((status = AllocAndCopyIntegerItems
+ ((POINTER)newValue, info, (POINTER)&STATIC_RSA_CRT_KEY,
+ RSA_CRT_KEY_ITEMS,
+ sizeof (RSA_CRT_KEY_ITEMS) / sizeof (RSA_CRT_KEY_ITEMS[0]),
+ &key->infoCache.memoryPool)) != 0)
+ return (status);
+
+ /* Cache the full private key info, setting unused fields to NULL.
+ */
+ if ((status = CacheFullPrivateKey
+ (key, &newValue->modulus, (ITEM *)NULL_PTR, (ITEM *)NULL_PTR,
+ newValue->prime, newValue->primeExponent, &newValue->coefficient))
+ != 0)
+ return (status);
+ return (B_InfoCacheAddInfo
+ (&key->infoCache, (POINTER)&KIT_RSA_CRT, (POINTER)newValue));
+}
+
+int KIT_RSA_CRTMakeInfo (info, key)
+POINTER *info;
+B_Key *key;
+{
+ A_RSA_CRT_KEY keyValue;
+ int status;
+
+ /* If not already found in the cache, try to get values from
+ a full private key info, setting unneeded entries to NULL.
+ */
+ if ((status = GetFullPrivateKeyInfo
+ (&keyValue.modulus, (ITEM *)NULL_PTR, (ITEM *)NULL_PTR,
+ keyValue.prime, keyValue.primeExponent, &keyValue.coefficient,
+ key)) != 0)
+ return (status);
+
+ /* Got all the needed fields, so allocate memory for a new
+ A_RSA_CRT_KEY struct and copy the key value.
+ */
+ if ((status = B_MemoryPoolAlloc
+ (&key->infoCache.memoryPool, info, sizeof (A_RSA_CRT_KEY))) != 0)
+ return (status);
+
+ **(A_RSA_CRT_KEY **)info = keyValue;
+ return (0);
+}
+
diff --git a/lib/dns/sec/dnssafe/kirsapub.c b/lib/dns/sec/dnssafe/kirsapub.c
new file mode 100644
index 00000000..a588ec88
--- /dev/null
+++ b/lib/dns/sec/dnssafe/kirsapub.c
@@ -0,0 +1,80 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "kinfotyp.h"
+#include "intitem.h"
+#include "kifulprv.h"
+#include "kirsapub.h"
+
+B_KeyInfoType KIT_RSAPublic =
+ {KIT_RSAPublicAddInfo, KIT_RSAPublicMakeInfo};
+
+static A_RSA_KEY STATIC_RSA_KEY;
+static ITEM *RSA_KEY_ITEMS[] =
+ {&STATIC_RSA_KEY.modulus, &STATIC_RSA_KEY.exponent};
+
+int KI_RSAPublic (keyInfoType)
+POINTER *keyInfoType;
+{
+ *keyInfoType = (POINTER)&KIT_RSAPublic;
+
+ /* Return 1 to indicate a KeyInfoType, not an AlgorithmInfoType */
+ return (1);
+}
+
+int KIT_RSAPublicAddInfo (key, info)
+B_Key *key;
+POINTER info;
+{
+ POINTER newValue;
+ int status;
+
+ /* Allocate memory for A_RSA_KEY struct and copy integers
+ from supplied value.
+ */
+ if ((status = B_MemoryPoolAlloc
+ (&key->infoCache.memoryPool, &newValue, sizeof (A_RSA_KEY))) != 0)
+ return (status);
+ if ((status = AllocAndCopyIntegerItems
+ (newValue, info, (POINTER)&STATIC_RSA_KEY, RSA_KEY_ITEMS,
+ sizeof (RSA_KEY_ITEMS) / sizeof (RSA_KEY_ITEMS[0]),
+ &key->infoCache.memoryPool)) != 0)
+ return (status);
+
+ return (B_InfoCacheAddInfo
+ (&key->infoCache, (POINTER)&KIT_RSAPublic, newValue));
+}
+
+int KIT_RSAPublicMakeInfo (info, key)
+POINTER *info;
+B_Key *key;
+{
+ A_RSA_KEY keyValue;
+ int status;
+
+ /* If not already found in the cache, try to get values from
+ a full private key info, setting unneeded entries to NULL.
+ */
+ if ((status = GetFullPrivateKeyInfo
+ (&keyValue.modulus, &keyValue.exponent, (ITEM *)NULL_PTR,
+ (ITEM *)NULL_PTR, (ITEM *)NULL_PTR, (ITEM *)NULL_PTR, key)) != 0)
+ return (status);
+
+ /* Got all the needed fields, so allocate memory for a new
+ A_RSA_KEY struct and copy the key value.
+ */
+ if ((status = B_MemoryPoolAlloc
+ (&key->infoCache.memoryPool, info, sizeof (A_RSA_KEY))) != 0)
+ return (status);
+
+ **(A_RSA_KEY **)info = keyValue;
+ return (0);
+}
diff --git a/lib/dns/sec/dnssafe/kirsapub.h b/lib/dns/sec/dnssafe/kirsapub.h
new file mode 100644
index 00000000..485fd79a
--- /dev/null
+++ b/lib/dns/sec/dnssafe/kirsapub.h
@@ -0,0 +1,13 @@
+/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+extern B_KeyInfoType KIT_RSAPublic;
+
+int KIT_RSAPublicAddInfo PROTO_LIST ((B_Key *, POINTER));
+int KIT_RSAPublicMakeInfo PROTO_LIST ((POINTER *, B_Key *));
+
diff --git a/lib/dns/sec/dnssafe/md5.c b/lib/dns/sec/dnssafe/md5.c
new file mode 100644
index 00000000..a5865d9e
--- /dev/null
+++ b/lib/dns/sec/dnssafe/md5.c
@@ -0,0 +1,281 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "algae.h"
+#include "md5.h"
+
+/* Constants for MD5Transform routine.
+ */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
+static void Encode PROTO_LIST ((unsigned char *, UINT4 *, unsigned int));
+static void Decode PROTO_LIST ((UINT4 *, unsigned char *, unsigned int));
+
+/* F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+ Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context.
+ */
+void A_MD5Init (context)
+A_MD5_CTX *context;
+{
+ context->count[0] = context->count[1] = 0;
+
+ /* Load magic initialization constants.
+ */
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xefcdab89;
+ context->state[2] = 0x98badcfe;
+ context->state[3] = 0x10325476;
+}
+
+/* MD5 block update operation. Continues an MD5 message-digest
+ operation, processing another message block, and updating the
+ context.
+ */
+void A_MD5Update (context, input, inputLen)
+A_MD5_CTX *context;
+unsigned char *input; /* input block */
+unsigned int inputLen; /* length of input block */
+{
+ unsigned int i, index, partLen;
+
+ /* Compute number of bytes mod 64 */
+ index = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+ /* Update number of bits */
+ if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3))
+ context->count[1]++;
+ context->count[1] += ((UINT4)inputLen >> 29);
+
+ partLen = 64 - index;
+
+ /* Transform as many times as possible.
+ */
+ if (inputLen >= partLen) {
+ T_memcpy ((POINTER)&context->buffer[index], (POINTER)input, partLen);
+ MD5Transform (context->state, context->buffer);
+
+ for (i = partLen; i + 63 < inputLen; i += 64)
+ MD5Transform (context->state, &input[i]);
+
+ index = 0;
+ }
+ else
+ i = 0;
+
+ /* Buffer remaining input */
+ T_memcpy ((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i);
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+ the message digest and zeroizing the context.
+ Assume digest buffer is at least A_MD5_DIGEST_LEN.
+ */
+void A_MD5Final (context, digest)
+A_MD5_CTX *context;
+unsigned char *digest;
+{
+ unsigned char bits[8], pad[64];
+ unsigned int index, padLen;
+
+ /* Save number of bits */
+ Encode (bits, context->count, 8);
+
+ /* Pad out to 56 mod 64.
+ */
+ index = (unsigned int)((context->count[0] >> 3) & 0x3f);
+ padLen = (index < 56) ? (56 - index) : (120 - index);
+ T_memset ((POINTER)pad, 0, padLen);
+ pad[0] = 0x80;
+ A_MD5Update (context, pad, padLen);
+
+ /* Append length (before padding) */
+ A_MD5Update (context, bits, 8);
+
+ /* Store state in digest */
+ Encode (digest, context->state, 16);
+
+ /* Restart the context. */
+ A_MD5Init (context);
+}
+
+/* MD5 basic transformation. Transforms state based on block.
+ */
+static void MD5Transform (state, block)
+UINT4 state[4];
+unsigned char block[64];
+{
+ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+ Decode (x, block, 64);
+
+ /* Round 1 */
+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+
+ /* Zeroize sensitive information.
+ */
+ T_memset ((POINTER)x, 0, sizeof (x));
+}
+
+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
+ a multiple of 4.
+ */
+static void Encode (output, input, len)
+unsigned char *output;
+UINT4 *input;
+unsigned int len;
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4) {
+ output[j] = (unsigned char)(input[i] & 0xff);
+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
+ }
+}
+
+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
+ a multiple of 4.
+ */
+static void Decode (output, input, len)
+UINT4 *output;
+unsigned char *input;
+unsigned int len;
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4)
+ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
+ (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
+}
+
diff --git a/lib/dns/sec/dnssafe/md5.h b/lib/dns/sec/dnssafe/md5.h
new file mode 100644
index 00000000..f770a073
--- /dev/null
+++ b/lib/dns/sec/dnssafe/md5.h
@@ -0,0 +1,32 @@
+/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _MD5_H_
+#define _MD5_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define A_MD5_DIGEST_LEN 16
+
+typedef struct {
+ UINT4 state[4]; /* state (ABCD) */
+ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
+ unsigned char buffer[64]; /* input buffer */
+} A_MD5_CTX;
+
+void A_MD5Init PROTO_LIST ((A_MD5_CTX *));
+void A_MD5Update PROTO_LIST ((A_MD5_CTX *, unsigned char *, unsigned int));
+void A_MD5Final PROTO_LIST ((A_MD5_CTX *, unsigned char *));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/dns/sec/dnssafe/md5rand.c b/lib/dns/sec/dnssafe/md5rand.c
new file mode 100644
index 00000000..b5013d95
--- /dev/null
+++ b/lib/dns/sec/dnssafe/md5rand.c
@@ -0,0 +1,69 @@
+/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+/* Define this so that the type of the 'this' pointer in the
+ virtual functions will be correct for this derived class.
+ */
+struct A_MD5_RANDOM_CTX;
+#define THIS_DIGEST_RANDOM struct A_MD5_RANDOM_CTX
+
+#include "global.h"
+#include "algae.h"
+#include "md5rand.h"
+
+static void A_MD5RandomDigestUpdate PROTO_LIST
+ ((A_MD5_RANDOM_CTX *, unsigned char *, unsigned int));
+static void A_MD5RandomDigestFinal PROTO_LIST
+ ((A_MD5_RANDOM_CTX *, unsigned char *));
+
+static A_DigestRandomVTable V_TABLE =
+ {A_MD5RandomDigestUpdate, A_MD5RandomDigestFinal};
+
+void A_MD5RandomInit (context)
+A_MD5_RANDOM_CTX *context;
+{
+ /* Initialize "base class" */
+ A_DigestRandomInit
+ (&context->digestRandom, A_MD5_DIGEST_LEN, context->state);
+
+ /* Initialize digest algorithm and set vTable.
+ */
+ A_MD5Init (&context->md5Context);
+ context->digestRandom.vTable = &V_TABLE;
+}
+
+void A_MD5RandomUpdate (context, input, inputLen)
+A_MD5_RANDOM_CTX *context;
+unsigned char *input;
+unsigned int inputLen;
+{
+ A_DigestRandomUpdate (&context->digestRandom, input, inputLen);
+}
+
+void A_MD5RandomGenerateBytes (context, output, outputLen)
+A_MD5_RANDOM_CTX *context;
+unsigned char *output;
+unsigned int outputLen;
+{
+ A_DigestRandomGenerateBytes (&context->digestRandom, output, outputLen);
+}
+
+static void A_MD5RandomDigestUpdate (context, input, inputLen)
+A_MD5_RANDOM_CTX *context;
+unsigned char *input;
+unsigned int inputLen;
+{
+ A_MD5Update (&context->md5Context, input, inputLen);
+}
+
+static void A_MD5RandomDigestFinal (context, digest)
+A_MD5_RANDOM_CTX *context;
+unsigned char *digest;
+{
+ A_MD5Final (&context->md5Context, digest);
+}
diff --git a/lib/dns/sec/dnssafe/md5rand.h b/lib/dns/sec/dnssafe/md5rand.h
new file mode 100644
index 00000000..f1974106
--- /dev/null
+++ b/lib/dns/sec/dnssafe/md5rand.h
@@ -0,0 +1,36 @@
+/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _MD5RAND_H_
+#define _MD5RAND_H_ 1
+
+#include "digrand.h"
+#include "md5.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct A_MD5_RANDOM_CTX {
+ A_DigestRandom digestRandom; /* "base class" */
+
+ unsigned char state[3 * A_MD5_DIGEST_LEN];
+ A_MD5_CTX md5Context;
+} A_MD5_RANDOM_CTX;
+
+void A_MD5RandomInit PROTO_LIST ((A_MD5_RANDOM_CTX *));
+void A_MD5RandomUpdate PROTO_LIST
+ ((A_MD5_RANDOM_CTX *, unsigned char *, unsigned int));
+void A_MD5RandomGenerateBytes PROTO_LIST
+ ((A_MD5_RANDOM_CTX *, unsigned char *, unsigned int));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/dns/sec/dnssafe/prime.c b/lib/dns/sec/dnssafe/prime.c
new file mode 100644
index 00000000..f2832ea1
--- /dev/null
+++ b/lib/dns/sec/dnssafe/prime.c
@@ -0,0 +1,163 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+#include "global.h"
+#include "algae.h"
+#include "bigmath.h"
+#include "prime.h"
+
+static unsigned char SMALL_PRIME[]= {3, 5, 7, 11, 13, 17, 19, 23, 29, 31};
+
+/* Prime finding routine.
+ Returns 0, AE_CANCEL, AE_NEED_RANDOM.
+ */
+int PrimeFind
+ (prime, primeSizeBits, primeWords, ee, modulusWords, randomBlock,
+ surrenderContext)
+UINT2 *prime;
+unsigned int primeSizeBits;
+unsigned int primeWords;
+UINT2 *ee;
+unsigned int modulusWords;
+unsigned char *randomBlock;
+A_SURRENDER_CTX *surrenderContext;
+{
+ UINT2 t1[MAX_RSA_MODULUS_WORDS], u1[MAX_RSA_MODULUS_WORDS],
+ u2[MAX_RSA_MODULUS_WORDS], u3[MAX_RSA_MODULUS_WORDS],
+ u4[MAX_RSA_MODULUS_WORDS];
+ char sieve[1000];
+ int status = 0;
+ unsigned int i, r, s, testResult;
+
+ do {
+ /* Create a starting point for the prime from the random block */
+ for (i = 0; i < primeWords; i++) {
+ prime[i] = (UINT2)((UINT2)randomBlock[0] << 8) + randomBlock[1];
+ randomBlock += 2;
+ }
+
+ /* set high order two bits */
+ BigSetbit (prime, primeSizeBits-2);
+ BigSetbit (prime, primeSizeBits-1);
+ for (i = primeSizeBits; i < (unsigned int)(16 * primeWords); i++)
+ BigClrbit (prime, i);
+
+ /* force p to be even */
+ BigClrbit (prime, 0);
+
+ /* clear sieve and mark even positions */
+ for (i = 0; i < 1000; i += 2) {
+ sieve[i] = 1;
+ sieve[i+1] = 0;
+ }
+
+ /* sieve by all odd numbers (don't bother with primality checking) */
+ for (s = 3; s < 9000; s += 2) {
+ /* increase likelihood that s is prime */
+ for (i = 0; i < 5; i++)
+ if (s > SMALL_PRIME[i] && !(s % SMALL_PRIME[i]))
+ continue;
+
+ /* sieve based on s */
+ r = BigSmod (prime, s, primeWords);
+
+ /* returns prime modulo s */
+ if (r == 0)
+ r = s;
+
+ for (i = s - r; i < 1000; i += s)
+ sieve[i] = 1;
+ }
+
+ /* t1 = 1 */
+ BigConst (t1, 1, modulusWords);
+
+ /* now check for primality of values with unmarked sieve */
+ testResult = 0;
+ for (i = 0; i < 1000; i++, BigInc (prime, primeWords)) {
+ if (sieve[i])
+ continue;
+
+ /* copy prime into big variable */
+ BigZero (u4, modulusWords);
+ BigCopy (u4, prime, primeWords);
+
+ /* set u4 = p - 1 */
+ BigDec (u4, modulusWords);
+ BigPegcd (u1, u2, u3, ee, u4, modulusWords);
+
+ /* Now u1 = gcd (E, t1).
+ Test (E, t1)==1 */
+ if (BigCmp (t1, u1, modulusWords))
+ continue;
+
+ /* check for pseudo primality */
+ if ((status = PseudoPrime
+ (&testResult, prime, primeWords, surrenderContext)) != 0)
+ break;
+ if (testResult)
+ /* testResult is set and will cause a break out of while (1) loop */
+ break;
+ }
+ if (status)
+ break;
+
+ if (!testResult)
+ /* Couldn't find a prime with the supplied random block, so ask
+ caller to generate another random block and try again. */
+ status = AE_NEED_RANDOM;
+ } while (0);
+
+ T_memset ((POINTER)u1, 0, sizeof (u1));
+ T_memset ((POINTER)u2, 0, sizeof (u2));
+ T_memset ((POINTER)u3, 0, sizeof (u3));
+ T_memset ((POINTER)u4, 0, sizeof (u4));
+ return (status);
+}
+
+/* Pseudo-primality test.
+ If pseudo prime, *testResult = 1, else *testResult = 0.
+ Returns 0, AE_CANCEL.
+ */
+int PseudoPrime (testResult, prime, primeWords, surrenderContext)
+unsigned int *testResult;
+UINT2 *prime;
+unsigned int primeWords;
+A_SURRENDER_CTX *surrenderContext;
+{
+ UINT2 base[MAX_RSA_MODULUS_WORDS], remainder[MAX_RSA_MODULUS_WORDS];
+ int status;
+ unsigned int i;
+
+ /* Default testResult to false. */
+ *testResult = 0;
+
+ /* Prepare for setting base vector to the small prime. */
+ T_memset ((POINTER)base, 0, sizeof (base));
+
+ for (i = 0; i < 4; i++) {
+ /* check to see if target is multiple of SMALL_PRIME */
+ if (BigSmod (prime, (unsigned int)SMALL_PRIME[i], primeWords) == 0)
+ /* fail... */
+ return (0);
+
+ /* Fermat test. Compute remainder = base ^ prime mod prime
+ and compare the base to the remainder.
+ */
+ base[0] = (UINT2)SMALL_PRIME[i];
+ if ((status = BigModExp
+ (remainder, base, prime, prime, primeWords, surrenderContext)) != 0)
+ return (status);
+ if (BigCmp (remainder, base, primeWords) != 0)
+ /* fail... */
+ return (0);
+ }
+
+ *testResult = 1;
+ return (0);
+}
+
diff --git a/lib/dns/sec/dnssafe/prime.h b/lib/dns/sec/dnssafe/prime.h
new file mode 100644
index 00000000..e922f36a
--- /dev/null
+++ b/lib/dns/sec/dnssafe/prime.h
@@ -0,0 +1,26 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _PRIME_H_
+#define _PRIME_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int PrimeFind PROTO_LIST
+ ((UINT2 *, unsigned int, unsigned int, UINT2 *, unsigned int,
+ unsigned char *, A_SURRENDER_CTX *));
+int PseudoPrime PROTO_LIST
+ ((unsigned int *, UINT2 *, unsigned int, A_SURRENDER_CTX *));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/dns/sec/dnssafe/random.c b/lib/dns/sec/dnssafe/random.c
new file mode 100644
index 00000000..44732d47
--- /dev/null
+++ b/lib/dns/sec/dnssafe/random.c
@@ -0,0 +1,58 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "bsafe2.h"
+#include "bkey.h"
+#include "balg.h"
+#include "ainfotyp.h"
+#include "algobj.h"
+
+int B_RandomInit
+ (algorithmObject, algorithmChooser, surrenderContext)
+B_ALGORITHM_OBJ algorithmObject;
+B_ALGORITHM_CHOOSER algorithmChooser;
+A_SURRENDER_CTX *surrenderContext;
+{
+ if (AlgorithmWrapCheck (THE_ALG_WRAP) != 0)
+ /* Assume error is B_ALGORITHM_OBJ */
+ return (BE_RANDOM_OBJ);
+
+ return (B_AlgorithmRandomInit
+ (&THE_ALG_WRAP->algorithm, algorithmChooser, surrenderContext));
+}
+
+int B_RandomUpdate (algorithmObject, input, inputLen, surrenderContext)
+B_ALGORITHM_OBJ algorithmObject;
+unsigned char *input;
+unsigned int inputLen;
+A_SURRENDER_CTX *surrenderContext;
+{
+ if (AlgorithmWrapCheck (THE_ALG_WRAP) != 0)
+ /* Assume error is B_ALGORITHM_OBJ */
+ return (BE_RANDOM_OBJ);
+
+ return (B_AlgorithmRandomUpdate
+ (&THE_ALG_WRAP->algorithm, input, inputLen, surrenderContext));
+}
+
+int B_GenerateRandomBytes
+ (algorithmObject, output, outputLen, surrenderContext)
+B_ALGORITHM_OBJ algorithmObject;
+unsigned char *output;
+unsigned int outputLen;
+A_SURRENDER_CTX *surrenderContext;
+{
+ if (AlgorithmWrapCheck (THE_ALG_WRAP) != 0)
+ /* Assume error is B_ALGORITHM_OBJ */
+ return (BE_RANDOM_OBJ);
+
+ return (B_AlgorithmGenerateRandomBytes
+ (&THE_ALG_WRAP->algorithm, output, outputLen, surrenderContext));
+}
+
diff --git a/lib/dns/sec/dnssafe/rsa.c b/lib/dns/sec/dnssafe/rsa.c
new file mode 100644
index 00000000..8cf24b32
--- /dev/null
+++ b/lib/dns/sec/dnssafe/rsa.c
@@ -0,0 +1,209 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "algae.h"
+#include "rsa.h"
+#include "bigmath.h"
+
+/* RSA encryption/decryption with full exponent.
+ */
+
+#define GENERATE_BREAK(type) { \
+ status = type; \
+ break; \
+ }
+
+static int RSA PROTO_LIST
+ ((A_RSA_CTX *, unsigned char *, unsigned int *, unsigned int,
+ unsigned char *, A_SURRENDER_CTX *));
+
+/* Returns 0, AE_MODULUS_LEN, AE_KEY_INFO.
+ */
+int A_RSAInit (context, key)
+A_RSA_CTX *context;
+A_RSA_KEY *key;
+{
+ if (A_IntegerBits (key->modulus.data, key->modulus.len)
+ > MAX_RSA_MODULUS_BITS)
+ /* Key size is too big to handle. */
+ return (AE_MODULUS_LEN);
+
+ /* Set the block update blockLen to be big enough to hold the modulus. */
+ context->blockLen =
+ (A_IntegerBits (key->modulus.data, key->modulus.len) + 7) / 8;
+
+ context->inputLen = 0;
+
+ /* convert modulus to bignum representation */
+ if (CanonicalToBig
+ (context->modulus, MAX_RSA_MODULUS_WORDS, key->modulus.data,
+ key->modulus.len))
+ return (AE_KEY_INFO);
+
+ /* compute significant length of modulus */
+ context->modulusWords = BigLen
+ (context->modulus, MAX_RSA_MODULUS_WORDS) / 16 + 1;
+
+ /* convert exponent to bignum representation */
+ if (CanonicalToBig
+ (context->exponent, context->modulusWords,
+ key->exponent.data, key->exponent.len))
+ return (AE_KEY_INFO);
+
+ return (0);
+}
+
+int A_RSAUpdate
+ (context, partOut, partOutLen, maxPartOutLen, partIn, partInLen,
+ surrenderContext)
+A_RSA_CTX *context;
+unsigned char *partOut;
+unsigned int *partOutLen;
+unsigned int maxPartOutLen;
+unsigned char *partIn;
+unsigned int partInLen;
+A_SURRENDER_CTX *surrenderContext;
+{
+ int status;
+ unsigned int partialLen, localPartOutLen;
+
+ /* Initialize partOutLen to zero. */
+ *partOutLen = 0;
+
+ if (context->inputLen + partInLen < context->blockLen) {
+ /* Not enough to encrypt - just accumulate.
+ */
+ T_memcpy
+ ((POINTER)(context->input + context->inputLen), (POINTER)partIn,
+ partInLen);
+ context->inputLen += partInLen;
+ return (0);
+ }
+
+ if (context->inputLen > 0) {
+ /* Need to accumulate the rest of the block bytes into the input and
+ encrypt from there (otherwise it's OK to encrypt straight from
+ the partIn).
+ */
+ partialLen = context->blockLen - context->inputLen;
+ T_memcpy
+ ((POINTER)(context->input + context->inputLen), (POINTER)partIn,
+ partialLen);
+ partIn += partialLen;
+ partInLen -= partialLen;
+
+ if ((status = RSA
+ (context, partOut, &localPartOutLen, maxPartOutLen, context->input,
+ surrenderContext)) != 0)
+ return (status);
+ (*partOutLen) += localPartOutLen;
+ partOut += localPartOutLen;
+ maxPartOutLen -= localPartOutLen;
+ }
+
+ /* Encrypt as many blocks of input as provided.
+ */
+ while (partInLen >= context->blockLen) {
+ if ((status = RSA
+ (context, partOut, &localPartOutLen, maxPartOutLen, partIn,
+ surrenderContext)) != 0)
+ return (status);
+
+ partIn += context->blockLen;
+ partInLen -= context->blockLen;
+ (*partOutLen) += localPartOutLen;
+ partOut += localPartOutLen;
+ maxPartOutLen -= localPartOutLen;
+ }
+
+ /* Copy remaining input bytes to the context's input buffer.
+ */
+ T_memcpy
+ ((POINTER)context->input, partIn, context->inputLen = partInLen);
+ return (0);
+}
+
+int A_RSAFinal (context)
+A_RSA_CTX *context;
+{
+ if (context->inputLen != 0)
+ return (AE_INPUT_LEN);
+
+ /* Restart context to accumulate a new block. */
+ context->inputLen = 0;
+ return (0);
+}
+
+/* Assume input length is context->blockLen.
+ */
+static int RSA
+ (context, output, outputLen, maxOutputLen, input, surrenderContext)
+A_RSA_CTX *context;
+unsigned char *output;
+unsigned int *outputLen;
+unsigned int maxOutputLen;
+unsigned char *input;
+A_SURRENDER_CTX *surrenderContext;
+{
+ struct ModExpFrame {
+ UINT2 bigInBuf[MAX_RSA_MODULUS_WORDS], bigOutBuf[MAX_RSA_MODULUS_WORDS];
+ } *frame = (struct ModExpFrame *)NULL_PTR;
+#if !USE_ALLOCED_FRAME
+ struct ModExpFrame stackFrame;
+#endif
+ int status;
+
+ status = 0;
+ do {
+ if ((*outputLen = context->blockLen) > maxOutputLen)
+ return (AE_OUTPUT_LEN);
+
+#if USE_ALLOCED_FRAME
+ if ((frame = (struct ModExpFrame *)T_malloc (sizeof (*frame)))
+ == (struct ModExpFrame *)NULL_PTR) {
+ status = AE_ALLOC;
+ break;
+ }
+#else
+ /* Just use the buffers allocated on the stack. */
+ frame = &stackFrame;
+#endif
+
+ /* Convert input to bignum representation.
+ This won't return AE_DATA since input length was checked at Update.
+ */
+ CanonicalToBig
+ (frame->bigInBuf, context->modulusWords, input, context->blockLen);
+
+ /* Check for overflow. */
+ if (BigCmp (frame->bigInBuf, context->modulus, context->modulusWords) >= 0)
+ GENERATE_BREAK (AE_INPUT_DATA);
+
+ /* Exponentiate. */
+ if ((status = BigModExp
+ (frame->bigOutBuf, frame->bigInBuf, context->exponent,
+ context->modulus, context->modulusWords, surrenderContext)) != 0)
+ break;
+
+ /* Convert output to canonical representation.
+ This won't return AE_DATA since outputLen was set above.
+ */
+ BigToCanonical
+ (output, *outputLen, frame->bigOutBuf, context->modulusWords);
+ } while (0);
+
+ if (frame != (struct ModExpFrame *)NULL_PTR) {
+ T_memset ((POINTER)frame, 0, sizeof (*frame));
+#if USE_ALLOCED_FRAME
+ T_free ((POINTER)frame);
+#endif
+ }
+
+ return (status);
+}
diff --git a/lib/dns/sec/dnssafe/rsa.h b/lib/dns/sec/dnssafe/rsa.h
new file mode 100644
index 00000000..2d86099a
--- /dev/null
+++ b/lib/dns/sec/dnssafe/rsa.h
@@ -0,0 +1,44 @@
+/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _RSA_H_
+#define _RSA_H_ 1
+
+#include "bigmaxes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Note, these are only valid after a call to A_RSAInit.
+ */
+#define A_RSA_BLOCK_LEN(context) ((context)->blockLen)
+#define A_RSA_MAX_OUTPUT_LEN(context, inputLen)\
+ (inputLen) + (((inputLen) % (context)->blockLen) ?\
+ (context)->blockLen - ((inputLen) % (context)->blockLen) : 0)
+
+typedef struct {
+ unsigned int blockLen; /* total size for the block to be computed */
+ unsigned char input[MAX_RSA_MODULUS_LEN];
+ unsigned int inputLen;
+ unsigned int modulusWords;
+ UINT2 modulus[MAX_RSA_MODULUS_WORDS];
+ UINT2 exponent[MAX_RSA_MODULUS_WORDS];
+} A_RSA_CTX;
+
+int A_RSAInit PROTO_LIST ((A_RSA_CTX *, A_RSA_KEY *));
+int A_RSAUpdate PROTO_LIST
+ ((A_RSA_CTX *, unsigned char *, unsigned int *, unsigned int,
+ unsigned char *, unsigned int, A_SURRENDER_CTX *));
+int A_RSAFinal PROTO_LIST ((A_RSA_CTX *));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/dns/sec/dnssafe/rsakeygn.c b/lib/dns/sec/dnssafe/rsakeygn.c
new file mode 100644
index 00000000..685fb71c
--- /dev/null
+++ b/lib/dns/sec/dnssafe/rsakeygn.c
@@ -0,0 +1,242 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "algae.h"
+#include "bigmath.h"
+#include "surrendr.h"
+#include "prime.h"
+#include "rsakeygn.h"
+
+#define GENERATE_BREAK(type) { \
+ status = type; \
+ break; \
+ }
+
+static int RSAParameters PROTO_LIST
+ ((UINT2 *, UINT2 *, UINT2 *, UINT2 *, UINT2 *, UINT2 *, UINT2 *, UINT2 *,
+ unsigned int, unsigned int, A_SURRENDER_CTX *));
+static void SetRSAKeyGenResult PROTO_LIST
+ ((A_PKCS_RSA_PRIVATE_KEY *, A_RSA_KEY_GEN_CTX *, UINT2 *, UINT2 *));
+
+int A_RSAKeyGenInit (context, params)
+A_RSA_KEY_GEN_CTX *context;
+A_RSA_KEY_GEN_PARAMS *params;
+{
+ context->modulusBits = params->modulusBits;
+
+ /* Prezeroize big public exponent vector. */
+ T_memset
+ ((POINTER)context->bigPublicExponent, 0,
+ sizeof (context->bigPublicExponent));
+
+ /* Copy public exponent into big vector */
+ if (CanonicalToBig
+ (context->bigPublicExponent, MAX_RSA_MODULUS_WORDS,
+ params->publicExponent.data, params->publicExponent.len) != 0)
+ /* could not copy exponent into MAX_RSA_MODULUS_WORDS */
+ return (AE_EXPONENT_LEN);
+
+ /* Check that public exponent is in bounds and odd.
+ */
+ if (BigLen (context->bigPublicExponent, MAX_RSA_MODULUS_WORDS) >=
+ context->modulusBits)
+ return (AE_EXPONENT_LEN);
+ if (!(context->bigPublicExponent[0] & 1))
+ return (AE_EXPONENT_EVEN);
+
+ return (0);
+}
+
+/* This generates an RSA keypair of size modulusBits with the fixed
+ publicExponent, pointing result to the resulting integers. The
+ resulting integer data is in the context, so that the values must be
+ copied before the context is zeroized.
+ All integers are unsigned canonical bytes arrays with the most significant
+ byte first.
+ The randomBlock is of length randomBlockLen returned by RSAKeyGenQuery.
+ This assumes that the modulusBits size was checked by RSAKeyGenQuery.
+ */
+int A_RSAKeyGen (context, result, randomBlock, surrenderContext)
+A_RSA_KEY_GEN_CTX *context;
+A_PKCS_RSA_PRIVATE_KEY **result;
+unsigned char *randomBlock;
+A_SURRENDER_CTX *surrenderContext;
+{
+ UINT2 *bigPrimeP, *bigPrimeQ;
+ int status;
+ unsigned int modulusWords, primeSizeBits, primeWords;
+
+ /* Prezeroize all big word vectors. */
+ T_memset ((POINTER)context->bigModulus, 0, sizeof (context->bigModulus));
+ T_memset
+ ((POINTER)context->bigPrivateExponent, 0,
+ sizeof (context->bigPrivateExponent));
+ T_memset ((POINTER)context->bigPrime1, 0, sizeof (context->bigPrime1));
+ T_memset ((POINTER)context->bigPrime2, 0, sizeof (context->bigPrime2));
+ T_memset ((POINTER)context->bigExponentP, 0, sizeof (context->bigExponentP));
+ T_memset ((POINTER)context->bigExponentQ, 0, sizeof (context->bigExponentQ));
+ T_memset
+ ((POINTER)context->bigCoefficient, 0, sizeof (context->bigCoefficient));
+
+ /* prime size is half modulus size */
+ modulusWords = BITS_TO_WORDS (context->modulusBits);
+ primeSizeBits = RSA_PRIME_BITS (context->modulusBits);
+ primeWords = BITS_TO_WORDS (RSA_PRIME_BITS (context->modulusBits));
+
+ /* Fish for bigPrime1 and bigPrime2 that are compatible with supplied
+ publicExponent.
+ The randomBlock holds random bytes for two primes.
+ */
+ if ((status = PrimeFind
+ (context->bigPrime1, primeSizeBits, primeWords,
+ context->bigPublicExponent, modulusWords, randomBlock,
+ surrenderContext)) != 0)
+ return (status);
+ if ((status = PrimeFind
+ (context->bigPrime2, context->modulusBits - primeSizeBits,
+ primeWords, context->bigPublicExponent, modulusWords,
+ randomBlock + (2 * primeWords), surrenderContext)) != 0)
+ return (status);
+
+ /* Set bigPrimeP to the larger of bigPrime1 and bigPrime2 and set
+ bigPrimeQ to the smaller.
+ */
+ if (BigCmp (context->bigPrime1, context->bigPrime2, primeWords) == 1) {
+ bigPrimeP = context->bigPrime1;
+ bigPrimeQ = context->bigPrime2;
+ }
+ else {
+ bigPrimeP = context->bigPrime2;
+ bigPrimeQ = context->bigPrime1;
+ }
+
+ /* Calculate the rest of the key components */
+ if ((status = RSAParameters
+ (context->bigModulus, context->bigCoefficient,
+ context->bigExponentP, context->bigExponentQ,
+ context->bigPrivateExponent, context->bigPublicExponent,
+ bigPrimeP, bigPrimeQ, primeWords, modulusWords, surrenderContext)) != 0)
+ return (status);
+
+ /* Copy key components into canonical buffers which are at the
+ end of the context. */
+ *result = &context->result;
+ SetRSAKeyGenResult (*result, context, bigPrimeP, bigPrimeQ);
+
+ return (0);
+}
+
+/* Assumes ee, pp, qq are given, calculates other parameters.
+ Returns 0, AE_CANCEL.
+ */
+static int RSAParameters
+ (nn, cr, dp, dq, dd, ee, pp, qq, primeWords, modulusWords, surrenderContext)
+UINT2 *nn, *cr, *dp, *dq, *dd, *ee, *pp, *qq;
+unsigned int primeWords, modulusWords;
+A_SURRENDER_CTX *surrenderContext;
+{
+ UINT2 t1[2 * MAX_RSA_PRIME_WORDS], t2[MAX_RSA_PRIME_WORDS],
+ t3[MAX_RSA_MODULUS_WORDS], u1[MAX_RSA_MODULUS_WORDS],
+ u3[MAX_RSA_MODULUS_WORDS], pm1[MAX_RSA_PRIME_WORDS],
+ qm1[MAX_RSA_PRIME_WORDS];
+ int status;
+
+ do {
+ /* N=P*Q */
+ BigMpy (t1, pp, qq, primeWords);
+ if ((status = CheckSurrender (surrenderContext)) != 0)
+ break;
+ BigCopy (nn, t1, modulusWords);
+
+ /* qm1=q-1 & pm1=p-1 */
+ BigConst (t1, 1, primeWords);
+ BigSub (qm1, qq, t1, primeWords);
+ BigSub (pm1, pp, t1, primeWords);
+
+ /* t3=1 */
+ BigConst (t3, 1, modulusWords);
+
+ /*t1=phi (N) */
+ BigMpy (t1, pm1, qm1, primeWords);
+ if ((status = CheckSurrender (surrenderContext)) != 0)
+ break;
+
+ /* compute decryption exponent */
+ BigPegcd (u1, dd, u3, ee, t1, modulusWords);
+ if ((status = CheckSurrender (surrenderContext)) != 0)
+ break;
+
+ /* calc DP=inv (E)[mod (P-1)] & DQ=inv (e)[mod (Q-1)] */
+ BigPdiv (t1, dp, dd, pm1, modulusWords, primeWords);
+ if ((status = CheckSurrender (surrenderContext)) != 0)
+ break;
+ BigPdiv (t1, dq, dd, qm1, modulusWords, primeWords);
+ if ((status = CheckSurrender (surrenderContext)) != 0)
+ break;
+
+ /* calc CR = (inv (Q)[modP]) */
+ BigPegcd (t1, t2, cr, pp, qq, primeWords);
+ } while (0);
+
+ T_memset ((POINTER)t1, 0, sizeof (t1));
+ T_memset ((POINTER)t2, 0, sizeof (t2));
+ T_memset ((POINTER)t3, 0, sizeof (t3));
+ T_memset ((POINTER)u1, 0, sizeof (u1));
+ T_memset ((POINTER)u3, 0, sizeof (u3));
+ T_memset ((POINTER)pm1, 0, sizeof (pm1));
+ T_memset ((POINTER)qm1, 0, sizeof (qm1));
+ return (status);
+}
+
+static void SetRSAKeyGenResult (result, context, bigPrimeP, bigPrimeQ)
+A_PKCS_RSA_PRIVATE_KEY *result;
+A_RSA_KEY_GEN_CTX *context;
+UINT2 *bigPrimeP;
+UINT2 *bigPrimeQ;
+{
+ unsigned int primeLen, modulusLen;
+
+ modulusLen = result->modulus.len = result->publicExponent.len =
+ result->privateExponent.len = BITS_TO_LEN (context->modulusBits);
+ primeLen = result->prime[0].len = result->prime[1].len =
+ result->primeExponent[0].len = result->primeExponent[1].len =
+ result->coefficient.len = RSA_PRIME_LEN (context->modulusBits);
+
+ result->modulus.data = context->resultBuffer;
+ result->publicExponent.data = result->modulus.data + modulusLen;
+ result->privateExponent.data = result->publicExponent.data + modulusLen;
+ result->prime[0].data = result->privateExponent.data + modulusLen;
+ result->prime[1].data = result->prime[0].data + primeLen;
+ result->primeExponent[0].data = result->prime[1].data + primeLen;
+ result->primeExponent[1].data = result->primeExponent[0].data + primeLen;
+ result->coefficient.data = result->primeExponent[1].data + primeLen;
+
+ BigToCanonical
+ (result->modulus.data, modulusLen, context->bigModulus,
+ MAX_RSA_MODULUS_WORDS);
+ BigToCanonical
+ (result->publicExponent.data, modulusLen,
+ context->bigPublicExponent, MAX_RSA_MODULUS_WORDS);
+ BigToCanonical
+ (result->privateExponent.data, modulusLen,
+ context->bigPrivateExponent, MAX_RSA_MODULUS_WORDS);
+ BigToCanonical
+ (result->prime[0].data, primeLen, bigPrimeP, MAX_RSA_PRIME_WORDS);
+ BigToCanonical
+ (result->prime[1].data, primeLen, bigPrimeQ, MAX_RSA_PRIME_WORDS);
+ BigToCanonical
+ (result->primeExponent[0].data, primeLen, context->bigExponentP,
+ MAX_RSA_PRIME_WORDS);
+ BigToCanonical
+ (result->primeExponent[1].data, primeLen, context->bigExponentQ,
+ MAX_RSA_PRIME_WORDS);
+ BigToCanonical
+ (result->coefficient.data, primeLen, context->bigCoefficient,
+ MAX_RSA_PRIME_WORDS);
+}
diff --git a/lib/dns/sec/dnssafe/rsakeygn.h b/lib/dns/sec/dnssafe/rsakeygn.h
new file mode 100644
index 00000000..ba40b864
--- /dev/null
+++ b/lib/dns/sec/dnssafe/rsakeygn.h
@@ -0,0 +1,54 @@
+/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _RSAKEYGN_H_
+#define _RSAKEYGN_H_ 1
+
+#include "bigmaxes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MIN_RSA_MODULUS_BITS 256
+
+/* Need randomBlock to hold bytes for two UINT2 prime number arrays each,
+ of length primeWords = BITS_TO_WORDS (RSA_PRIME_BITS (modulusBits)). */
+#define A_RSA_KEY_GEN_RANDOM_BLOCK_LEN(modulusBits) \
+ (4 * BITS_TO_WORDS (RSA_PRIME_BITS (modulusBits)))
+
+/* Note that the scratch area for the output integers is allocated
+ in the context after the RSA_KEY_GEN_CTX.
+ */
+typedef struct {
+ unsigned int modulusBits;
+ UINT2 bigModulus[MAX_RSA_MODULUS_WORDS];
+ UINT2 bigPublicExponent[MAX_RSA_MODULUS_WORDS];
+ UINT2 bigPrivateExponent[MAX_RSA_MODULUS_WORDS];
+ UINT2 bigPrime1[MAX_RSA_PRIME_WORDS];
+ UINT2 bigPrime2[MAX_RSA_PRIME_WORDS];
+ UINT2 bigExponentP[MAX_RSA_PRIME_WORDS];
+ UINT2 bigExponentQ[MAX_RSA_PRIME_WORDS];
+ UINT2 bigCoefficient[MAX_RSA_PRIME_WORDS];
+ A_PKCS_RSA_PRIVATE_KEY result;
+ unsigned char resultBuffer
+ [3 * BITS_TO_LEN (MAX_RSA_MODULUS_BITS) +
+ 5 * RSA_PRIME_LEN (MAX_RSA_MODULUS_BITS)];
+} A_RSA_KEY_GEN_CTX;
+
+int A_RSAKeyGenInit PROTO_LIST ((A_RSA_KEY_GEN_CTX *, A_RSA_KEY_GEN_PARAMS *));
+int A_RSAKeyGen PROTO_LIST
+ ((A_RSA_KEY_GEN_CTX *, A_PKCS_RSA_PRIVATE_KEY **, unsigned char *,
+ A_SURRENDER_CTX *));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/lib/dns/sec/dnssafe/seccbcd.c b/lib/dns/sec/dnssafe/seccbcd.c
new file mode 100644
index 00000000..52dafd69
--- /dev/null
+++ b/lib/dns/sec/dnssafe/seccbcd.c
@@ -0,0 +1,146 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "algae.h"
+#include "secrcbc.h"
+
+static void SecretCBCDecryptBlock PROTO_LIST
+ ((POINTER, unsigned char *, SECRET_CRYPT, unsigned char *,
+ unsigned char *));
+
+/* On first call, it is assumed that *remainderLen is zero.
+ This assumes remainder buffer is at least 16 bytes is size.
+ Returns AE_OUTPUT_LEN, 0.
+ */
+int SecretCBCDecryptUpdate
+ (context, xorBlock, remainder, remainderLen, SecretDecrypt, output,
+ outputLen, maxOutputLen, input, inputLen)
+POINTER context;
+unsigned char *xorBlock;
+unsigned char *remainder;
+unsigned int *remainderLen;
+SECRET_CRYPT SecretDecrypt;
+unsigned char *output;
+unsigned int *outputLen;
+unsigned int maxOutputLen;
+unsigned char *input;
+unsigned int inputLen;
+{
+ unsigned int partialLen;
+
+ if (*remainderLen + inputLen <= 16) {
+ /* Not enough to decrypt, just accumulate into remainder.
+ */
+ *outputLen = 0;
+ T_memcpy ((POINTER)remainder + *remainderLen, (POINTER)input, inputLen);
+ *remainderLen += inputLen;
+ return (0);
+ }
+
+ /* Fill up the rest of the remainder with bytes from input.
+ */
+ T_memcpy
+ ((POINTER)remainder + *remainderLen, (POINTER)input,
+ partialLen = 16 - *remainderLen);
+ input += partialLen;
+ inputLen -= partialLen;
+
+ /* remainder is full and inputLen is at least 1. Compute outputLen
+ as the size needed to keep remainder as full as possible.
+ */
+ if ((*outputLen = 8 * ((inputLen + 7) / 8)) > maxOutputLen)
+ return (AE_OUTPUT_LEN);
+
+ SecretCBCDecryptBlock
+ (context, xorBlock, SecretDecrypt, output, remainder);
+ output += 8;
+
+ if (inputLen <= 8) {
+ /* Shift remaining input bytes into remainder */
+ T_memmove ((POINTER)remainder, (POINTER)(remainder + 8), 8);
+ T_memcpy ((POINTER)(remainder + 8), (POINTER)input, inputLen);
+ *remainderLen = 8 + inputLen;
+ return (0);
+ }
+
+ /* Decrypt the rest of the remainder.
+ */
+ SecretCBCDecryptBlock
+ (context, xorBlock, SecretDecrypt, output, remainder + 8);
+ output += 8;
+
+ /* Now decrypt the bulk of the input.
+ */
+ while (inputLen > 16) {
+ SecretCBCDecryptBlock (context, xorBlock, SecretDecrypt, output, input);
+ output += 8;
+ input += 8;
+ inputLen -= 8;
+ }
+
+ /* inputLen is now <= 16, so copy input to remainder.
+ */
+ T_memcpy ((POINTER)remainder, (POINTER)input, inputLen);
+ *remainderLen = inputLen;
+ return (0);
+}
+
+/* The caller must restart the context (setting remainderLen to zero).
+ Returns AE_INPUT_LEN, AE_OUTPUT_LEN, 0.
+ */
+int SecretCBCDecryptFinal
+ (context, xorBlock, remainder, remainderLen, SecretDecrypt, output,
+ outputLen, maxOutputLen)
+POINTER context;
+unsigned char *xorBlock;
+unsigned char *remainder;
+unsigned int remainderLen;
+SECRET_CRYPT SecretDecrypt;
+unsigned char *output;
+unsigned int *outputLen;
+unsigned int maxOutputLen;
+{
+ if ((*outputLen = remainderLen) == 0)
+ /* There was never any data. */
+ return (0);
+
+ if (remainderLen != 8 && remainderLen != 16)
+ return (AE_INPUT_LEN);
+
+ if (*outputLen > maxOutputLen)
+ return (AE_OUTPUT_LEN);
+
+ SecretCBCDecryptBlock
+ (context, xorBlock, SecretDecrypt, output, remainder);
+ output += 8;
+ if (remainderLen == 16)
+ SecretCBCDecryptBlock
+ (context, xorBlock, SecretDecrypt, output, remainder + 8);
+ return (0);
+}
+
+static void SecretCBCDecryptBlock (context, xorBlock, SecretDecrypt, out, in)
+POINTER context;
+unsigned char *xorBlock;
+SECRET_CRYPT SecretDecrypt;
+unsigned char *out;
+unsigned char *in;
+{
+ unsigned char tempBuffer[8];
+ unsigned int i;
+
+ /* Save input to be copied to the xor block. */
+ T_memcpy ((POINTER)tempBuffer, (POINTER)in, 8);
+ (*SecretDecrypt) (context, out, in);
+ for (i = 0; i < 8; i++)
+ out[i] ^= xorBlock[i];
+ T_memcpy ((POINTER)xorBlock, (POINTER)tempBuffer, 8);
+
+ T_memset ((POINTER)tempBuffer, 0, sizeof (tempBuffer));
+}
diff --git a/lib/dns/sec/dnssafe/seccbce.c b/lib/dns/sec/dnssafe/seccbce.c
new file mode 100644
index 00000000..6fe5c863
--- /dev/null
+++ b/lib/dns/sec/dnssafe/seccbce.c
@@ -0,0 +1,97 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "algae.h"
+#include "secrcbc.h"
+
+/* On first call, it is assumed that *remainderLen is zero.
+ Returns AE_OUTPUT_LEN, 0.
+ */
+int SecretCBCEncryptUpdate
+ (context, xorBlock, remainder, remainderLen, SecretEncrypt, output,
+ outputLen, maxOutputLen, input, inputLen)
+POINTER context;
+unsigned char *xorBlock;
+unsigned char *remainder;
+unsigned int *remainderLen;
+SECRET_CRYPT SecretEncrypt;
+unsigned char *output;
+unsigned int *outputLen;
+unsigned int maxOutputLen;
+unsigned char *input;
+unsigned int inputLen;
+{
+ unsigned int partialLen, totalLen, i;
+
+ totalLen = *remainderLen + inputLen;
+
+ /* Output length will be all available 8-byte blocks.
+ */
+ if ((*outputLen = 8 * (totalLen / 8)) > maxOutputLen)
+ return (AE_OUTPUT_LEN);
+
+ if (totalLen < 8) {
+ /* Not enough to encrypt, just accumulate into remainder.
+ */
+ T_memcpy
+ ((POINTER)remainder + *remainderLen, (POINTER)input, inputLen);
+ *remainderLen = totalLen;
+
+ return (0);
+ }
+
+ /* Accumulate enough bytes from input into remainder to encrypt the
+ remainder.
+ */
+ T_memcpy
+ ((POINTER)remainder + *remainderLen, (POINTER)input,
+ partialLen = 8 - *remainderLen);
+
+ for (i = 0; i < 8; i++)
+ output[i] = remainder[i] ^ xorBlock[i];
+ /* Encrypt in place */
+ (*SecretEncrypt) (context, output, output);
+
+ T_memcpy ((POINTER)xorBlock, (POINTER)output, 8);
+ input += partialLen;
+ inputLen -= partialLen;
+ output += 8;
+
+ /* Now encrypt the bulk of the input.
+ */
+ while (inputLen >= 8) {
+ for (i = 0; i < 8; i++)
+ output[i] = *(input++) ^ xorBlock[i];
+ /* Encrypt in place */
+ (*SecretEncrypt) (context, output, output);
+ T_memcpy ((POINTER)xorBlock, (POINTER)output, 8);
+ output += 8;
+ inputLen -= 8;
+ }
+
+ /* inputLen is now < 8, so copy input to remainder.
+ */
+ T_memcpy ((POINTER)remainder, (POINTER)input, inputLen);
+ *remainderLen = inputLen;
+
+ return (0);
+}
+
+/* This just ensures that *remainderLen is zero.
+ The caller must restart the context (setting remainderLen to zero).
+ Returns AE_INPUT_LEN, 0.
+ */
+int SecretCBCEncryptFinal (remainderLen)
+unsigned int remainderLen;
+{
+ if (remainderLen != 0)
+ return (AE_INPUT_LEN);
+
+ return (0);
+}
diff --git a/lib/dns/sec/dnssafe/secrcbc.h b/lib/dns/sec/dnssafe/secrcbc.h
new file mode 100644
index 00000000..122f83f5
--- /dev/null
+++ b/lib/dns/sec/dnssafe/secrcbc.h
@@ -0,0 +1,36 @@
+/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _SECRCBC_H_
+#define _SECRCBC_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*SECRET_CRYPT) PROTO_LIST
+ ((POINTER, unsigned char *, unsigned char *));
+
+int SecretCBCEncryptUpdate PROTO_LIST
+ ((POINTER, unsigned char *, unsigned char *, unsigned int *, SECRET_CRYPT,
+ unsigned char *, unsigned int *, unsigned int, unsigned char *,
+ unsigned int));
+int SecretCBCEncryptFinal PROTO_LIST ((unsigned int));
+int SecretCBCDecryptUpdate PROTO_LIST
+ ((POINTER, unsigned char *, unsigned char *, unsigned int *, SECRET_CRYPT,
+ unsigned char *, unsigned int *, unsigned int, unsigned char *,
+ unsigned int));
+int SecretCBCDecryptFinal PROTO_LIST
+ ((POINTER, unsigned char *, unsigned char *, unsigned int, SECRET_CRYPT,
+ unsigned char *, unsigned int *, unsigned int));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/dns/sec/dnssafe/surrendr.c b/lib/dns/sec/dnssafe/surrendr.c
new file mode 100644
index 00000000..c9aa460e
--- /dev/null
+++ b/lib/dns/sec/dnssafe/surrendr.c
@@ -0,0 +1,24 @@
+/* Copyright (C) RSA Data Security, Inc. created 1992, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#include "global.h"
+#include "algae.h"
+#include "surrendr.h"
+
+/* Returns 0, AE_CANCEL.
+ */
+int CheckSurrender (surrenderContext)
+A_SURRENDER_CTX *surrenderContext;
+{
+ if (surrenderContext == (A_SURRENDER_CTX *)NULL_PTR)
+ return (0);
+
+ if ((*surrenderContext->Surrender) (surrenderContext->handle))
+ return (AE_CANCEL);
+ return (0);
+}
diff --git a/lib/dns/sec/dnssafe/surrendr.h b/lib/dns/sec/dnssafe/surrendr.h
new file mode 100644
index 00000000..dc929046
--- /dev/null
+++ b/lib/dns/sec/dnssafe/surrendr.h
@@ -0,0 +1,22 @@
+/* Copyright (C) RSA Data Security, Inc. created 1992, 1996. This is an
+ unpublished work protected as such under copyright law. This work
+ contains proprietary, confidential, and trade secret information of
+ RSA Data Security, Inc. Use, disclosure or reproduction without the
+ express written authorization of RSA Data Security, Inc. is
+ prohibited.
+ */
+
+#ifndef _SURRENDR_H_
+#define _SURRENDR_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int CheckSurrender PROTO_LIST ((A_SURRENDER_CTX *));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/dns/sec/dst/.cvsignore b/lib/dns/sec/dst/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/lib/dns/sec/dst/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/lib/dns/sec/dst/Makefile.in b/lib/dns/sec/dst/Makefile.in
new file mode 100644
index 00000000..b881b2bc
--- /dev/null
+++ b/lib/dns/sec/dst/Makefile.in
@@ -0,0 +1,44 @@
+# Copyright (C) 1998, 1999, 2000 Internet Software Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+# CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+# SOFTWARE.
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_INCLUDES@
+
+CINCLUDES = -I${srcdir} \
+ -I${srcdir}/../dnssafe \
+ -I${srcdir}/../openssl/include \
+ ${DNS_INCLUDES} ${ISC_INCLUDES}
+
+CDEFINES = -DUSE_MD5 -DDNSSAFE -DOPENSSL
+CWARNINGS =
+
+LIBS = @LIBS@
+
+# Alphabetically
+OBJS = bsafe_link.@O@ dst_api.@O@ dst_parse.@O@ hmac_link.@O@ \
+ openssl_link.@O@ openssldh_link.@O@ opensslmd5_link.@O@ \
+ dst_result.@O@ dst_support.@O@ dst_lib.@O@
+
+SRCS = bsafe_link.c dst_api.c dst_parse.c hmac_link.c \
+ openssl_link.c openssldh_link.c opensslmd5_link.c \
+ dst_result.c dst_support.c dst_lib.c
+
+SUBDIRS = include
+TARGETS = ${OBJS}
+
+@BIND9_MAKE_RULES@
diff --git a/lib/dns/sec/dst/bsafe_link.c b/lib/dns/sec/dst/bsafe_link.c
new file mode 100644
index 00000000..05fc9d96
--- /dev/null
+++ b/lib/dns/sec/dst/bsafe_link.c
@@ -0,0 +1,1093 @@
+#if defined(BSAFE) || defined(DNSSAFE)
+
+/*
+ * Portions Copyright (c) 1995-1999 by Network Associates, Inc.
+ *
+ * Permission to use, copy modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND NETWORK ASSOCIATES
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * NETWORK ASSOCIATES BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THE SOFTWARE.
+ */
+
+/*
+ * Principal Author: Brian Wellington
+ * $Id: bsafe_link.c,v 1.11 1999/10/29 12:56:56 marka Exp $
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+
+#include <isc/assertions.h>
+#include <isc/buffer.h>
+#include <isc/int.h>
+#include <isc/region.h>
+
+#include <dns/keyvalues.h>
+
+#include "dst_internal.h"
+#include "dst_parse.h"
+
+# ifdef BSAFE
+# include <aglobal.h>
+# include <bsafe.h>
+# else
+# include <global.h>
+# include <bsafe2.h>
+# endif
+
+typedef struct bsafekey {
+ B_KEY_OBJ rk_Private_Key;
+ B_KEY_OBJ rk_Public_Key;
+} RSA_Key;
+
+#define MAX_RSA_MODULUS_BITS 2048
+#define MAX_RSA_MODULUS_LEN (MAX_RSA_MODULUS_BITS/8)
+#define MAX_RSA_PRIME_LEN (MAX_RSA_MODULUS_LEN/2)
+
+#define NULL_SURRENDER (A_SURRENDER_CTX *)NULL_PTR
+#define NULL_RANDOM (B_ALGORITHM_OBJ)NULL_PTR
+
+static struct dst_func bsafe_functions;
+
+static B_ALGORITHM_METHOD *CHOOSER[] =
+{
+ &AM_MD5,
+ &AM_MD5_RANDOM,
+ &AM_RSA_KEY_GEN,
+ &AM_RSA_ENCRYPT,
+ &AM_RSA_DECRYPT,
+ &AM_RSA_CRT_ENCRYPT,
+ &AM_RSA_CRT_DECRYPT,
+ (B_ALGORITHM_METHOD *) NULL_PTR
+};
+
+static unsigned char pkcs1[] =
+{
+ 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,
+ 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00,
+ 0x04, 0x10
+};
+
+static dst_result_t dst_bsafe_md5digest(const unsigned int mode,
+ B_ALGORITHM_OBJ *digest_obj,
+ isc_region_t *data,
+ isc_buffer_t *digest);
+
+static int dst_bsafe_key_size(RSA_Key *r_key);
+static isc_boolean_t dst_s_bsafe_itemcmp(ITEM i1, ITEM i2);
+
+static dst_result_t dst_bsafe_sign(const unsigned int mode, dst_key_t *key,
+ void **context, isc_region_t *data,
+ isc_buffer_t *sig, isc_mem_t *mctx);
+static dst_result_t dst_bsafe_verify(const unsigned int mode,
+ dst_key_t *key,
+ void **context, isc_region_t *data,
+ isc_region_t *sig, isc_mem_t *mctx);
+static isc_boolean_t dst_bsafe_compare(const dst_key_t *key1,
+ const dst_key_t *key2);
+static dst_result_t dst_bsafe_generate(dst_key_t *key, int exp,
+ isc_mem_t *mctx);
+static isc_boolean_t dst_bsafe_isprivate(const dst_key_t *key);
+static void dst_bsafe_destroy(void *key, isc_mem_t *mctx);
+static dst_result_t dst_bsafe_to_dns(const dst_key_t *in_key,
+ isc_buffer_t *data);
+static dst_result_t dst_bsafe_from_dns(dst_key_t *key, isc_buffer_t *data,
+ isc_mem_t *mctx);
+static dst_result_t dst_bsafe_to_file(const dst_key_t *key);
+static dst_result_t dst_bsafe_from_file(dst_key_t *key,
+ const isc_uint16_t id,
+ isc_mem_t *mctx);
+
+/*
+ * dst_s_bsafersa_init()
+ * Sets up function pointers for BSAFE/DNSSAFE related functions
+ */
+void
+dst_s_bsafersa_init() {
+ REQUIRE(dst_t_func[DST_ALG_RSA] == NULL);
+ dst_t_func[DST_ALG_RSA] = &bsafe_functions;
+ memset(&bsafe_functions, 0, sizeof(struct dst_func));
+ bsafe_functions.sign = dst_bsafe_sign;
+ bsafe_functions.verify = dst_bsafe_verify;
+ bsafe_functions.computesecret = NULL;
+ bsafe_functions.compare = dst_bsafe_compare;
+ bsafe_functions.paramcompare = NULL;
+ bsafe_functions.generate = dst_bsafe_generate;
+ bsafe_functions.isprivate = dst_bsafe_isprivate;
+ bsafe_functions.destroy = dst_bsafe_destroy;
+ bsafe_functions.to_dns = dst_bsafe_to_dns;
+ bsafe_functions.from_dns = dst_bsafe_from_dns;
+ bsafe_functions.to_file = dst_bsafe_to_file;
+ bsafe_functions.from_file = dst_bsafe_from_file;
+}
+
+/*
+ * dst_bsafe_sign
+ * Call BSAFE signing functions to sign a block of data.
+ * There are three steps to signing, INIT (initialize structures),
+ * UPDATE (hash (more) data), FINAL (generate a signature). This
+ * routine performs one or more of these steps.
+ * Parameters
+ * mode DST_SIGMODE_{INIT_UPDATE_FINAL|ALL}
+ * key key to use for signing
+ * context the context to use for this computation
+ * data data to be signed
+ * signature buffer to store signature
+ * mctx memory context for temporary allocations
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+static dst_result_t
+dst_bsafe_sign(const unsigned int mode, dst_key_t *key, void **context,
+ isc_region_t *data, isc_buffer_t *sig, isc_mem_t *mctx)
+{
+ int status = 0;
+ B_ALGORITHM_OBJ *md5_ctx = NULL;
+ unsigned char digest_array[DNS_SIG_RSAMAXSIZE];
+ isc_buffer_t digest;
+ isc_region_t sig_region, digest_region;
+ dst_result_t ret;
+
+ if (mode & DST_SIGMODE_INIT) {
+ md5_ctx = (B_ALGORITHM_OBJ *) isc_mem_get(mctx,
+ sizeof(*md5_ctx));
+ if (md5_ctx == NULL)
+ return (ISC_R_NOMEMORY);
+ if ((status = B_CreateAlgorithmObject(md5_ctx)) != 0)
+ return (ISC_R_NOMEMORY);
+ if ((status = B_SetAlgorithmInfo(*md5_ctx, AI_MD5, NULL)) != 0)
+ return (ISC_R_NOMEMORY);
+ }
+ else if (context != NULL)
+ md5_ctx = (B_ALGORITHM_OBJ *) *context;
+ REQUIRE (md5_ctx != NULL);
+
+ isc_buffer_init(&digest, digest_array, sizeof(digest_array),
+ ISC_BUFFERTYPE_BINARY);
+ ret = dst_bsafe_md5digest(mode, md5_ctx, data, &digest);
+ if (ret != ISC_R_SUCCESS || (mode & DST_SIGMODE_FINAL)) {
+ B_DestroyAlgorithmObject(md5_ctx);
+ memset(md5_ctx, 0, sizeof(*md5_ctx));
+ isc_mem_put(mctx, md5_ctx, sizeof(*md5_ctx));
+ if (ret != ISC_R_SUCCESS)
+ return (ret);
+ }
+
+ if (mode & DST_SIGMODE_FINAL) {
+ RSA_Key *rkey;
+ B_ALGORITHM_OBJ rsaEncryptor = (B_ALGORITHM_OBJ) NULL_PTR;
+ unsigned int written = 0;
+
+ isc_buffer_available(sig, &sig_region);
+ isc_buffer_remaining(&digest, &digest_region);
+
+ if (sig_region.length * 8 < (unsigned int) key->key_size)
+ return (ISC_R_NOSPACE);
+
+ rkey = (RSA_Key *) key->opaque;
+ if (rkey == NULL)
+ return (DST_R_NULLKEY);
+ if (rkey->rk_Private_Key == NULL)
+ return (DST_R_NOTPRIVATEKEY);
+
+ if ((status = B_CreateAlgorithmObject(&rsaEncryptor)) != 0)
+ return (ISC_R_NOMEMORY);
+ if ((status = B_SetAlgorithmInfo(rsaEncryptor,
+ AI_PKCS_RSAPrivate,
+ NULL_PTR)) != 0)
+
+ goto finalfail;
+ if ((status = B_EncryptInit(rsaEncryptor,
+ rkey->rk_Private_Key,
+ CHOOSER, NULL_SURRENDER)) != 0)
+ goto finalfail;
+ if ((status = B_EncryptUpdate(rsaEncryptor, sig_region.base,
+ &written, sig_region.length,
+ pkcs1, sizeof(pkcs1),
+ NULL_PTR, NULL_SURRENDER)) != 0)
+ goto finalfail;
+
+ if (written > 0) {
+ isc_buffer_add(sig, written);
+ isc_buffer_available(sig, &sig_region);
+ written = 0;
+ }
+
+ if ((status = B_EncryptUpdate(rsaEncryptor, sig_region.base,
+ &written, sig_region.length,
+ digest_region.base,
+ digest_region.length,
+ NULL_PTR, NULL_SURRENDER)) != 0)
+ goto finalfail;
+
+ if (written > 0) {
+ isc_buffer_add(sig, written);
+ isc_buffer_available(sig, &sig_region);
+ written = 0;
+ }
+
+ isc_buffer_forward(&digest, digest_region.length);
+
+ if ((status = B_EncryptFinal(rsaEncryptor, sig_region.base,
+ &written, sig_region.length,
+ NULL_PTR, NULL_SURRENDER)) != 0)
+ goto finalfail;
+ isc_buffer_add(sig, written);
+
+ B_DestroyAlgorithmObject(&rsaEncryptor);
+ return (ISC_R_SUCCESS);
+ finalfail:
+ B_DestroyAlgorithmObject(&rsaEncryptor);
+ return (DST_R_SIGNFINALFAILURE);
+ }
+ else
+ *context = md5_ctx;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+/*
+ * dst_bsafe_verify
+ * Calls BSAFE verification routines. There are three steps to
+ * verification, INIT (initialize structures), UPDATE (hash (more) data),
+ * FINAL (generate a signature). This routine performs one or more of
+ * these steps.
+ * Parameters
+ * mode DST_SIGMODE_{INIT_UPDATE_FINAL|ALL}
+ * key key to use for verifying
+ * context the context to use for this computation
+ * data signed data
+ * signature signature
+ * mctx memory context for temporary allocations
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+static dst_result_t
+dst_bsafe_verify(const unsigned int mode, dst_key_t *key, void **context,
+ isc_region_t *data, isc_region_t *sig, isc_mem_t *mctx)
+{
+ B_ALGORITHM_OBJ *md5_ctx = NULL;
+ unsigned char digest_array[DST_HASH_SIZE];
+ unsigned char work_area[DST_HASH_SIZE + sizeof(pkcs1)];
+ isc_buffer_t work, digest;
+ isc_region_t work_region, digest_region;
+ dst_result_t ret;
+ int status = 0;
+
+ if (mode & DST_SIGMODE_INIT) {
+ md5_ctx = (B_ALGORITHM_OBJ *) isc_mem_get(mctx,
+ sizeof(*md5_ctx));
+ if (md5_ctx == NULL)
+ return (ISC_R_NOMEMORY);
+ if ((status = B_CreateAlgorithmObject(md5_ctx)) != 0)
+ return (ISC_R_NOMEMORY);
+ if ((status = B_SetAlgorithmInfo(*md5_ctx, AI_MD5, NULL)) != 0)
+ return (ISC_R_NOMEMORY);
+ }
+ else if (context != NULL)
+ md5_ctx = (B_ALGORITHM_OBJ *) *context;
+ REQUIRE (md5_ctx != NULL);
+
+ isc_buffer_init(&digest, digest_array, sizeof(digest_array),
+ ISC_BUFFERTYPE_BINARY);
+ ret = dst_bsafe_md5digest(mode, md5_ctx, data, &digest);
+ if (ret != ISC_R_SUCCESS || (mode & DST_SIGMODE_FINAL)) {
+ B_DestroyAlgorithmObject(md5_ctx);
+ memset(md5_ctx, 0, sizeof(*md5_ctx));
+ isc_mem_put(mctx, md5_ctx, sizeof(*md5_ctx));
+ if (ret != ISC_R_SUCCESS)
+ return (ret);
+ }
+
+ if (mode & DST_SIGMODE_FINAL) {
+ RSA_Key *rkey;
+ B_ALGORITHM_OBJ rsaEncryptor = (B_ALGORITHM_OBJ) NULL_PTR;
+ unsigned int written = 0;
+
+ isc_buffer_init(&work, work_area, sizeof(work_area),
+ ISC_BUFFERTYPE_BINARY);
+
+ isc_buffer_available(&work, &work_region);
+
+ rkey = (RSA_Key *) key->opaque;
+ if (rkey == NULL)
+ return (DST_R_NULLKEY);
+ if (rkey->rk_Public_Key == NULL)
+ return (DST_R_NOTPUBLICKEY);
+ if ((status = B_CreateAlgorithmObject(&rsaEncryptor)) != 0)
+ return (ISC_R_NOMEMORY);
+ if ((status = B_SetAlgorithmInfo(rsaEncryptor,
+ AI_PKCS_RSAPublic,
+ NULL_PTR)) != 0)
+ goto finalfail;
+ if ((status = B_DecryptInit(rsaEncryptor, rkey->rk_Public_Key,
+ CHOOSER, NULL_SURRENDER)) != 0)
+ goto finalfail;
+
+ if ((status = B_DecryptUpdate(rsaEncryptor, work_region.base,
+ &written, work_region.length,
+ sig->base, sig->length,
+ NULL_PTR, NULL_SURRENDER)) != 0)
+ goto finalfail;
+
+ if (written > 0) {
+ isc_buffer_add(&work, written);
+ isc_buffer_available(&work, &work_region);
+ written = 0;
+ }
+
+ if ((status = B_DecryptFinal(rsaEncryptor, work_region.base,
+ &written, work_region.length,
+ NULL_PTR, NULL_SURRENDER)) != 0)
+ goto finalfail;
+
+ if (written > 0)
+ isc_buffer_add(&work, written);
+
+ isc_buffer_used(&work, &work_region);
+ isc_buffer_used(&digest, &digest_region);
+
+ B_DestroyAlgorithmObject(&rsaEncryptor);
+ /* skip PKCS#1 header in output from Decrypt function */
+ if (memcmp(digest_region.base, work_region.base + sizeof(pkcs1),
+ digest_region.length) == 0)
+ return (ISC_R_SUCCESS);
+ else
+ return (DST_R_VERIFYFINALFAILURE);
+ finalfail:
+ B_DestroyAlgorithmObject(&rsaEncryptor);
+ return (DST_R_VERIFYFINALFAILURE);
+ }
+ else
+ *context = md5_ctx;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+/*
+ * dst_bsafe_isprivate
+ * Is this a private key?
+ * Parameters
+ * key DST KEY structure
+ * Returns
+ * ISC_TRUE
+ * ISC_FALSE
+ */
+static isc_boolean_t
+dst_bsafe_isprivate(const dst_key_t *key) {
+ RSA_Key *rkey = (RSA_Key *) key->opaque;
+ return (ISC_TF(rkey != NULL && rkey->rk_Private_Key != NULL));
+}
+
+
+/*
+ * dst_bsafe_to_dns
+ * Converts key from RSA to DNS distribution format
+ * Parameters
+ * key DST KEY structure
+ * data output data
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+
+static dst_result_t
+dst_bsafe_to_dns(const dst_key_t *key, isc_buffer_t *data) {
+ B_KEY_OBJ public;
+ A_RSA_KEY *pub = NULL;
+ isc_region_t r;
+ int status;
+
+ REQUIRE(key->opaque != NULL);
+
+ public = (B_KEY_OBJ)((RSA_Key *)key->opaque)->rk_Public_Key;
+
+ if ((status = B_GetKeyInfo((POINTER *)&pub, public, KI_RSAPublic)) != 0)
+ return (DST_R_INVALIDPUBLICKEY);
+ isc_buffer_available(data, &r);
+ if (pub->exponent.len < 256) { /* key exponent is <= 2040 bits */
+ if (r.length < 1 + pub->exponent.len + pub->modulus.len)
+ return (ISC_R_NOSPACE);
+ isc_buffer_putuint8(data, (isc_uint8_t)pub->exponent.len);
+ } else { /* key exponent is > 2040 bits */
+ if (r.length < 3 + pub->exponent.len + pub->modulus.len)
+ return (ISC_R_NOSPACE);
+ isc_buffer_putuint8(data, 0);
+ isc_buffer_putuint16(data, (isc_uint16_t)pub->exponent.len);
+ }
+
+ isc_buffer_available(data, &r);
+ memcpy(r.base, pub->exponent.data, pub->exponent.len);
+ r.base += pub->exponent.len;
+ memcpy(r.base, pub->modulus.data, pub->modulus.len);
+ isc_buffer_add(data, pub->exponent.len + pub->modulus.len);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+/*
+ * dst_bsafe_from_dns
+ * Converts from a DNS KEY RR format to an RSA KEY.
+ * Parameters
+ * key Partially filled key structure
+ * data Buffer containing key in DNS format
+ * Return
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+static dst_result_t
+dst_bsafe_from_dns(dst_key_t *key, isc_buffer_t *data, isc_mem_t *mctx) {
+ unsigned int bytes;
+ RSA_Key *rkey;
+ A_RSA_KEY *public;
+ isc_region_t r;
+ isc_buffer_t b;
+ int status;
+
+ isc_buffer_remaining(data, &r);
+ if (r.length == 0)
+ return (ISC_R_SUCCESS);
+
+ rkey = (RSA_Key *) isc_mem_get(mctx, sizeof(RSA_Key));
+ if (rkey == NULL)
+ return (ISC_R_NOMEMORY);
+
+ memset(rkey, 0, sizeof(RSA_Key));
+
+ if (B_CreateKeyObject(&rkey->rk_Public_Key) != 0) {
+ isc_mem_put(mctx, rkey, sizeof(RSA_Key));
+ return (ISC_R_NOMEMORY);
+ }
+
+ /* length of exponent in bytes */
+ bytes = isc_buffer_getuint8(data);
+ if (bytes == 0) /* special case for long exponents */
+ bytes = isc_buffer_getuint16(data);
+
+ if (bytes > MAX_RSA_MODULUS_LEN) {
+ dst_bsafe_destroy(rkey, mctx);
+ return (DST_R_INVALIDPUBLICKEY);
+ }
+
+ public = (A_RSA_KEY *) isc_mem_get(mctx, sizeof(A_RSA_KEY));
+ if (public == NULL)
+ return (ISC_R_NOMEMORY);
+ memset(public, 0, sizeof(*public));
+ public->exponent.len = bytes;
+ public->exponent.data = (unsigned char *) isc_mem_get(mctx, bytes);
+ if (public->exponent.data == NULL) {
+ isc_mem_put(mctx, public, sizeof(*public));
+ return (ISC_R_NOMEMORY);
+ }
+
+ isc_buffer_remaining(data, &r);
+ if (r.length < bytes) {
+ isc_mem_put(mctx, public, sizeof(*public));
+ return (ISC_R_NOMEMORY);
+ }
+ memcpy(public->exponent.data, r.base, bytes);
+ isc_buffer_forward(data, bytes);
+
+ isc_buffer_remaining(data, &r);
+
+ if (r.length > MAX_RSA_MODULUS_LEN) {
+ dst_bsafe_destroy(rkey, mctx);
+ memset(public->exponent.data, 0, bytes);
+ isc_mem_put(mctx, public->exponent.data, bytes);
+ isc_mem_put(mctx, public, sizeof(*public));
+ return (ISC_R_NOMEMORY);
+ }
+ public->modulus.len = r.length;
+ public->modulus.data = (unsigned char *) isc_mem_get(mctx, r.length);
+ if (public->modulus.data == NULL) {
+ dst_bsafe_destroy(rkey, mctx);
+ memset(public->exponent.data, 0, bytes);
+ isc_mem_put(mctx, public->exponent.data, bytes);
+ isc_mem_put(mctx, public, sizeof(*public));
+ return (ISC_R_NOMEMORY);
+ }
+ memcpy(public->modulus.data, r.base, r.length);
+ isc_buffer_forward(data, r.length);
+
+ status = B_SetKeyInfo(rkey->rk_Public_Key, KI_RSAPublic,
+ (POINTER) public);
+ if (status != 0)
+ return (DST_R_INVALIDPUBLICKEY);
+
+ isc_buffer_init(&b, public->modulus.data + public->modulus.len - 3,
+ 2, ISC_BUFFERTYPE_BINARY);
+ isc_buffer_add(&b, 2);
+ key->key_id = isc_buffer_getuint16(&b);
+ key->key_size = dst_bsafe_key_size(rkey);
+
+ memset(public->exponent.data, 0, public->exponent.len);
+ isc_mem_put(mctx, public->exponent.data, public->exponent.len);
+ memset(public->modulus.data, 0, public->modulus.len);
+ isc_mem_put(mctx, public->modulus.data, public->modulus.len);
+ isc_mem_put(mctx, public, sizeof(*public));
+
+ key->opaque = (void *) rkey;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+/*
+ * dst_bsafe_to_file
+ * Encodes an RSA Key into the portable file format.
+ * Parameters
+ * key DST KEY structure
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+static dst_result_t
+dst_bsafe_to_file(const dst_key_t *key) {
+ int cnt = 0;
+ B_KEY_OBJ rkey;
+ A_PKCS_RSA_PRIVATE_KEY *private = NULL;
+ dst_private_t priv;
+
+ if (key->opaque == NULL)
+ return (DST_R_NULLKEY);
+
+ rkey = (B_KEY_OBJ)((RSA_Key *) key->opaque)->rk_Private_Key;
+
+ B_GetKeyInfo((POINTER *) &private, rkey, KI_PKCS_RSAPrivate);
+
+ priv.elements[cnt].tag = TAG_RSA_MODULUS;
+ priv.elements[cnt].data = private->modulus.data;
+ priv.elements[cnt++].length = private->modulus.len;
+
+ priv.elements[cnt].tag = TAG_RSA_PUBLICEXPONENT;
+ priv.elements[cnt].data = private->publicExponent.data;
+ priv.elements[cnt++].length = private->publicExponent.len;
+
+ priv.elements[cnt].tag = TAG_RSA_PRIVATEEXPONENT;
+ priv.elements[cnt].data = private->privateExponent.data;
+ priv.elements[cnt++].length = private->privateExponent.len;
+
+ priv.elements[cnt].tag = TAG_RSA_PRIME1;
+ priv.elements[cnt].data = private->prime[0].data;
+ priv.elements[cnt++].length = private->prime[0].len;
+
+ priv.elements[cnt].tag = TAG_RSA_PRIME2;
+ priv.elements[cnt].data = private->prime[1].data;
+ priv.elements[cnt++].length = private->prime[1].len;
+
+ priv.elements[cnt].tag = TAG_RSA_EXPONENT1;
+ priv.elements[cnt].data = private->primeExponent[0].data;
+ priv.elements[cnt++].length = private->primeExponent[0].len;
+
+ priv.elements[cnt].tag = TAG_RSA_EXPONENT2;
+ priv.elements[cnt].data = private->primeExponent[1].data;
+ priv.elements[cnt++].length = private->primeExponent[1].len;
+
+ priv.elements[cnt].tag = TAG_RSA_COEFFICIENT;
+ priv.elements[cnt].data = private->coefficient.data;
+ priv.elements[cnt++].length = private->coefficient.len;
+
+ priv.nelements = cnt;
+ return (dst_s_write_private_key_file(key->key_name, key->key_alg,
+ key->key_id, &priv));
+}
+
+
+/*
+ * dst_bsafe_from_file
+ * Converts contents of a private key file into a private RSA key.
+ * Parameters
+ * key Partially filled RSA KEY structure
+ * id The key id
+ * path The directory that the file will be read from
+ * Return
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+
+static dst_result_t
+dst_bsafe_from_file(dst_key_t *key, const isc_uint16_t id, isc_mem_t *mctx) {
+ dst_private_t priv;
+ dst_result_t ret;
+ isc_buffer_t b;
+ int i;
+ RSA_Key *rkey = NULL;
+ A_RSA_KEY *public = NULL;
+ A_PKCS_RSA_PRIVATE_KEY *private = NULL;
+ int status = 0;
+#define DST_RET(a) {ret = a; goto err;}
+
+ /* read private key file */
+ ret = dst_s_parse_private_key_file(key->key_name, key->key_alg,
+ id, &priv, mctx);
+ if (ret != ISC_R_SUCCESS)
+ return (ret);
+ /* allocate key*/
+ private = (A_PKCS_RSA_PRIVATE_KEY *)
+ isc_mem_get(mctx, sizeof(A_PKCS_RSA_PRIVATE_KEY));
+ if (private == NULL)
+ DST_RET(ISC_R_NOMEMORY);
+ memset(private, 0, sizeof(*private));
+
+ public = (A_RSA_KEY *) isc_mem_get(mctx, sizeof(A_RSA_KEY));
+ if (public == NULL)
+ DST_RET(ISC_R_NOMEMORY);
+ memset(public, 0, sizeof(*public));
+
+ for (i=0; i < priv.nelements; i++) {
+ int len = priv.elements[i].length;
+ unsigned char *data = priv.elements[i].data;
+
+ switch (priv.elements[i].tag){
+ case TAG_RSA_MODULUS:
+ public->modulus.len = len;
+ private->modulus.len = len;
+ public->modulus.data = data;
+ private->modulus.data = data;
+ break;
+ case TAG_RSA_PUBLICEXPONENT:
+ public->exponent.len = len;
+ private->publicExponent.len = len;
+ public->exponent.data = data;
+ private->publicExponent.data = data;
+ break;
+ case TAG_RSA_PRIVATEEXPONENT:
+ private->privateExponent.len = len;
+ private->privateExponent.data = data;
+ break;
+ case TAG_RSA_PRIME1:
+ private->prime[0].len = len;
+ private->prime[0].data = data;
+ break;
+ case TAG_RSA_PRIME2:
+ private->prime[1].len = len;
+ private->prime[1].data = data;
+ break;
+ case TAG_RSA_EXPONENT1:
+ private->primeExponent[0].len = len;
+ private->primeExponent[0].data = data;
+ break;
+ case TAG_RSA_EXPONENT2:
+ private->primeExponent[1].len = len;
+ private->primeExponent[1].data = data;
+ break;
+ case TAG_RSA_COEFFICIENT:
+ private->coefficient.len = len;
+ private->coefficient.data = data;
+ break;
+ }
+ }
+
+ isc_buffer_init(&b, public->modulus.data + public->modulus.len - 3,
+ 2, ISC_BUFFERTYPE_BINARY);
+ isc_buffer_add(&b, 2);
+ key->key_id = isc_buffer_getuint16(&b);
+ if (key->key_id != id)
+ DST_RET(DST_R_INVALIDPRIVATEKEY);
+
+ rkey = (RSA_Key *) isc_mem_get(mctx, sizeof(RSA_Key));
+ if (rkey == NULL)
+ DST_RET(ISC_R_NOMEMORY);
+ memset(rkey, 0, sizeof(*rkey));
+ if ((status = B_CreateKeyObject(&(rkey->rk_Public_Key))) != 0)
+ DST_RET(ISC_R_NOMEMORY);
+ if ((status = B_SetKeyInfo(rkey->rk_Public_Key, KI_RSAPublic,
+ (POINTER) public)) != 0)
+ DST_RET(DST_R_INVALIDPUBLICKEY);
+
+ if ((status = B_CreateKeyObject(&rkey->rk_Private_Key)) != 0)
+ DST_RET(ISC_R_NOMEMORY);
+
+ if ((status = B_SetKeyInfo(rkey->rk_Private_Key, KI_PKCS_RSAPrivate,
+ (POINTER) private)) != 0)
+ DST_RET(DST_R_INVALIDPRIVATEKEY);
+
+ key->key_size = dst_bsafe_key_size(rkey);
+ key->opaque = rkey;
+ rkey = NULL;
+ err:
+ if (private != NULL) {
+ memset(private, 0, sizeof(*private));
+ isc_mem_put(mctx, private, sizeof(*private));
+ }
+ if (public != NULL) {
+ memset(public, 0, sizeof(*public));
+ isc_mem_put(mctx, public, sizeof(*public));
+ }
+ if (rkey != NULL) {
+ memset(rkey, 0, sizeof(*rkey));
+ isc_mem_put(mctx, rkey, sizeof(*rkey));
+ }
+ dst_s_free_private_structure_fields(&priv, mctx);
+ memset(&priv, 0, sizeof(priv));
+ return (ret);
+}
+
+/*
+ * dst_bsafe_destroy
+ * Frees all dynamically allocated structures in key.
+ */
+static void
+dst_bsafe_destroy(void *key, isc_mem_t *mctx)
+{
+ RSA_Key *rkey = (RSA_Key *) key;
+ if (rkey == NULL)
+ return;
+ if (rkey->rk_Private_Key != NULL)
+ B_DestroyKeyObject(&rkey->rk_Private_Key);
+ if (rkey->rk_Public_Key != NULL)
+ B_DestroyKeyObject(&rkey->rk_Public_Key);
+ memset(rkey, 0, sizeof(*rkey));
+ isc_mem_put(mctx, rkey, sizeof(*rkey));
+}
+
+
+/*
+ * dst_bsafe_generate
+ * Generates unique keys that are hard to predict.
+ * Parameters
+ * key DST Key structure
+ * exp the public exponent
+ * mctx memory context to allocate key
+ * Return
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+
+static dst_result_t
+dst_bsafe_generate(dst_key_t *key, int exp, isc_mem_t *mctx) {
+ int status;
+ B_KEY_OBJ private;
+ B_KEY_OBJ public;
+ B_ALGORITHM_OBJ keypairGenerator = NULL;
+ B_ALGORITHM_OBJ randomAlgorithm = NULL;
+ A_RSA_KEY_GEN_PARAMS keygenParams;
+ char exponent[4];
+ int exponent_len = 0;
+ RSA_Key *rsa;
+ unsigned char randomSeed[256];
+ isc_buffer_t b, rand;
+ A_RSA_KEY *pub = NULL;
+ dst_result_t ret;
+
+ rsa = (RSA_Key *) isc_mem_get(mctx, sizeof(RSA_Key));
+ if (rsa == NULL)
+ return (ISC_R_NOMEMORY);
+
+ memset(rsa, 0, sizeof(*rsa));
+ keygenParams.publicExponent.data = NULL;
+
+#define do_fail(code) {ret = code; goto fail;}
+ if ((status = B_CreateAlgorithmObject(&keypairGenerator)) != 0)
+ do_fail(ISC_R_NOMEMORY);
+
+ keygenParams.modulusBits = key->key_size;
+
+ /* exp = 0 or 1 are special (mean 3 or F4) */
+ if (exp == 0)
+ exp = 3;
+ else if (exp == 1)
+ exp = 65537;
+
+ /* Now encode the exponent and its length */
+ if (exp < 256) {
+ exponent_len = 1;
+ exponent[0] = exp;
+ } else if (exp < (1 << 16)) {
+ exponent_len = 2;
+ exponent[0] = exp >> 8;
+ exponent[1] = exp;
+ } else if (exp < (1 << 24)) {
+ exponent_len = 3;
+ exponent[0] = exp >> 16;
+ exponent[1] = exp >> 8;
+ exponent[2] = exp;
+ } else {
+ exponent_len = 4;
+ exponent[0] = exp >> 24;
+ exponent[1] = exp >> 16;
+ exponent[2] = exp >> 8;
+ exponent[3] = exp;
+ }
+
+ keygenParams.publicExponent.data = (unsigned char *) isc_mem_get(mctx,
+ exponent_len);
+ if (keygenParams.publicExponent.data == NULL)
+ do_fail(ISC_R_NOMEMORY);
+
+ memcpy(keygenParams.publicExponent.data, exponent, exponent_len);
+ keygenParams.publicExponent.len = exponent_len;
+ if ((status = B_SetAlgorithmInfo
+ (keypairGenerator, AI_RSAKeyGen, (POINTER) &keygenParams)) != 0)
+ do_fail(DST_R_INVALIDPARAM);
+
+ isc_mem_put(mctx, keygenParams.publicExponent.data, exponent_len);
+ keygenParams.publicExponent.data = NULL;
+
+ if ((status = B_GenerateInit(keypairGenerator, CHOOSER,
+ NULL_SURRENDER)) != 0)
+ do_fail(ISC_R_NOMEMORY);
+
+ if ((status = B_CreateKeyObject(&public)) != 0)
+ do_fail(ISC_R_NOMEMORY);
+
+ if ((status = B_CreateKeyObject(&private)) != 0)
+ do_fail(ISC_R_NOMEMORY);
+
+ if ((status = B_CreateAlgorithmObject(&randomAlgorithm)) != 0)
+ do_fail(ISC_R_NOMEMORY);
+
+ if ((status = B_SetAlgorithmInfo(randomAlgorithm, AI_MD5Random,
+ NULL_PTR)) != 0)
+ do_fail(ISC_R_NOMEMORY);
+
+ if ((status = B_RandomInit(randomAlgorithm, CHOOSER,
+ NULL_SURRENDER)) != 0)
+ do_fail(ISC_R_NOMEMORY);
+
+ isc_buffer_init(&rand, randomSeed, sizeof(randomSeed),
+ ISC_BUFFERTYPE_BINARY);
+ ret = dst_random_get(sizeof(randomSeed), &rand);
+ if (ret != ISC_R_SUCCESS)
+ goto fail;
+
+ if ((status = B_RandomUpdate(randomAlgorithm, randomSeed,
+ sizeof(randomSeed), NULL_SURRENDER)) != 0)
+ do_fail(ISC_R_NOMEMORY);
+
+ memset(randomSeed, 0, sizeof(randomSeed));
+
+ if ((status = B_GenerateKeypair(keypairGenerator, public, private,
+ randomAlgorithm, NULL_SURRENDER)) != 0)
+ do_fail(DST_R_INVALIDPARAM);
+
+ rsa->rk_Private_Key = private;
+ rsa->rk_Public_Key = public;
+ key->opaque = (void *) rsa;
+
+ B_DestroyAlgorithmObject(&keypairGenerator);
+ B_DestroyAlgorithmObject(&randomAlgorithm);
+
+ /* fill in the footprint in generate key */
+ B_GetKeyInfo((POINTER *) &pub, public, KI_RSAPublic);
+
+ isc_buffer_init(&b, pub->modulus.data + pub->modulus.len - 3,
+ 2, ISC_BUFFERTYPE_BINARY);
+ isc_buffer_add(&b, 2);
+ key->key_id = isc_buffer_getuint16(&b);
+ return (ISC_R_SUCCESS);
+
+ fail:
+ if (rsa != NULL) {
+ memset(rsa, 0, sizeof(*rsa));
+ isc_mem_put(mctx, rsa, sizeof(*rsa));
+ }
+ if (keygenParams.publicExponent.data != NULL) {
+ memset(keygenParams.publicExponent.data, 0, exponent_len);
+ isc_mem_put(mctx, keygenParams.publicExponent.data,
+ exponent_len);
+ }
+ if (keypairGenerator != NULL)
+ B_DestroyAlgorithmObject(&keypairGenerator);
+ if (randomAlgorithm != NULL)
+ B_DestroyAlgorithmObject(&randomAlgorithm);
+ return (ret);
+}
+
+
+static isc_boolean_t
+dst_s_bsafe_itemcmp(ITEM i1, ITEM i2) {
+ if (i1.len != i2.len || memcmp (i1.data, i2.data, i1.len) != 0)
+ return (ISC_FALSE);
+ else
+ return (ISC_TRUE);
+}
+
+/**************************************************************************
+ * dst_bsafe_compare
+ * Compare two keys for equality.
+ * Return
+ * ISC_TRUE The keys are equal
+ * ISC_FALSE The keys are not equal
+ */
+static isc_boolean_t
+dst_bsafe_compare(const dst_key_t *key1, const dst_key_t *key2) {
+ int status, s1 = 0, s2 = 0;
+ RSA_Key *rkey1, *rkey2;
+ A_RSA_KEY *public1 = NULL, *public2 = NULL;
+ A_PKCS_RSA_PRIVATE_KEY *p1 = NULL, *p2 = NULL;
+
+ rkey1 = (RSA_Key *) key1->opaque;
+ rkey2 = (RSA_Key *) key2->opaque;
+
+ if (rkey1 == NULL && rkey2 == NULL)
+ return (ISC_TRUE);
+ else if (rkey1 == NULL || rkey2 == NULL)
+ return (ISC_FALSE);
+
+ if (rkey1->rk_Public_Key)
+ B_GetKeyInfo((POINTER *) &public1, rkey1->rk_Public_Key,
+ KI_RSAPublic);
+ if (rkey2->rk_Public_Key)
+ B_GetKeyInfo((POINTER *) &public2, rkey2->rk_Public_Key,
+ KI_RSAPublic);
+ if (public1 == NULL && public2 == NULL)
+ return (ISC_TRUE);
+ else if (public1 == NULL || public2 == NULL)
+ return (ISC_FALSE);
+
+ status = dst_s_bsafe_itemcmp(public1->modulus, public2->modulus) ||
+ dst_s_bsafe_itemcmp(public1->exponent, public2->exponent);
+
+ if (status == ISC_FALSE)
+ return (ISC_FALSE);
+
+ if (rkey1->rk_Private_Key != NULL || rkey2->rk_Private_Key != NULL) {
+ if (rkey1->rk_Private_Key == NULL ||
+ rkey2->rk_Private_Key == NULL)
+ return (ISC_FALSE);
+
+ s1 = B_GetKeyInfo((POINTER *) &p1, rkey1->rk_Private_Key,
+ KI_PKCS_RSAPrivate);
+ s2 = B_GetKeyInfo((POINTER *) &p2, rkey2->rk_Private_Key,
+ KI_PKCS_RSAPrivate);
+ if (p1 == NULL || p2 == NULL)
+ return (ISC_FALSE);
+
+ status = dst_s_bsafe_itemcmp(p1->modulus, p2->modulus) &&
+ dst_s_bsafe_itemcmp(p1->publicExponent,
+ p2->publicExponent) &&
+ dst_s_bsafe_itemcmp(p1->privateExponent,
+ p2->privateExponent) &&
+ dst_s_bsafe_itemcmp(p1->prime[0], p2->prime[0]) &&
+ dst_s_bsafe_itemcmp(p1->prime[1], p2->prime[1]) &&
+ dst_s_bsafe_itemcmp(p1->primeExponent[0],
+ p2->primeExponent[0]) &&
+ dst_s_bsafe_itemcmp(p1->primeExponent[1],
+ p2->primeExponent[1]) &&
+ dst_s_bsafe_itemcmp(p1->coefficient, p2->coefficient);
+ if (status == ISC_FALSE)
+ return (ISC_FALSE);
+ }
+ return (ISC_TRUE);
+}
+
+
+/*
+ * dst_bsafe_key_size()
+ * Function to calculate the size of the key in bits
+ */
+static int
+dst_bsafe_key_size(RSA_Key *key)
+{
+ int size;
+ A_PKCS_RSA_PRIVATE_KEY *private = NULL;
+
+ REQUIRE(key != NULL);
+ REQUIRE(key->rk_Private_Key != NULL || key->rk_Public_Key != NULL);
+
+ if (key->rk_Private_Key != NULL)
+ B_GetKeyInfo((POINTER *) &private, key->rk_Private_Key,
+ KI_PKCS_RSAPrivate);
+ else
+ B_GetKeyInfo((POINTER *) &private, key->rk_Public_Key,
+ KI_RSAPublic);
+
+ size = dst_s_calculate_bits(private->modulus.data,
+ private->modulus.len * 8);
+ return (size);
+}
+
+/*
+ * dst_bsafe_md5digest(): function to digest data using MD5 digest function
+ * if needed
+ */
+static dst_result_t
+dst_bsafe_md5digest(const unsigned int mode, B_ALGORITHM_OBJ *digest_obj,
+ isc_region_t *data, isc_buffer_t *digest)
+{
+ int status = 0;
+ unsigned int written = 0;
+ isc_region_t r;
+
+ REQUIRE(digest != NULL);
+ REQUIRE(digest_obj != NULL);
+
+ if ((mode & DST_SIGMODE_INIT) &&
+ (status = B_DigestInit(*digest_obj, (B_KEY_OBJ) NULL,
+ CHOOSER, NULL_SURRENDER)) != 0)
+ return (DST_R_SIGNINITFAILURE);
+
+ if ((mode & DST_SIGMODE_UPDATE) &&
+ (status = B_DigestUpdate(*digest_obj, data->base, data->length,
+ NULL_SURRENDER)) != 0)
+ return (DST_R_SIGNUPDATEFAILURE);
+
+ isc_buffer_available(digest, &r);
+ if (mode & DST_SIGMODE_FINAL) {
+ if (digest == NULL ||
+ (status = B_DigestFinal(*digest_obj, r.base, &written,
+ r.length, NULL_SURRENDER)) != 0)
+ return (DST_R_SIGNFINALFAILURE);
+ isc_buffer_add(digest, written);
+ }
+ return (ISC_R_SUCCESS);
+}
+
+
+/*
+ * define memory functions for bsafe that use the isc_mem functions and a
+ * static context.
+ */
+void
+T_free(POINTER block) {
+ dst_mem_free(block);
+}
+
+POINTER
+T_malloc(unsigned int len) {
+ return (dst_mem_alloc(len));
+}
+
+int
+T_memcmp(POINTER firstBlock, POINTER secondBlock, unsigned int len) {
+ return (memcmp(firstBlock, secondBlock, len));
+}
+
+void
+T_memcpy(POINTER output, POINTER input, unsigned int len) {
+ memcpy(output, input, len);
+}
+
+void
+T_memmove(POINTER output, POINTER input, unsigned int len) {
+ memmove(output, input, len);
+}
+
+void
+T_memset(POINTER output, int value, unsigned int len) {
+ memset(output, value, len);
+}
+
+POINTER
+T_realloc(POINTER block, unsigned int len) {
+ return (dst_mem_realloc(block, len));
+}
+#endif /* BSAFE || DNSSAFE */
diff --git a/lib/dns/sec/dst/dst_api.c b/lib/dns/sec/dst/dst_api.c
new file mode 100644
index 00000000..5cdfedc4
--- /dev/null
+++ b/lib/dns/sec/dst/dst_api.c
@@ -0,0 +1,1092 @@
+/*
+ * Portions Copyright (c) 1995-1999 by Network Associates, Inc.
+ *
+ * Permission to use, copy modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND NETWORK ASSOCIATES
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * NETWORK ASSOCIATES BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THE SOFTWARE.
+ */
+
+/*
+ * Principal Author: Brian Wellington
+ * $Id: dst_api.c,v 1.20 1999/12/23 00:09:04 explorer Exp $
+ */
+
+#include <config.h>
+
+#include <ctype.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <isc/assertions.h>
+#include <isc/buffer.h>
+#include <isc/dir.h>
+#include <isc/error.h>
+#include <isc/int.h>
+#include <isc/lex.h>
+#include <isc/mem.h>
+#include <isc/mutex.h>
+#include <isc/once.h>
+#include <isc/region.h>
+#include <dns/rdata.h>
+#include <dns/keyvalues.h>
+
+#include <openssl/rand.h>
+
+#include "dst_internal.h"
+#include "dst/result.h"
+
+#define KEY_MAGIC 0x44535421U /* DST! */
+
+#define VALID_KEY(key) (key != NULL && key->magic == KEY_MAGIC)
+
+dst_func *dst_t_func[DST_MAX_ALGS];
+
+static isc_mem_t *dst_memory_pool = NULL;
+static isc_once_t once = ISC_ONCE_INIT;
+static isc_mutex_t random_lock;
+
+/* Static functions */
+static void initialize(void);
+static dst_key_t * get_key_struct(const char *name, const int alg,
+ const int flags, const int protocol,
+ const int bits, isc_mem_t *mctx);
+static dst_result_t read_public_key(const char *name,
+ const isc_uint16_t id, int in_alg,
+ isc_mem_t *mctx, dst_key_t **keyp);
+static dst_result_t write_public_key(const dst_key_t *key);
+
+/*
+ * dst_supported_algorithm
+ * This function determines if the crypto system for the specified
+ * algorithm is present.
+ * Parameters
+ * alg The algorithm to test
+ * Returns
+ * ISC_TRUE The algorithm is available.
+ * ISC_FALSE The algorithm is not available.
+ */
+isc_boolean_t
+dst_supported_algorithm(const int alg) {
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+ if (alg >= DST_MAX_ALGS || dst_t_func[alg] == NULL)
+ return (ISC_FALSE);
+ return (ISC_TRUE);
+}
+
+/*
+ * dst_sign
+ * An incremental signing function. Data is signed in steps.
+ * First the context must be initialized (DST_SIGMODE_INIT).
+ * Then data is hashed (DST_SIGMODE_UPDATE). Finally the signature
+ * itself is created (DST_SIGMODE_FINAL). This function can be called
+ * once with DST_SIGMODE_ALL set, or it can be called separately
+ * for each step. The UPDATE step may be repeated.
+ * Parameters
+ * mode A bit mask specifying operation(s) to be performed.
+ * DST_SIGMODE_INIT Initialize digest
+ * DST_SIGMODE_UPDATE Add data to digest
+ * DST_SIGMODE_FINAL Generate signature
+ * DST_SIGMODE_ALL Perform all operations
+ * key The private key used to sign the data
+ * context The state of the operation
+ * data The data to be signed.
+ * sig The buffer to which the signature will be written.
+ * Return
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+dst_result_t
+dst_sign(const unsigned int mode, dst_key_t *key, dst_context_t *context,
+ isc_region_t *data, isc_buffer_t *sig)
+{
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+ REQUIRE(VALID_KEY(key));
+ REQUIRE((mode & DST_SIGMODE_ALL) != 0);
+
+ if ((mode & DST_SIGMODE_UPDATE) != 0)
+ REQUIRE(data != NULL && data->base != NULL);
+
+ if ((mode & DST_SIGMODE_FINAL) != 0)
+ REQUIRE(sig != NULL);
+
+ if (dst_supported_algorithm(key->key_alg) == ISC_FALSE)
+ return (DST_R_UNSUPPORTEDALG);
+ if (key->opaque == NULL)
+ return (DST_R_NULLKEY);
+ if (key->func->sign == NULL)
+ return (DST_R_NOTPRIVATEKEY);
+
+ return (key->func->sign(mode, key, (void **)context, data, sig,
+ key->mctx));
+}
+
+
+/*
+ * dst_verify
+ * An incremental verify function. Data is verified in steps.
+ * First the context must be initialized (DST_SIGMODE_INIT).
+ * Then data is hashed (DST_SIGMODE_UPDATE). Finally the signature
+ * is verified (DST_SIGMODE_FINAL). This function can be called
+ * once with DST_SIGMODE_ALL set, or it can be called separately
+ * for each step. The UPDATE step may be repeated.
+ * Parameters
+ * mode A bit mask specifying operation(s) to be performed.
+ * DST_SIGMODE_INIT Initialize digest
+ * DST_SIGMODE_UPDATE Add data to digest
+ * DST_SIGMODE_FINAL Verify signature
+ * DST_SIGMODE_ALL Perform all operations
+ * key The public key used to verify the signature.
+ * context The state of the operation
+ * data The data to be digested.
+ * sig The signature.
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+
+dst_result_t
+dst_verify(const unsigned int mode, dst_key_t *key, dst_context_t *context,
+ isc_region_t *data, isc_region_t *sig)
+{
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+ REQUIRE(VALID_KEY(key));
+ REQUIRE((mode & DST_SIGMODE_ALL) != 0);
+
+ if ((mode & DST_SIGMODE_UPDATE) != 0)
+ REQUIRE(data != NULL && data->base != NULL);
+
+ if ((mode & DST_SIGMODE_FINAL) != 0)
+ REQUIRE(sig != NULL && sig->base != NULL);
+
+ if (dst_supported_algorithm(key->key_alg) == ISC_FALSE)
+ return (DST_R_UNSUPPORTEDALG);
+ if (key->opaque == NULL)
+ return (DST_R_NULLKEY);
+ if (key->func->verify == NULL)
+ return (DST_R_NOTPUBLICKEY);
+
+ return (key->func->verify(mode, key, (void **)context, data, sig,
+ key->mctx));
+}
+
+/*
+ * dst_digest
+ * An incremental digest function. Data is digested in steps.
+ * First the context must be initialized (DST_SIGMODE_INIT).
+ * Then data is hashed (DST_SIGMODE_UPDATE). Finally the digest
+ * is generated (DST_SIGMODE_FINAL). This function can be called
+ * once with DST_SIGMODE_ALL set, or it can be called separately
+ * for each step. The UPDATE step may be repeated.
+ * Parameters
+ * mode A bit mask specifying operation(s) to be performed.
+ * DST_SIGMODE_INIT Initialize digest
+ * DST_SIGMODE_UPDATE Add data to digest
+ * DST_SIGMODE_FINAL Complete digest
+ * DST_SIGMODE_ALL Perform all operations
+ * alg The digest algorithm to use
+ * context The state of the operation
+ * data The data to be digested.
+ * sig The sdigest.
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+dst_result_t
+dst_digest(const unsigned int mode, const unsigned int alg,
+ dst_context_t *context, isc_region_t *data, isc_buffer_t *digest)
+{
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+ REQUIRE((mode & DST_SIGMODE_ALL) != 0);
+
+ if ((mode & DST_SIGMODE_UPDATE) != 0)
+ REQUIRE(data != NULL && data->base != NULL);
+
+ if ((mode & DST_SIGMODE_FINAL) != 0)
+ REQUIRE(digest != NULL);
+
+ if (alg != DST_DIGEST_MD5)
+ return (DST_R_UNSUPPORTEDALG);
+
+ return (dst_s_md5(mode, context, data, digest, dst_memory_pool));
+}
+
+
+/*
+ * dst_computesecret
+ * A function to compute a shared secret from two (Diffie-Hellman) keys.
+ * Parameters
+ * pub The public key
+ * priv The private key
+ * secret A buffer into which the secret is written
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+dst_result_t
+dst_computesecret(const dst_key_t *pub, const dst_key_t *priv,
+ isc_buffer_t *secret)
+{
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+ REQUIRE(VALID_KEY(pub) && VALID_KEY(priv));
+ REQUIRE(secret != NULL);
+
+ if (dst_supported_algorithm(pub->key_alg) == ISC_FALSE ||
+ dst_supported_algorithm(priv->key_alg) == ISC_FALSE)
+ return (DST_R_UNSUPPORTEDALG);
+
+ if (pub->opaque == NULL || priv->opaque == NULL)
+ return (DST_R_NULLKEY);
+
+ if (pub->key_alg != priv->key_alg ||
+ pub->func->computesecret == NULL ||
+ priv->func->computesecret == NULL)
+ return (DST_R_KEYCANNOTCOMPUTESECRET);
+
+ if (dst_key_isprivate(priv) == ISC_FALSE)
+ return (DST_R_NOTPRIVATEKEY);
+
+ return (pub->func->computesecret(pub, priv, secret));
+}
+
+/*
+ * dst_key_tofile
+ * Writes a key to disk. The key can either be a public or private key.
+ * The public key is written in DNS format and the private key is
+ * written as a set of base64 encoded values.
+ * Parameters
+ * key The key to be written.
+ * type Either DST_PUBLIC or DST_PRIVATE, or both
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+dst_result_t
+dst_key_tofile(const dst_key_t *key, const int type) {
+ int ret = ISC_R_SUCCESS;
+
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+ REQUIRE(VALID_KEY(key));
+
+ if (dst_supported_algorithm(key->key_alg) == ISC_FALSE)
+ return (DST_R_UNSUPPORTEDALG);
+
+ if ((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) == 0)
+ return (DST_R_UNSUPPORTEDTYPE);
+
+ if (type & DST_TYPE_PUBLIC)
+ if ((ret = write_public_key(key)) != ISC_R_SUCCESS)
+ return (ret);
+
+ if ((type & DST_TYPE_PRIVATE) &&
+ (key->key_flags & DNS_KEYFLAG_TYPEMASK) != DNS_KEYTYPE_NOKEY)
+ {
+ ret = key->func->to_file(key);
+ if (ret != ISC_R_SUCCESS)
+ return (ret);
+ }
+
+ return (ret);
+}
+
+/*
+ * dst_key_fromfile
+ * Reads a key from disk. The key can either be a public or private
+ * key, and is specified by name, algorithm, and id.
+ * Parameters
+ * name The key name.
+ * id The id of the key.
+ * alg The algorithm of the key.
+ * type Either DST_PUBLIC or DST_PRIVATE
+ * mctx Memory context used to allocate key structure
+ * keyp Returns the new key
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+dst_result_t
+dst_key_fromfile(const char *name, const isc_uint16_t id, const int alg,
+ const int type, isc_mem_t *mctx, dst_key_t **keyp)
+{
+ dst_key_t *key = NULL, *pubkey = NULL;
+ dst_result_t ret;
+
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+ REQUIRE(name != NULL);
+ REQUIRE(mctx != NULL);
+ REQUIRE(keyp != NULL);
+
+ *keyp = NULL;
+ if (dst_supported_algorithm(alg) == ISC_FALSE)
+ return (DST_R_UNSUPPORTEDALG);
+
+ if ((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) == 0)
+ return (DST_R_UNSUPPORTEDTYPE);
+
+ ret = read_public_key(name, id, alg, mctx, &pubkey);
+ if (ret == ISC_R_NOTFOUND && (type & DST_TYPE_PUBLIC) == 0)
+ key = get_key_struct(name, alg, 0, 0, 0, mctx);
+ else if (ret != ISC_R_SUCCESS)
+ return (ret);
+ else {
+ if (type == DST_TYPE_PUBLIC ||
+ (pubkey->key_flags & DNS_KEYFLAG_TYPEMASK) ==
+ DNS_KEYTYPE_NOKEY)
+ {
+ *keyp = pubkey;
+ return (ISC_R_SUCCESS);
+ }
+
+ key = get_key_struct(name, pubkey->key_alg, pubkey->key_flags,
+ pubkey->key_proto, 0, mctx);
+ dst_key_free(pubkey);
+ }
+
+ if (key == NULL)
+ return (ISC_R_NOMEMORY);
+
+ /* Fill in private key and some fields in the general key structure */
+ ret = key->func->from_file(key, id, mctx);
+ if (ret != ISC_R_SUCCESS) {
+ dst_key_free(key);
+ return (ret);
+ }
+
+ *keyp = key;
+ return (ISC_R_SUCCESS);
+}
+
+/*
+ * dst_key_todns
+ * Function to encode a public key into DNS KEY format
+ * Parameters
+ * key Key structure to encode.
+ * target Buffer to write the encoded key into.
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+dst_result_t
+dst_key_todns(const dst_key_t *key, isc_buffer_t *target) {
+ isc_region_t r;
+
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+ REQUIRE(VALID_KEY(key));
+ REQUIRE(target != NULL);
+
+ if (dst_supported_algorithm(key->key_alg) == ISC_FALSE)
+ return (DST_R_UNSUPPORTEDALG);
+
+ isc_buffer_available(target, &r);
+ if (r.length < 4)
+ return (ISC_R_NOSPACE);
+ isc_buffer_putuint16(target, (isc_uint16_t)(key->key_flags & 0xffff));
+ isc_buffer_putuint8(target, (isc_uint8_t)key->key_proto);
+ isc_buffer_putuint8(target, (isc_uint8_t)key->key_alg);
+
+ if (key->key_flags & DNS_KEYFLAG_EXTENDED) {
+ isc_buffer_available(target, &r);
+ if (r.length < 2)
+ return (ISC_R_NOSPACE);
+ isc_buffer_putuint16(target,
+ (isc_uint16_t)((key->key_flags >> 16)
+ & 0xffff));
+ }
+
+ if (key->opaque == NULL) /* NULL KEY */
+ return (ISC_R_SUCCESS);
+
+ return (key->func->to_dns(key, target));
+}
+
+/*
+ * dst_key_fromdns
+ * This function converts the contents of a DNS KEY RR into a key
+ * Paramters
+ * name Name of the new key
+ * source A buffer containing the KEY RR
+ * mctx The memory context used to allocate the key
+ * keyp Returns the new key
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+
+dst_result_t
+dst_key_fromdns(const char *name, isc_buffer_t *source, isc_mem_t *mctx,
+ dst_key_t **keyp)
+{
+ isc_region_t r;
+ isc_uint8_t alg, proto;
+ isc_uint32_t flags, extflags;
+ dst_result_t ret;
+
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+ REQUIRE (name != NULL);
+ REQUIRE (source != NULL);
+ REQUIRE (mctx != NULL);
+ REQUIRE (keyp != NULL);
+
+ isc_buffer_remaining(source, &r);
+ if (r.length < 4) /* 2 bytes of flags, 1 proto, 1 alg */
+ return (DST_R_INVALIDPUBLICKEY);
+ flags = isc_buffer_getuint16(source);
+ proto = isc_buffer_getuint8(source);
+ alg = isc_buffer_getuint8(source);
+
+ if (!dst_supported_algorithm(alg))
+ return (DST_R_UNSUPPORTEDALG);
+
+ if (flags & DNS_KEYFLAG_EXTENDED) {
+ isc_buffer_remaining(source, &r);
+ if (r.length < 2)
+ return (DST_R_INVALIDPUBLICKEY);
+ extflags = isc_buffer_getuint16(source);
+ flags |= (extflags << 16);
+ }
+
+ *keyp = get_key_struct(name, alg, flags, proto, 0, mctx);
+ if (*keyp == NULL)
+ return (ISC_R_NOMEMORY);
+
+ ret = (*keyp)->func->from_dns(*keyp, source, mctx);
+ if (ret != ISC_R_SUCCESS)
+ dst_key_free((*keyp));
+ return (ret);
+}
+
+
+/*
+ * dst_key_frombuffer
+ * Function to convert raw data into a public key. The raw data format
+ * is basically DNS KEY rdata format.
+ * Parameters
+ * name The key name
+ * alg The algorithm
+ * flags The key's flags
+ * protocol The key's protocol
+ * source A buffer containing the key
+ * mctx The memory context used to allocate the key
+ * keyp Returns the new key
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+dst_result_t
+dst_key_frombuffer(const char *name, const int alg, const int flags,
+ const int protocol, isc_buffer_t *source, isc_mem_t *mctx,
+ dst_key_t **keyp)
+{
+ dst_result_t ret;
+
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+ REQUIRE(name != NULL);
+ REQUIRE(source != NULL);
+ REQUIRE(mctx != NULL);
+
+ if (dst_supported_algorithm(alg) == ISC_FALSE)
+ return (DST_R_UNSUPPORTEDALG);
+
+ *keyp = get_key_struct(name, alg, flags, protocol, 0, mctx);
+
+ if (*keyp == NULL)
+ return (ISC_R_NOMEMORY);
+
+ ret = (*keyp)->func->from_dns((*keyp), source, mctx);
+ if (ret != ISC_R_SUCCESS) {
+ dst_key_free((*keyp));
+ return (ret);
+ }
+ return (ISC_R_SUCCESS);
+}
+
+/*
+ * dst_key_tobuffer
+ * Function to convert a public key into raw data. The raw data format
+ * is basically DNS KEY rdata format.
+ * Parameters
+ * key The key
+ * target The buffer to be written into.
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+dst_result_t
+dst_key_tobuffer(const dst_key_t *key, isc_buffer_t *target) {
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+ REQUIRE(VALID_KEY(key));
+ REQUIRE(target != NULL);
+
+ if (dst_supported_algorithm(key->key_alg) == ISC_FALSE)
+ return (DST_R_UNSUPPORTEDALG);
+
+ return (key->func->to_dns(key, target));
+}
+
+/*
+ * dst_key_generate
+ * Generate a public/private keypair.
+ * Parameters
+ * name Name of the new key. Used to create key files
+ * K<name>+<alg>+<id>.public
+ * K<name>+<alg>+<id>.private
+ * alg The algorithm to use
+ * bits Size of the new key in bits
+ * param Algorithm specific
+ * RSA: exponent
+ * 0 use exponent 3
+ * !0 use Fermat4 (2^16 + 1)
+ * DH: generator
+ * 0 default - use well-known prime if bits == 768
+ * or 1024, otherwise use generator 2
+ * !0 use this value as the generator
+ * DSA/HMACMD5: unused
+ * flags The default value of the DNS Key flags.
+ * protocol Default value of the DNS Key protocol field.
+ * mctx The memory context used to allocate the key
+ * keyp Returns the new key
+ *
+ * Return
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+dst_result_t
+dst_key_generate(const char *name, const int alg, const int bits,
+ const int exp, const int flags, const int protocol,
+ isc_mem_t *mctx, dst_key_t **keyp)
+{
+ dst_result_t ret;
+
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+ REQUIRE(name != NULL);
+ REQUIRE(mctx != NULL);
+ REQUIRE(keyp != NULL);
+
+ if (dst_supported_algorithm(alg) == ISC_FALSE)
+ return (DST_R_UNSUPPORTEDALG);
+
+ *keyp = get_key_struct(name, alg, flags, protocol, bits, mctx);
+ if (*keyp == NULL)
+ return (ISC_R_NOMEMORY);
+
+ if (bits == 0) { /* NULL KEY */
+ (*keyp)->key_flags |= DNS_KEYTYPE_NOKEY;
+ return (ISC_R_SUCCESS);
+ }
+
+ ret = (*keyp)->func->generate(*keyp, exp, mctx);
+ if (ret != ISC_R_SUCCESS) {
+ dst_key_free(*keyp);
+ return (ret);
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+/*
+ * dst_key_compare
+ * Compares two keys for equality.
+ * Parameters
+ * key1, key2 Two keys to be compared.
+ * Returns
+ * ISC_TRUE The keys are equal.
+ * ISC_FALSE The keys are not equal.
+ */
+isc_boolean_t
+dst_key_compare(const dst_key_t *key1, const dst_key_t *key2) {
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+ REQUIRE(VALID_KEY(key1));
+ REQUIRE(VALID_KEY(key2));
+
+ if (key1 == key2)
+ return (ISC_TRUE);
+ if (key1 == NULL || key2 == NULL)
+ return (ISC_FALSE);
+ if (key1->key_alg == key2->key_alg &&
+ key1->key_id == key2->key_id &&
+ key1->func->compare(key1, key2) == ISC_TRUE)
+ return (ISC_TRUE);
+ else
+ return (ISC_FALSE);
+}
+/*
+ * dst_key_paramcompare
+ * Compares two keys' parameters for equality. This is designed to
+ * determine if two (Diffie-Hellman) keys can be used to derive a shared
+ * secret.
+ * Parameters
+ * key1, key2 Two keys whose parameters are to be compared.
+ * Returns
+ * ISC_TRUE The keys' parameters are equal.
+ * ISC_FALSE The keys' parameters are not equal.
+ */
+isc_boolean_t
+dst_key_paramcompare(const dst_key_t *key1, const dst_key_t *key2) {
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+ REQUIRE(VALID_KEY(key1));
+ REQUIRE(VALID_KEY(key2));
+
+ if (key1 == key2)
+ return (ISC_TRUE);
+ if (key1 == NULL || key2 == NULL)
+ return (ISC_FALSE);
+ if (key1->key_alg == key2->key_alg &&
+ key1->func->paramcompare != NULL &&
+ key1->func->paramcompare(key1, key2) == ISC_TRUE)
+ return (ISC_TRUE);
+ else
+ return (ISC_FALSE);
+}
+
+/*
+ * dst_key_free
+ * Release all data structures pointed to by a key structure.
+ * Parameters
+ * key Key structure to be freed.
+ */
+void
+dst_key_free(dst_key_t *key) {
+ isc_mem_t *mctx;
+
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+ REQUIRE(VALID_KEY(key));
+
+ mctx = key->mctx;
+
+ if (key->opaque != NULL)
+ key->func->destroy(key->opaque, mctx);
+
+ isc_mem_free(mctx, key->key_name);
+ memset(key, 0, sizeof(dst_key_t));
+ isc_mem_put(mctx, key, sizeof(dst_key_t));
+}
+
+char *
+dst_key_name(const dst_key_t *key) {
+ REQUIRE(VALID_KEY(key));
+ return (key->key_name);
+}
+
+int
+dst_key_size(const dst_key_t *key) {
+ REQUIRE(VALID_KEY(key));
+ return (key->key_size);
+}
+
+int
+dst_key_proto(const dst_key_t *key) {
+ REQUIRE(VALID_KEY(key));
+ return (key->key_proto);
+}
+
+int
+dst_key_alg(const dst_key_t *key) {
+ REQUIRE(VALID_KEY(key));
+ return (key->key_alg);
+}
+
+isc_uint32_t
+dst_key_flags(const dst_key_t *key) {
+ REQUIRE(VALID_KEY(key));
+ return (key->key_flags);
+}
+
+isc_uint16_t
+dst_key_id(const dst_key_t *key) {
+ REQUIRE(VALID_KEY(key));
+ return (key->key_id);
+}
+
+isc_boolean_t
+dst_key_isprivate(const dst_key_t *key) {
+ REQUIRE(VALID_KEY(key));
+ return (key->func->isprivate(key));
+}
+
+/*
+ * dst_sig_size
+ * Computes the maximum size of a signature generated by the given key
+ * Parameters
+ * key The DST key
+ * n Stores the number of bytes necessary to hold a signature
+ * with the key.
+ * Returns
+ * ISC_R_SUCCESS
+ * DST_R_UNSUPPORTEDALG
+ */
+isc_result_t
+dst_sig_size(const dst_key_t *key, unsigned int *n) {
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+ REQUIRE(VALID_KEY(key));
+ REQUIRE(n != NULL);
+
+ switch (key->key_alg) {
+ case DST_ALG_RSA:
+ *n = (key->key_size + 7) / 8;
+ break;
+ case DST_ALG_DSA:
+ *n = DNS_SIG_DSASIGSIZE;
+ break;
+ case DST_ALG_HMACMD5:
+ *n = 16;
+ break;
+ case DST_ALG_HMACSHA1:
+ *n = 20;
+ break;
+ case DST_ALG_DH:
+ default:
+ return (DST_R_UNSUPPORTEDALG);
+ }
+ return (ISC_R_SUCCESS);
+}
+
+/*
+ * dst_secret_size
+ * Computes the maximum size of a shared secret generated by the given key
+ * Parameters
+ * key The DST key
+ * n Stores the number of bytes necessary to hold a shared secret
+ * generated by the key.
+ * Returns
+ * ISC_R_SUCCESS
+ * DST_R_UNSUPPORTEDALG
+ */
+isc_result_t
+dst_secret_size(const dst_key_t *key, unsigned int *n) {
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+ REQUIRE(VALID_KEY(key));
+ REQUIRE(n != NULL);
+
+ switch (key->key_alg) {
+ case DST_ALG_DH:
+ *n = (key->key_size + 7) / 8;
+ break;
+ case DST_ALG_RSA:
+ case DST_ALG_DSA:
+ case DST_ALG_HMACMD5:
+ case DST_ALG_HMACSHA1:
+ default:
+ return (DST_R_UNSUPPORTEDALG);
+ }
+ return (ISC_R_SUCCESS);
+}
+
+/*
+ * dst_random_get
+ * a random number generator that can generate different levels of
+ * randomness
+ * Parameters
+ * mode selects the random number generator
+ * wanted the number of random bytes requested
+ * target the buffer to store the random data
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+dst_result_t
+dst_random_get(const unsigned int wanted, isc_buffer_t *target) {
+ isc_region_t r;
+
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
+ REQUIRE(target != NULL);
+
+ isc_buffer_available(target, &r);
+ if (r.length < wanted)
+ return (ISC_R_NOSPACE);
+
+ RUNTIME_CHECK(isc_mutex_lock((&random_lock)) == ISC_R_SUCCESS);
+ RAND_bytes(r.base, wanted);
+ RUNTIME_CHECK(isc_mutex_unlock((&random_lock)) == ISC_R_SUCCESS);
+ isc_buffer_add(target, wanted);
+ return (ISC_R_SUCCESS);
+}
+
+/***
+ *** Static methods
+ ***/
+
+/*
+ * initialize
+ * This function initializes the Digital Signature Toolkit.
+ * Parameters
+ * none
+ * Returns
+ * none
+ */
+static void
+initialize() {
+ memset(dst_t_func, 0, sizeof(dst_t_func));
+
+ RUNTIME_CHECK(isc_mem_create(0, 0, &dst_memory_pool) == ISC_R_SUCCESS);
+ RUNTIME_CHECK(isc_mutex_init(&random_lock) == ISC_R_SUCCESS);
+
+ dst_result_register();
+
+ dst_s_hmacmd5_init();
+#if defined(BSAFE) || defined(DNSSAFE)
+ dst_s_bsafersa_init();
+#endif
+#ifdef OPENSSL
+ dst_s_openssldsa_init();
+ dst_s_openssldh_init();
+#endif
+}
+
+/*
+ * get_key_struct
+ * This function allocates key structure and fills in some of the
+ * fields of the structure.
+ * Parameters:
+ * name the name of the key
+ * alg the algorithm number
+ * flags the dns flags of the key
+ * protocol the dns protocol of the key
+ * bits the size of the key
+ * mctx the memory context to allocate from
+ * Returns:
+ * NULL error
+ * valid pointer otherwise
+ */
+static dst_key_t *
+get_key_struct(const char *name, const int alg, const int flags,
+ const int protocol, const int bits, isc_mem_t *mctx)
+{
+ dst_key_t *key;
+
+ REQUIRE(dst_supported_algorithm(alg) != ISC_FALSE);
+
+ key = (dst_key_t *) isc_mem_get(mctx, sizeof(dst_key_t));
+ if (key == NULL)
+ return (NULL);
+
+ memset(key, 0, sizeof(dst_key_t));
+ key->magic = KEY_MAGIC;
+ if (name[strlen(name) - 1] == '.') {
+ key->key_name = isc_mem_strdup(mctx, name);
+ if (key->key_name == NULL) {
+ isc_mem_free(mctx, key);
+ return (NULL);
+ }
+ }
+ else {
+ key->key_name = isc_mem_allocate(mctx, strlen(name) + 2);
+ if (key->key_name == NULL) {
+ isc_mem_free(mctx, key);
+ return (NULL);
+ }
+ sprintf(key->key_name, "%s.", name);
+ }
+ key->key_alg = alg;
+ key->key_flags = flags;
+ key->key_proto = protocol;
+ key->mctx = mctx;
+ key->opaque = NULL;
+ key->key_size = bits;
+ key->func = dst_t_func[alg];
+ return (key);
+}
+
+/*
+ * dst_read_public_key
+ * Read a public key from disk
+ * Parameters
+ * name The name
+ * id The id
+ * alg The algorithm
+ * mctx The memory context used to allocate the key
+ * keyp Returns the new key
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+
+static dst_result_t
+read_public_key(const char *name, const isc_uint16_t id, int alg,
+ isc_mem_t *mctx, dst_key_t **keyp)
+{
+ char filename[ISC_DIR_NAMEMAX];
+ u_char rdatabuf[DST_KEY_MAXSIZE];
+ isc_buffer_t b;
+ isc_lex_t *lex = NULL;
+ isc_token_t token;
+ isc_result_t ret;
+ dns_rdata_t rdata;
+ unsigned int opt = ISC_LEXOPT_DNSMULTILINE;
+
+ if (dst_s_build_filename(filename, name, id, alg, PUBLIC_KEY,
+ sizeof(filename)) != ISC_R_SUCCESS)
+ return (DST_R_NAMETOOLONG);
+
+ /*
+ * Open the file and read its formatted contents
+ * File format:
+ * domain.name [ttl] [IN] KEY <flags> <protocol> <algorithm> <key>
+ */
+
+ /* 1500 should be large enough for any key */
+ ret = isc_lex_create(mctx, 1500, &lex);
+ if (ret != ISC_R_SUCCESS)
+ return (ISC_R_NOMEMORY);
+
+ ret = isc_lex_openfile(lex, filename);
+ if (ret != ISC_R_SUCCESS) {
+ if (ret == ISC_R_FAILURE)
+ ret = ISC_R_NOTFOUND;
+ goto cleanup;
+ }
+
+#define NEXTTOKEN(lex, opt, token) { \
+ ret = isc_lex_gettoken(lex, opt, token); \
+ if (ret != ISC_R_SUCCESS) \
+ goto cleanup; \
+ }
+
+ /* Read the domain name */
+ NEXTTOKEN(lex, opt, &token);
+
+ /* Read the next word: either TTL, 'IN', or 'KEY' */
+ NEXTTOKEN(lex, opt, &token);
+
+ /* If it's a TTL, read the next one */
+ if (token.type == isc_tokentype_number)
+ NEXTTOKEN(lex, opt, &token);
+
+ if (token.type != isc_tokentype_string)
+ goto cleanup;
+
+ if (strcasecmp(token.value.as_pointer, "IN") == 0)
+ NEXTTOKEN(lex, opt, &token);
+
+ if (token.type != isc_tokentype_string)
+ goto cleanup;
+
+ if (strcasecmp(token.value.as_pointer, "KEY") != 0)
+ goto cleanup;
+
+ isc_buffer_init(&b, rdatabuf, sizeof(rdatabuf), ISC_BUFFERTYPE_BINARY);
+ ret = dns_rdata_fromtext(&rdata, dns_rdataclass_in, dns_rdatatype_key,
+ lex, NULL, ISC_FALSE, &b, NULL);
+ if (ret != ISC_R_SUCCESS)
+ goto cleanup;
+
+ ret = dst_key_fromdns(name, &b, mctx, keyp);
+ if (ret != ISC_R_SUCCESS || (*keyp)->key_alg != alg)
+ goto cleanup;
+
+ isc_lex_close(lex);
+ isc_lex_destroy(&lex);
+
+ return (ISC_R_SUCCESS);
+
+cleanup:
+ if (lex != NULL) {
+ isc_lex_close(lex);
+ isc_lex_destroy(&lex);
+ }
+ return (ret);
+}
+
+
+/*
+ * write_public_key
+ * Write a key to disk in DNS format.
+ * Parameters
+ * key A DST key
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+
+static dst_result_t
+write_public_key(const dst_key_t *key) {
+ FILE *fp;
+ isc_buffer_t keyb, textb;
+ isc_region_t r;
+ char filename[ISC_DIR_NAMEMAX];
+ unsigned char key_array[DST_KEY_MAXSIZE];
+ char text_array[DST_KEY_MAXSIZE];
+ dst_result_t ret;
+ isc_result_t dnsret;
+ dns_rdata_t rdata;
+
+ REQUIRE(VALID_KEY(key));
+
+ isc_buffer_init(&keyb, key_array, sizeof(key_array),
+ ISC_BUFFERTYPE_BINARY);
+ isc_buffer_init(&textb, text_array, sizeof(text_array),
+ ISC_BUFFERTYPE_TEXT);
+
+ ret = dst_key_todns(key, &keyb);
+ if (ret != ISC_R_SUCCESS)
+ return (ret);
+
+ isc_buffer_used(&keyb, &r);
+ dns_rdata_fromregion(&rdata, dns_rdataclass_in, dns_rdatatype_key, &r);
+
+ dnsret = dns_rdata_totext(&rdata, (dns_name_t *) NULL, &textb);
+ if (dnsret != ISC_R_SUCCESS)
+ return (DST_R_INVALIDPUBLICKEY);
+
+ dns_rdata_freestruct(&rdata);
+
+ isc_buffer_used(&textb, &r);
+
+ /*
+ * Make the filename.
+ */
+ if (dst_s_build_filename(filename,
+ key->key_name, key->key_id, key->key_alg,
+ PUBLIC_KEY, sizeof(filename)) < 0)
+ return (DST_R_NAMETOOLONG);
+
+ /*
+ * Create public key file.
+ */
+ if ((fp = fopen(filename, "w")) == NULL)
+ return (DST_R_WRITEERROR);
+
+ fprintf(fp, "%s IN KEY ", key->key_name);
+ fwrite(r.base, 1, r.length, fp);
+ fputc('\n', fp);
+ fclose(fp);
+ return (ISC_R_SUCCESS);
+}
+
+void *
+dst_mem_alloc(size_t size) {
+ INSIST(dst_memory_pool != NULL);
+ return (isc_mem_allocate(dst_memory_pool, size));
+}
+
+void
+dst_mem_free(void *ptr) {
+ INSIST(dst_memory_pool != NULL);
+ if (ptr != NULL)
+ isc_mem_free(dst_memory_pool, ptr);
+}
+
+void *
+dst_mem_realloc(void *ptr, size_t size) {
+ void *p;
+
+ INSIST(dst_memory_pool != NULL);
+ p = NULL;
+ if (size > 0) {
+ p = dst_mem_alloc(size);
+ if (p != NULL && ptr != NULL)
+ memcpy(p, ptr, size);
+ }
+ if (ptr != NULL)
+ dst_mem_free(ptr);
+ return (p);
+}
diff --git a/lib/dns/sec/dst/dst_internal.h b/lib/dns/sec/dst/dst_internal.h
new file mode 100644
index 00000000..7689fb03
--- /dev/null
+++ b/lib/dns/sec/dst/dst_internal.h
@@ -0,0 +1,123 @@
+#ifndef DST_INTERNAL_H
+#define DST_INTERNAL_H
+
+/*
+ * Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc.
+ *
+ * Permission to use, copy modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND TRUSTED INFORMATION SYSTEMS
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * TRUSTED INFORMATION SYSTEMS BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THE SOFTWARE.
+ */
+#include <isc/lang.h>
+#include <isc/buffer.h>
+#include <isc/int.h>
+#include <isc/region.h>
+
+#include <dst/dst.h>
+#include <dst/result.h>
+
+ISC_LANG_BEGINDECLS
+
+/*
+ * define what crypto systems are supported.
+ * BSAFE, DNSSAFE for RSA
+ * OPENSSL for DSA
+ * Only one package per algorithm can be defined.
+ */
+#if defined(BSAFE) && defined(DNSSAFE)
+# error "Cannot have both BSAFE and DNSSAFE defined"
+#endif
+
+/***
+ *** Types
+ ***/
+
+typedef struct dst_func dst_func;
+
+struct dst_key {
+ unsigned int magic;
+ char * key_name; /* name of the key */
+ int key_size; /* size of the key in bits */
+ int key_proto; /* protocols this key is used for */
+ int key_alg; /* algorithm of the key */
+ isc_uint32_t key_flags; /* flags of the public key */
+ isc_uint16_t key_id; /* identifier of the key */
+ isc_mem_t *mctx; /* memory context */
+ void * opaque; /* pointer to key in crypto pkg fmt */
+ dst_func * func; /* crypto package specific functions */
+};
+
+struct dst_func {
+ dst_result_t (*sign)(const unsigned int mode, dst_key_t *key,
+ void **context, isc_region_t *data,
+ isc_buffer_t *sig, isc_mem_t *mctx);
+ dst_result_t (*verify)(const unsigned int mode, dst_key_t *key,
+ void **context, isc_region_t *data,
+ isc_region_t *sig, isc_mem_t *mctx);
+ dst_result_t (*computesecret)(const dst_key_t *pub,
+ const dst_key_t *priv,
+ isc_buffer_t *secret);
+ isc_boolean_t (*compare)(const dst_key_t *key1, const dst_key_t *key2);
+ isc_boolean_t (*paramcompare)(const dst_key_t *key1,
+ const dst_key_t *key2);
+ dst_result_t (*generate)(dst_key_t *key, int parms, isc_mem_t *mctx);
+ isc_boolean_t (*isprivate)(const dst_key_t *key);
+ void (*destroy)(void *key, isc_mem_t *mctx);
+ /* conversion functions */
+ dst_result_t (*to_dns)(const dst_key_t *key, isc_buffer_t *data);
+ dst_result_t (*from_dns)(dst_key_t *key, isc_buffer_t *data,
+ isc_mem_t *mctx);
+ dst_result_t (*to_file)(const dst_key_t *key);
+ dst_result_t (*from_file)(dst_key_t *key, const isc_uint16_t id,
+ isc_mem_t *mctx);
+};
+
+extern dst_func *dst_t_func[DST_MAX_ALGS];
+
+/* suffixes for key file names */
+#define PRIVATE_KEY "private"
+#define PUBLIC_KEY "key"
+
+#ifndef DST_HASH_SIZE
+#define DST_HASH_SIZE 20 /* RIPEMD160 & SHA-1 are 20 bytes, MD5 is 16 */
+#endif
+
+void dst_s_hmacmd5_init(void);
+void dst_s_bsafersa_init(void);
+void dst_s_openssldsa_init(void);
+void dst_s_openssldh_init(void);
+
+/* support functions */
+
+int dst_s_calculate_bits(const unsigned char *str, const int max_bits);
+isc_uint16_t dst_s_id_calc(const unsigned char *key, const int keysize);
+int dst_s_build_filename(char *filename, const char *name,
+ isc_uint16_t id, int alg,
+ const char *suffix,
+ size_t filename_length);
+
+
+/* digest functions */
+dst_result_t dst_s_md5(const unsigned int mode, void **context,
+ isc_region_t *data, isc_buffer_t *digest,
+ isc_mem_t *mctx);
+
+
+/* memory allocators using the DST memory pool */
+void * dst_mem_alloc(size_t size);
+void dst_mem_free(void *ptr);
+void * dst_mem_realloc(void *ptr, size_t size);
+
+
+ISC_LANG_ENDDECLS
+
+#endif /* DST_INTERNAL_H */
diff --git a/lib/dns/sec/dst/dst_lib.c b/lib/dns/sec/dst/dst_lib.c
new file mode 100644
index 00000000..d4702194
--- /dev/null
+++ b/lib/dns/sec/dst/dst_lib.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 1999 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Principal Author: Brian Wellington
+ * $Id: dst_lib.c,v 1.1 1999/07/12 20:08:28 bwelling Exp $
+ */
+
+#include <config.h>
+
+#include <stddef.h>
+
+#include <isc/once.h>
+#include <isc/error.h>
+#include <isc/msgcat.h>
+
+#include <dst/lib.h>
+
+/***
+ *** Globals
+ ***/
+
+isc_msgcat_t * dst_msgcat = NULL;
+
+
+/***
+ *** Private
+ ***/
+
+static isc_once_t msgcat_once = ISC_ONCE_INIT;
+
+
+/***
+ *** Functions
+ ***/
+
+static void
+open_msgcat(void) {
+ isc_msgcat_open("libdst.cat", &dst_msgcat);
+}
+
+void
+dst_lib_initmsgcat(void) {
+
+ /*
+ * Initialize the DST library's message catalog, dst_msgcat, if it
+ * has not already been initialized.
+ */
+
+ RUNTIME_CHECK(isc_once_do(&msgcat_once, open_msgcat) == ISC_R_SUCCESS);
+}
diff --git a/lib/dns/sec/dst/dst_parse.c b/lib/dns/sec/dst/dst_parse.c
new file mode 100644
index 00000000..e2dae73a
--- /dev/null
+++ b/lib/dns/sec/dst/dst_parse.c
@@ -0,0 +1,391 @@
+/*
+ * Portions Copyright (c) 1995-1999 by Network Associates, Inc.
+ *
+ * Permission to use, copy modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND NETWORK ASSOCIATES
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * NETWORK ASSOCIATES BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THE SOFTWARE.
+ */
+
+/*
+ * Principal Author: Brian Wellington
+ * $Id: dst_parse.c,v 1.9 1999/10/20 22:14:14 bwelling Exp $
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
+
+#include <isc/assertions.h>
+#include <isc/base64.h>
+#include <isc/buffer.h>
+#include <isc/dir.h>
+#include <isc/int.h>
+#include <isc/lex.h>
+#include <isc/mem.h>
+#include <isc/region.h>
+#include <dns/rdata.h>
+
+/* XXXBEW For chmod. This should be removed. */
+#include <sys/stat.h>
+
+#include "dst_internal.h"
+#include "dst_parse.h"
+#include "dst/result.h"
+
+
+#define PRIVATE_KEY_STR "Private-key-format:"
+#define ALGORITHM_STR "Algorithm:"
+#define RSA_STR "RSA"
+#define DH_STR "DH"
+#define DSA_STR "DSA"
+#define HMACMD5_STR "HMAC_MD5"
+
+struct parse_map {
+ int value;
+ char *tag;
+};
+
+static struct parse_map map[] = {
+ {TAG_RSA_MODULUS, "Modulus:"},
+ {TAG_RSA_PUBLICEXPONENT, "PublicExponent:"},
+ {TAG_RSA_PRIVATEEXPONENT, "PrivateExponent:"},
+ {TAG_RSA_PRIME1, "Prime1:"},
+ {TAG_RSA_PRIME2, "Prime2:"},
+ {TAG_RSA_EXPONENT1, "Exponent1:"},
+ {TAG_RSA_EXPONENT2, "Exponent2:"},
+ {TAG_RSA_COEFFICIENT, "Coefficient:"},
+
+ {TAG_DH_PRIME, "Prime(p):"},
+ {TAG_DH_GENERATOR, "Generator(g):"},
+ {TAG_DH_PRIVATE, "Private_value(x):"},
+ {TAG_DH_PUBLIC, "Public_value(y):"},
+
+ {TAG_DSA_PRIME, "Prime(p):"},
+ {TAG_DSA_SUBPRIME, "Subprime(q):"},
+ {TAG_DSA_BASE, "Base(g):"},
+ {TAG_DSA_PRIVATE, "Private_value(x):"},
+ {TAG_DSA_PUBLIC, "Public_value(y):"},
+
+ {TAG_HMACMD5_KEY, "Key:"},
+ {0, NULL}
+};
+
+static int
+find_value(const char *s, const int alg) {
+ int i;
+
+ for (i = 0; ; i++) {
+ if (map[i].tag == NULL)
+ return (-1);
+ else if (strcasecmp(s, map[i].tag) == 0 &&
+ TAG_ALG(map[i].value) == alg)
+ return (map[i].value);
+ }
+}
+
+static char *
+find_tag(const int value) {
+ int i;
+
+ for (i = 0; ; i++) {
+ if (map[i].tag == NULL)
+ return (NULL);
+ else if (value == map[i].value)
+ return (map[i].tag);
+ }
+}
+
+static int
+check_rsa(const dst_private_t *priv) {
+ int i, j;
+ if (priv->nelements != RSA_NTAGS)
+ return (-1);
+ for (i = 0; i < RSA_NTAGS; i++) {
+ for (j = 0; j < priv->nelements; j++)
+ if (priv->elements[j].tag == TAG(DST_ALG_RSA, i))
+ break;
+ if (j == priv->nelements)
+ return (-1);
+ }
+ return (0);
+}
+
+static int
+check_dh(const dst_private_t *priv) {
+ int i, j;
+ if (priv->nelements != DH_NTAGS)
+ return (-1);
+ for (i = 0; i < DH_NTAGS; i++) {
+ for (j = 0; j < priv->nelements; j++)
+ if (priv->elements[j].tag == TAG(DST_ALG_DH, i))
+ break;
+ if (j == priv->nelements)
+ return (-1);
+ }
+ return (0);
+}
+
+static int
+check_dsa(const dst_private_t *priv) {
+ int i, j;
+ if (priv->nelements != DSA_NTAGS)
+ return (-1);
+ for (i = 0; i < DSA_NTAGS; i++) {
+ for (j = 0; j < priv->nelements; j++)
+ if (priv->elements[j].tag == TAG(DST_ALG_DSA, i))
+ break;
+ if (j == priv->nelements)
+ return (-1);
+ }
+ return (0);
+}
+
+static int
+check_hmac_md5(const dst_private_t *priv) {
+ if (priv->nelements != HMACMD5_NTAGS)
+ return (-1);
+ if (priv->elements[0].tag != TAG_HMACMD5_KEY)
+ return (-1);
+ return (0);
+}
+
+static int
+check_data(const dst_private_t *priv, const int alg) {
+ switch (alg) {
+ case DST_ALG_RSA:
+ return (check_rsa(priv));
+ case DST_ALG_DH:
+ return (check_dh(priv));
+ case DST_ALG_DSA:
+ return (check_dsa(priv));
+ case DST_ALG_HMACMD5:
+ return (check_hmac_md5(priv));
+ default:
+ return (DST_R_UNSUPPORTEDALG);
+ }
+}
+
+void
+dst_s_free_private_structure_fields(dst_private_t *priv, isc_mem_t *mctx) {
+ int i;
+
+ if (priv == NULL)
+ return;
+ for (i = 0; i < priv->nelements; i++) {
+ if (priv->elements[i].data == NULL)
+ continue;
+ memset(priv->elements[i].data, 0, MAXFIELDSIZE);
+ isc_mem_put(mctx, priv->elements[i].data, MAXFIELDSIZE);
+ }
+ priv->nelements = 0;
+}
+
+int
+dst_s_parse_private_key_file(const char *name, const int alg,
+ const isc_uint16_t id, dst_private_t *priv,
+ isc_mem_t *mctx)
+{
+ char filename[ISC_DIR_NAMEMAX];
+ int n = 0, ret, major, minor;
+ isc_buffer_t b;
+ isc_lex_t *lex = NULL;
+ isc_token_t token;
+ unsigned int opt = ISC_LEXOPT_EOL;
+ isc_result_t iret;
+ isc_result_t error = DST_R_INVALIDPRIVATEKEY;
+
+ REQUIRE(priv != NULL);
+
+ priv->nelements = 0;
+
+ ret = dst_s_build_filename(filename, name, id, alg, PRIVATE_KEY,
+ sizeof(filename));
+ if (ret < 0)
+ return (DST_R_NAMETOOLONG);
+
+ iret = isc_lex_create(mctx, 1024, &lex);
+ if (iret != ISC_R_SUCCESS)
+ return (ISC_R_NOMEMORY);
+
+ iret = isc_lex_openfile(lex, filename);
+ if (iret != ISC_R_SUCCESS)
+ goto fail;
+
+#define NEXTTOKEN(lex, opt, token) \
+ { \
+ iret = isc_lex_gettoken(lex, opt, token); \
+ if (iret != ISC_R_SUCCESS) \
+ goto fail; \
+ }
+
+#define READLINE(lex, opt, token) \
+ do { \
+ NEXTTOKEN(lex, opt, token) \
+ } while ((*token).type != isc_tokentype_eol) \
+
+ /* Read the description line */
+ NEXTTOKEN(lex, opt, &token);
+ if (token.type != isc_tokentype_string ||
+ strcmp(token.value.as_pointer, PRIVATE_KEY_STR) != 0)
+ goto fail;
+
+ NEXTTOKEN(lex, opt, &token);
+ if (token.type != isc_tokentype_string ||
+ ((char *)token.value.as_pointer)[0] != 'v')
+ goto fail;
+ if (sscanf(token.value.as_pointer, "v%d.%d", &major, &minor) != 2)
+ goto fail;
+
+ if (major > MAJOR_VERSION ||
+ (major == MAJOR_VERSION && minor > MINOR_VERSION))
+ goto fail;
+
+ READLINE(lex, opt, &token);
+
+ /* Read the algorithm line */
+ NEXTTOKEN(lex, opt, &token);
+ if (token.type != isc_tokentype_string ||
+ strcmp(token.value.as_pointer, ALGORITHM_STR) != 0)
+ goto fail;
+
+ NEXTTOKEN(lex, opt | ISC_LEXOPT_NUMBER, &token);
+ if (token.type != isc_tokentype_number ||
+ token.value.as_ulong != (unsigned long) alg)
+ goto fail;
+
+ READLINE(lex, opt, &token);
+
+ /* Read the key data */
+ for (n = 0; n < MAXFIELDS; n++) {
+ int tag;
+ unsigned char *data;
+ isc_region_t r;
+
+ iret = isc_lex_gettoken(lex, opt, &token);
+ if (iret == ISC_R_EOF)
+ break;
+ if (iret != ISC_R_SUCCESS)
+ goto fail;
+ if (token.type != isc_tokentype_string)
+ goto fail;
+
+ memset(&priv->elements[n], 0, sizeof(dst_private_element_t));
+ tag = find_value(token.value.as_pointer, alg);
+ if (tag < 0 || TAG_ALG(tag) != alg)
+ goto fail;
+ priv->elements[n].tag = tag;
+
+ data = (unsigned char *) isc_mem_get(mctx, MAXFIELDSIZE);
+ if (data == NULL) {
+ error = DST_R_INVALIDPRIVATEKEY;
+ goto fail;
+ }
+ isc_buffer_init(&b, data, MAXFIELDSIZE, ISC_BUFFERTYPE_BINARY);
+ ret = isc_base64_tobuffer(lex, &b, -1);
+ if (ret != ISC_R_SUCCESS)
+ goto fail;
+ isc_buffer_used(&b, &r);
+ priv->elements[n].length = r.length;
+ priv->elements[n].data = r.base;
+
+ READLINE(lex, opt, &token);
+ }
+
+ priv->nelements = n;
+
+ if (check_data(priv, alg) < 0)
+ goto fail;
+
+ isc_lex_close(lex);
+ isc_lex_destroy(&lex);
+
+ return (ISC_R_SUCCESS);
+
+fail:
+ if (lex != NULL) {
+ isc_lex_close(lex);
+ isc_lex_destroy(&lex);
+ }
+
+ priv->nelements = n;
+ dst_s_free_private_structure_fields(priv, mctx);
+ return (DST_R_INVALIDPRIVATEKEY);
+}
+
+int
+dst_s_write_private_key_file(const char *name, const int alg,
+ const isc_uint16_t id, const dst_private_t *priv)
+{
+ FILE *fp;
+ int ret, i;
+ isc_result_t iret;
+ char filename[ISC_DIR_NAMEMAX];
+ char buffer[MAXFIELDSIZE * 2];
+
+ REQUIRE(priv != NULL);
+
+ if (check_data(priv, alg) < 0)
+ return (DST_R_INVALIDPRIVATEKEY);
+
+ ret = dst_s_build_filename(filename, name, id, alg, PRIVATE_KEY,
+ sizeof(filename));
+ if (ret < 0)
+ return (DST_R_NAMETOOLONG);
+
+ if ((fp = fopen(filename, "w")) == NULL)
+ return (DST_R_WRITEERROR);
+
+ /* XXXBEW This won't exist on non-unix systems. Hmmm.... */
+ chmod(filename, 0600);
+
+ fprintf(fp, "%s v%d.%d\n", PRIVATE_KEY_STR, MAJOR_VERSION,
+ MINOR_VERSION);
+
+ fprintf(fp, "%s %d ", ALGORITHM_STR, alg);
+ switch (alg) {
+ case DST_ALG_RSA: fprintf(fp, "(RSA)\n"); break;
+ case DST_ALG_DH: fprintf(fp, "(DH)\n"); break;
+ case DST_ALG_DSA: fprintf(fp, "(DSA)\n"); break;
+ case DST_ALG_HMACMD5: fprintf(fp, "(HMAC_MD5)\n"); break;
+ default : fprintf(fp, "(?)\n"); break;
+ }
+
+ for (i = 0; i < priv->nelements; i++) {
+ isc_buffer_t b;
+ isc_region_t r;
+ char *s;
+
+ s = find_tag(priv->elements[i].tag);
+
+ r.base = priv->elements[i].data;
+ r.length = priv->elements[i].length;
+ isc_buffer_init(&b, buffer, sizeof(buffer),
+ ISC_BUFFERTYPE_TEXT);
+ iret = isc_base64_totext(&r, sizeof(buffer), "", &b);
+ if (iret != ISC_R_SUCCESS) {
+ fclose(fp);
+ return (DST_R_INVALIDPRIVATEKEY);
+ }
+ isc_buffer_used(&b, &r);
+
+ fprintf(fp, "%s ", s);
+ fwrite(r.base, 1, r.length, fp);
+ fprintf(fp, "\n");
+ }
+
+ fclose(fp);
+ return (ISC_R_SUCCESS);
+}
diff --git a/lib/dns/sec/dst/dst_parse.h b/lib/dns/sec/dst/dst_parse.h
new file mode 100644
index 00000000..a431fc98
--- /dev/null
+++ b/lib/dns/sec/dst/dst_parse.h
@@ -0,0 +1,88 @@
+#ifndef DST_PARSE_H
+#define DST_PARSE_H
+
+/*
+ * Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc.
+ *
+ * Permission to use, copy modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND TRUSTED INFORMATION SYSTEMS
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * TRUSTED INFORMATION SYSTEMS BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THE SOFTWARE.
+ */
+#include <isc/lang.h>
+#include <isc/mem.h>
+#include <dst/dst.h>
+
+ISC_LANG_BEGINDECLS
+
+#define MAJOR_VERSION 1
+#define MINOR_VERSION 2
+
+#define MAXFIELDSIZE 512
+#define MAXFIELDS 12
+
+#define TAG_SHIFT 4
+#define TAG_ALG(tag) (tag >> TAG_SHIFT)
+#define TAG(alg, off) ((alg << TAG_SHIFT) + off)
+
+#define RSA_NTAGS 8
+#define TAG_RSA_MODULUS ((DST_ALG_RSA << TAG_SHIFT) + 0)
+#define TAG_RSA_PUBLICEXPONENT ((DST_ALG_RSA << TAG_SHIFT) + 1)
+#define TAG_RSA_PRIVATEEXPONENT ((DST_ALG_RSA << TAG_SHIFT) + 2)
+#define TAG_RSA_PRIME1 ((DST_ALG_RSA << TAG_SHIFT) + 3)
+#define TAG_RSA_PRIME2 ((DST_ALG_RSA << TAG_SHIFT) + 4)
+#define TAG_RSA_EXPONENT1 ((DST_ALG_RSA << TAG_SHIFT) + 5)
+#define TAG_RSA_EXPONENT2 ((DST_ALG_RSA << TAG_SHIFT) + 6)
+#define TAG_RSA_COEFFICIENT ((DST_ALG_RSA << TAG_SHIFT) + 7)
+
+#define DH_NTAGS 4
+#define TAG_DH_PRIME ((DST_ALG_DH << TAG_SHIFT) + 0)
+#define TAG_DH_GENERATOR ((DST_ALG_DH << TAG_SHIFT) + 1)
+#define TAG_DH_PRIVATE ((DST_ALG_DH << TAG_SHIFT) + 2)
+#define TAG_DH_PUBLIC ((DST_ALG_DH << TAG_SHIFT) + 3)
+
+#define DSA_NTAGS 5
+#define TAG_DSA_PRIME ((DST_ALG_DSA << TAG_SHIFT) + 0)
+#define TAG_DSA_SUBPRIME ((DST_ALG_DSA << TAG_SHIFT) + 1)
+#define TAG_DSA_BASE ((DST_ALG_DSA << TAG_SHIFT) + 2)
+#define TAG_DSA_PRIVATE ((DST_ALG_DSA << TAG_SHIFT) + 3)
+#define TAG_DSA_PUBLIC ((DST_ALG_DSA << TAG_SHIFT) + 4)
+
+#define HMACMD5_NTAGS 1
+#define TAG_HMACMD5_KEY ((DST_ALG_HMACMD5 << TAG_SHIFT) + 0)
+
+struct dst_private_element {
+ unsigned short tag;
+ unsigned short length;
+ unsigned char *data;
+};
+
+typedef struct dst_private_element dst_private_element_t;
+
+struct dst_private {
+ unsigned short nelements;
+ dst_private_element_t elements[MAXFIELDS];
+};
+
+typedef struct dst_private dst_private_t;
+
+void dst_s_free_private_structure_fields(dst_private_t *priv,
+ isc_mem_t *mctx);
+int dst_s_parse_private_key_file(const char *name, const int alg,
+ const isc_uint16_t id, dst_private_t *priv,
+ isc_mem_t *mctx);
+int dst_s_write_private_key_file(const char *name, const int alg,
+ const isc_uint16_t id,
+ const dst_private_t *priv);
+
+ISC_LANG_ENDDECLS
+
+#endif /* DST_PARSE_H */
diff --git a/lib/dns/sec/dst/dst_result.c b/lib/dns/sec/dst/dst_result.c
new file mode 100644
index 00000000..16cc3d5a
--- /dev/null
+++ b/lib/dns/sec/dst/dst_result.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 1998, 1999 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Principal Author: Brian Wellington
+ * $Id: dst_result.c,v 1.3 1999/09/27 16:55:44 bwelling Exp $
+ */
+
+#include <config.h>
+
+#include <stddef.h>
+
+#include <isc/resultclass.h>
+#include <isc/once.h>
+#include <isc/error.h>
+
+#include <dst/result.h>
+#include <dst/lib.h>
+
+static char *text[DST_R_NRESULTS] = {
+ "algorithm is unsupported", /* 0 */
+ "key type is unsupported", /* 1 */
+ "signature mode is unsupported", /* 2 */
+ "illegal operation for a null key", /* 3 */
+ "public key is invalid", /* 4 */
+ "private key is invalid", /* 5 */
+ "key name is too long", /* 6 */
+ "error occurred writing key to disk", /* 7 */
+ "invalid algorithm specific parameter", /* 8 */
+ "sign init failure", /* 9 */
+ "sign update failure", /* 10 */
+ "sign final failure", /* 11 */
+ "verify init failure", /* 12 */
+ "verify update failure", /* 13 */
+ "verify final failure", /* 14 */
+ "not a public key", /* 15 */
+ "not a private key", /* 16 */
+ "not a key that can compute a secret", /* 17 */
+ "failure computing a shared secret", /* 18 */
+};
+
+#define DST_RESULT_RESULTSET 2
+
+static isc_once_t once = ISC_ONCE_INIT;
+
+static void
+initialize_action(void) {
+ isc_result_t result;
+
+ result = isc_result_register(ISC_RESULTCLASS_DST, DST_R_NRESULTS,
+ text, dst_msgcat, DST_RESULT_RESULTSET);
+ if (result != ISC_R_SUCCESS)
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "isc_result_register() failed: %u", result);
+}
+
+static void
+initialize(void) {
+ dst_lib_initmsgcat();
+ RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
+}
+
+char *
+dst_result_totext(dst_result_t result) {
+ initialize();
+
+ return (isc_result_totext(result));
+}
+
+void
+dst_result_register(void) {
+ initialize();
+}
diff --git a/lib/dns/sec/dst/dst_support.c b/lib/dns/sec/dst/dst_support.c
new file mode 100644
index 00000000..a2d42a9d
--- /dev/null
+++ b/lib/dns/sec/dst/dst_support.c
@@ -0,0 +1,129 @@
+/*
+ * Portions Copyright (c) 1995-1999 by Network Associates, Inc.
+ *
+ * Permission to use, copy modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND NETWORK ASSOCIATES
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * NETWORK ASSOCIATES BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THE SOFTWARE.
+ */
+
+/*
+ * Principal Author: Brian Wellington
+ * $Id: dst_support.c,v 1.3 1999/11/02 19:52:29 bwelling Exp $
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <memory.h>
+#include <string.h>
+#include <isc/int.h>
+
+#include "dst_internal.h"
+
+/*
+ * dst_s_calculate_bits
+ * Given a binary number represented by a u_char[], determine
+ * the number of significant bits used.
+ * Parameters
+ * str An input character string containing a binary number.
+ * max_bits The maximum possible significant bits.
+ * Return
+ * N The number of significant bits in str.
+ */
+
+int
+dst_s_calculate_bits(const unsigned char *str, const int max_bits)
+{
+ const unsigned char *p = str;
+ unsigned char i, j = 0x80;
+ int bits;
+ for (bits = max_bits; *p == 0x00 && bits > 0; p++)
+ bits -= 8;
+ for (i = *p; (i & j) != j; j >>= 1)
+ bits--;
+ return (bits);
+}
+
+
+/*
+ * dst_s_id_calc
+ * Calculates the checksum used by DNS as a key id.
+ * Parameters
+ * key The key in DNS format
+ * length The length of the array
+ * Return
+ * N the 16 bit checksum.
+ */
+isc_uint16_t
+dst_s_id_calc(const unsigned char *key, const int keysize)
+{
+ isc_uint32_t ac;
+ const unsigned char *kp = key;
+ int size = keysize;
+
+ if (key == NULL || (keysize <= 0))
+ return (-1);
+
+ for (ac = 0; size > 1; size -= 2, kp += 2)
+ ac += ((*kp) << 8) + *(kp + 1);
+
+ if (size > 0)
+ ac += ((*kp) << 8);
+ ac += (ac >> 16) & 0xffff;
+
+ return ((isc_uint16_t)(ac & 0xffff));
+}
+
+/*
+ * dst_s_build_filename
+ * Builds a key filename from the key name, its id, and a
+ * suffix. '\', '/' and ':' are not allowed. fA filename is of the
+ * form: K<keyname><id>.<suffix>
+ * form: K<keyname>+<alg>+<id>.<suffix>
+ *
+ * Returns -1 if the conversion fails:
+ * if the filename would be too long for space allotted
+ * if the filename would contain a '\', '/' or ':'
+ * Returns 0 on success
+ */
+
+int
+dst_s_build_filename(char *filename, const char *name, isc_uint16_t id,
+ int alg, const char *suffix, size_t filename_length)
+{
+ isc_uint32_t my_id;
+ char *dot;
+ if (filename == NULL)
+ return (-1);
+ memset(filename, 0, filename_length);
+ if (name == NULL)
+ return (-1);
+ if (suffix == NULL)
+ return (-1);
+ if (filename_length < 1 + strlen(name) + 1 + 4 + 6 + 1 + strlen(suffix))
+ return (-1);
+ my_id = id;
+ if (name[strlen(name) - 1] == '.')
+ dot = "";
+ else
+ dot = ".";
+ sprintf(filename, "K%s%s+%03d+%05d.%s", name, dot, alg, my_id,
+ (char *) suffix);
+ if (strrchr(filename, '/'))
+ return (-1);
+ if (strrchr(filename, '\\'))
+ return (-1);
+ if (strrchr(filename, ':'))
+ return (-1);
+ return (0);
+}
diff --git a/lib/dns/sec/dst/hmac_link.c b/lib/dns/sec/dst/hmac_link.c
new file mode 100644
index 00000000..6cc2c0b8
--- /dev/null
+++ b/lib/dns/sec/dst/hmac_link.c
@@ -0,0 +1,504 @@
+/*
+ * Portions Copyright (c) 1995-1998 by Network Associates, Inc.
+ *
+ * Permission to use, copy modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND NETWORK ASSOCIATES
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * NETWORK ASSOCIATES BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THE SOFTWARE.
+ */
+
+/*
+ * Principal Author: Brian Wellington
+ * $Id: hmac_link.c,v 1.15 1999/10/29 05:25:57 marka Exp $
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+
+#include <isc/assertions.h>
+#include <isc/buffer.h>
+#include <isc/int.h>
+#include <isc/region.h>
+
+#include <openssl/md5.h>
+
+#include "dst_internal.h"
+#include "dst_parse.h"
+
+#define HMAC_LEN 64
+#define HMAC_IPAD 0x36
+#define HMAC_OPAD 0x5c
+
+#define MD5Init MD5_Init
+#define MD5Update MD5_Update
+#define MD5Final MD5_Final
+
+#define RETERR(x) do { \
+ ret = (x); \
+ if (ret != ISC_R_SUCCESS) \
+ return (ret); \
+ } while (0)
+
+typedef struct hmackey {
+ unsigned char ipad[64], opad[64];
+} HMAC_Key;
+
+static struct dst_func hmacmd5_functions;
+
+static dst_result_t dst_hmacmd5_sign(const unsigned int mode,
+ dst_key_t *key,
+ void **context, isc_region_t *data,
+ isc_buffer_t *sig, isc_mem_t *mctx);
+static dst_result_t dst_hmacmd5_verify(const unsigned int mode,
+ dst_key_t *key,
+ void **context, isc_region_t *data,
+ isc_region_t *sig, isc_mem_t *mctx);
+static isc_boolean_t dst_hmacmd5_compare(const dst_key_t *key1,
+ const dst_key_t *key2);
+static dst_result_t dst_hmacmd5_generate(dst_key_t *key, int exp,
+ isc_mem_t *mctx);
+static isc_boolean_t dst_hmacmd5_isprivate(const dst_key_t *key);
+static void dst_hmacmd5_destroy(void *key, isc_mem_t *mctx);
+static dst_result_t dst_hmacmd5_to_dns(const dst_key_t *in_key,
+ isc_buffer_t *data);
+static dst_result_t dst_hmacmd5_from_dns(dst_key_t *key, isc_buffer_t *data,
+ isc_mem_t *mctx);
+static dst_result_t dst_hmacmd5_to_file(const dst_key_t *key);
+static dst_result_t dst_hmacmd5_from_file(dst_key_t *key,
+ const isc_uint16_t id,
+ isc_mem_t *mctx);
+
+/*
+ * dst_s_hmacmd5_init()
+ * Sets up function pointers for HMAC-MD5 related functions
+ */
+void
+dst_s_hmacmd5_init()
+{
+ REQUIRE(dst_t_func[DST_ALG_HMACMD5] == NULL);
+ dst_t_func[DST_ALG_HMACMD5] = &hmacmd5_functions;
+ memset(&hmacmd5_functions, 0, sizeof(struct dst_func));
+ hmacmd5_functions.sign = dst_hmacmd5_sign;
+ hmacmd5_functions.verify = dst_hmacmd5_verify;
+ hmacmd5_functions.computesecret = NULL;
+ hmacmd5_functions.compare = dst_hmacmd5_compare;
+ hmacmd5_functions.paramcompare = NULL;
+ hmacmd5_functions.generate = dst_hmacmd5_generate;
+ hmacmd5_functions.isprivate = dst_hmacmd5_isprivate;
+ hmacmd5_functions.destroy = dst_hmacmd5_destroy;
+ hmacmd5_functions.to_dns = dst_hmacmd5_to_dns;
+ hmacmd5_functions.from_dns = dst_hmacmd5_from_dns;
+ hmacmd5_functions.to_file = dst_hmacmd5_to_file;
+ hmacmd5_functions.from_file = dst_hmacmd5_from_file;
+}
+
+/*
+ * dst_hmacmd5_sign
+ * Call HMAC-MD5 signing functions to sign a block of data.
+ * There are three steps to signing, INIT (initialize structures),
+ * UPDATE (hash (more) data), FINAL (generate a signature). This
+ * routine performs one or more of these steps.
+ * Parameters
+ * mode DST_SIGMODE_{INIT_UPDATE_FINAL|ALL}
+ * key key to use for signing
+ * context the context to use for this computation
+ * data data to be signed
+ * signature buffer to store signature
+ * mctx memory context for temporary allocations
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+static dst_result_t
+dst_hmacmd5_sign(const unsigned int mode, dst_key_t *key, void **context,
+ isc_region_t *data, isc_buffer_t *sig, isc_mem_t *mctx)
+{
+ isc_region_t r;
+ isc_result_t ret;
+ void *ctx;
+
+ if ((mode & DST_SIGMODE_ALL) != DST_SIGMODE_ALL)
+ REQUIRE(context != NULL);
+ else
+ context = &ctx;
+
+ if (mode & DST_SIGMODE_INIT) {
+ HMAC_Key *hkey = key->opaque;
+
+ r.base = hkey->ipad;
+ r.length = HMAC_LEN;
+ RETERR(dst_s_md5(DST_SIGMODE_INIT, context, NULL, NULL, mctx));
+ RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, &r, NULL, mctx));
+ }
+ if (mode & DST_SIGMODE_UPDATE) {
+ RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, data, NULL,
+ mctx));
+ }
+ if (mode & DST_SIGMODE_FINAL) {
+ HMAC_Key *hkey = key->opaque;
+ unsigned char digest[MD5_DIGEST_LENGTH];
+ isc_buffer_t b;
+
+ isc_buffer_init(&b, digest, sizeof(digest),
+ ISC_BUFFERTYPE_BINARY);
+
+ RETERR(dst_s_md5(DST_SIGMODE_FINAL, context, NULL, &b, mctx));
+
+ RETERR(dst_s_md5(DST_SIGMODE_INIT, context, NULL, NULL, mctx));
+ r.base = hkey->opad;
+ r.length = HMAC_LEN;
+ RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, &r, NULL, mctx));
+ isc_buffer_used(&b, &r);
+ RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, &r, NULL, mctx));
+ RETERR(dst_s_md5(DST_SIGMODE_FINAL, context, NULL, sig, mctx));
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+
+/*
+ * dst_hmacmd5_verify
+ * Calls HMAC-MD5 verification routines. There are three steps to
+ * verification, INIT (initialize structures), UPDATE (hash (more) data),
+ * FINAL (generate a signature). This routine performs one or more of
+ * these steps.
+ * Parameters
+ * mode DST_SIGMODE_{INIT_UPDATE_FINAL|ALL}
+ * key key to use for verifying
+ * context the context to use for this computation
+ * data signed data
+ * signature signature
+ * mctx memory context for temporary allocations
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+static dst_result_t
+dst_hmacmd5_verify(const unsigned int mode, dst_key_t *key, void **context,
+ isc_region_t *data, isc_region_t *sig, isc_mem_t *mctx)
+{
+ isc_region_t r;
+ isc_result_t ret;
+ void *ctx;
+
+ if ((mode & DST_SIGMODE_ALL) != DST_SIGMODE_ALL)
+ REQUIRE(context != NULL);
+ else
+ context = &ctx;
+
+ if (mode & DST_SIGMODE_INIT) {
+ HMAC_Key *hkey = key->opaque;
+
+ r.base = hkey->ipad;
+ r.length = HMAC_LEN;
+ RETERR(dst_s_md5(DST_SIGMODE_INIT, context, NULL, NULL, mctx));
+ RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, &r, NULL, mctx));
+ }
+ if (mode & DST_SIGMODE_UPDATE) {
+ RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, data, NULL,
+ mctx));
+ }
+ if (mode & DST_SIGMODE_FINAL) {
+ HMAC_Key *hkey = key->opaque;
+ unsigned char digest[MD5_DIGEST_LENGTH];
+ isc_buffer_t b;
+
+ isc_buffer_init(&b, digest, sizeof(digest),
+ ISC_BUFFERTYPE_BINARY);
+
+ RETERR(dst_s_md5(DST_SIGMODE_FINAL, context, NULL, &b, mctx));
+
+ RETERR(dst_s_md5(DST_SIGMODE_INIT, context, NULL, NULL, mctx));
+ r.base = hkey->opad;
+ r.length = HMAC_LEN;
+ RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, &r, NULL, mctx));
+ isc_buffer_used(&b, &r);
+ RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, &r, NULL, mctx));
+ isc_buffer_clear(&b);
+ RETERR(dst_s_md5(DST_SIGMODE_FINAL, context, NULL, &b, mctx));
+
+ if (memcmp(digest, sig->base, MD5_DIGEST_LENGTH) != 0)
+ return (DST_R_VERIFYFINALFAILURE);
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+/*
+ * dst_hmacmd5_isprivate
+ * Is this a private key? Yes
+ * Parameters
+ * key DST KEY structure
+ * Returns
+ * ISC_TRUE
+ */
+static isc_boolean_t
+dst_hmacmd5_isprivate(const dst_key_t *key) {
+ key = key; /* suppress warning */
+
+ return (ISC_TRUE);
+}
+
+
+/*
+ * dst_hmacmd5_to_dns
+ * Converts key from HMAC to DNS rdata (raw bytes)
+ * Parameters
+ * key DST KEY structure
+ * data output data
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+
+static dst_result_t
+dst_hmacmd5_to_dns(const dst_key_t *key, isc_buffer_t *data) {
+ HMAC_Key *hkey;
+ isc_region_t r;
+ unsigned int bytes, i;
+
+ REQUIRE(key->opaque != NULL);
+
+ hkey = (HMAC_Key *) key->opaque;
+
+ isc_buffer_available(data, &r);
+
+ bytes = (key->key_size + 7) / 8;
+ if (r.length < bytes)
+ return (ISC_R_NOSPACE);
+
+ for (i = 0; i < bytes; i++)
+ *r.base++ = hkey->ipad[i] ^ HMAC_IPAD;
+
+ isc_buffer_add(data, bytes);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+/*
+ * dst_hmacmd5_from_dns
+ * Converts from a DNS KEY RR format to an HMAC-MD5 KEY.
+ * Parameters
+ * key Partially filled key structure
+ * data Buffer containing key in DNS format
+ * Return
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+static dst_result_t
+dst_hmacmd5_from_dns(dst_key_t *key, isc_buffer_t *data, isc_mem_t *mctx) {
+ HMAC_Key *hkey;
+ isc_region_t r;
+ int i, keylen;
+
+ isc_buffer_remaining(data, &r);
+ if (r.length == 0)
+ return (ISC_R_SUCCESS);
+
+ hkey = (HMAC_Key *) isc_mem_get(mctx, sizeof(HMAC_Key));
+ if (hkey == NULL)
+ return (ISC_R_NOMEMORY);
+
+ memset(hkey->ipad, 0, sizeof(hkey->ipad));
+ memset(hkey->opad, 0, sizeof(hkey->opad));
+
+ if (r.length > HMAC_LEN) {
+ MD5_CTX ctx;
+ unsigned char digest[MD5_DIGEST_LENGTH];
+
+ MD5Init(&ctx);
+ MD5Update(&ctx, r.base, r.length);
+ MD5Final(digest, &ctx);
+ memcpy(hkey->ipad, digest, MD5_DIGEST_LENGTH);
+ memcpy(hkey->opad, digest, MD5_DIGEST_LENGTH);
+ keylen = MD5_DIGEST_LENGTH;
+ }
+ else {
+ memcpy(hkey->ipad, r.base, r.length);
+ memcpy(hkey->opad, r.base, r.length);
+ keylen = r.length;
+ }
+
+ /* XOR key with ipad and opad values */
+ for (i = 0; i < HMAC_LEN; i++) {
+ hkey->ipad[i] ^= HMAC_IPAD;
+ hkey->opad[i] ^= HMAC_OPAD;
+ }
+ key->key_size = keylen * 8;
+ key->opaque = hkey;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+/*
+ * dst_hmacmd5_to_file
+ * Encodes an HMAC-MD5 Key into the portable file format.
+ * Parameters
+ * key DST KEY structure
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+static dst_result_t
+dst_hmacmd5_to_file(const dst_key_t *key) {
+ int i, cnt = 0;
+ HMAC_Key *hkey;
+ dst_private_t priv;
+ unsigned char keydata[HMAC_LEN];
+
+ if (key->opaque == NULL)
+ return (DST_R_NULLKEY);
+
+ hkey = (HMAC_Key *) key->opaque;
+ for (i = 0; i < HMAC_LEN; i++)
+ keydata[i] = hkey->ipad[i] ^ HMAC_IPAD;
+
+ priv.elements[cnt].tag = TAG_HMACMD5_KEY;
+ priv.elements[cnt].length = HMAC_LEN;
+ priv.elements[cnt++].data = keydata;
+
+ priv.nelements = cnt;
+ return (dst_s_write_private_key_file(key->key_name, key->key_alg,
+ key->key_id, &priv));
+}
+
+
+/*
+ * dst_hmacmd5_from_file
+ * Converts contents of a private key file into a private HMAC-MD5 key.
+ * Parameters
+ * key Partially filled HMAC-MD5 KEY structure
+ * id The key id
+ * path The directory that the file will be read from
+ * Return
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+
+static dst_result_t
+dst_hmacmd5_from_file(dst_key_t *key, const isc_uint16_t id, isc_mem_t *mctx) {
+ dst_private_t priv;
+ dst_result_t ret;
+ isc_buffer_t b;
+ HMAC_Key *hkey = NULL;
+#define DST_RET(a) {ret = a; goto err;}
+
+ /* read private key file */
+ ret = dst_s_parse_private_key_file(key->key_name, key->key_alg,
+ id, &priv, mctx);
+ if (ret != ISC_R_SUCCESS)
+ return (ret);
+
+ hkey = (HMAC_Key *) isc_mem_get(mctx, sizeof(HMAC_Key *));
+ if (hkey == NULL)
+ DST_RET(ISC_R_NOMEMORY);
+
+ key->opaque = hkey;
+ isc_buffer_init(&b, priv.elements[0].data, priv.elements[0].length,
+ ISC_BUFFERTYPE_BINARY);
+ ret = dst_hmacmd5_from_dns(key, &b, mctx);
+ if (ret != ISC_R_SUCCESS)
+ DST_RET(ret);
+
+ return (ISC_R_SUCCESS);
+
+ err:
+ dst_hmacmd5_destroy(hkey, mctx);
+ dst_s_free_private_structure_fields(&priv, mctx);
+ memset(&priv, 0, sizeof(priv));
+ return (ret);
+}
+
+/*
+ * dst_hmacmd5_destroy
+ * Frees all dynamically allocated structures in key.
+ */
+static void
+dst_hmacmd5_destroy(void *key, isc_mem_t *mctx) {
+ HMAC_Key *hkey = (HMAC_Key *) key;
+ memset(hkey, 0, sizeof(HMAC_Key));
+ isc_mem_put(mctx, hkey, sizeof(HMAC_Key));
+}
+
+
+/*
+ * dst_hmacmd5_generate
+ * Creates an HMAC-MD5 key. If the specified size is more than 512
+ * bits, a key of size 512 is generated.
+ * Parameters
+ * key DST Key structure
+ * unused algorithm specific data, unused for HMAC-MD5.
+ * mctx memory context to allocate key
+ * Return
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+
+static dst_result_t
+dst_hmacmd5_generate(dst_key_t *key, int unused, isc_mem_t *mctx) {
+ isc_buffer_t b;
+ dst_result_t ret;
+ int bytes;
+ unsigned char data[HMAC_LEN];
+
+ unused = unused; /* make the compiler happy */
+
+ bytes = (key->key_size + 7) / 8;
+ if (bytes > 64) {
+ bytes = 64;
+ key->key_size = 512;
+ }
+
+ memset(data, 0, HMAC_LEN);
+ isc_buffer_init(&b, data, sizeof(data), ISC_BUFFERTYPE_BINARY);
+ ret = dst_random_get(bytes, &b);
+ if (ret != ISC_R_SUCCESS)
+ return (ret);
+
+ ret = dst_hmacmd5_from_dns(key, &b, mctx);
+ memset(data, 0, HMAC_LEN);
+
+ return (ret);
+}
+
+
+/**************************************************************************
+ * dst_hmacmd5_compare
+ * Compare two keys for equality.
+ * Return
+ * ISC_TRUE The keys are equal
+ * ISC_FALSE The keys are not equal
+ */
+static isc_boolean_t
+dst_hmacmd5_compare(const dst_key_t *key1, const dst_key_t *key2) {
+ HMAC_Key *hkey1, *hkey2;
+
+ hkey1 = (HMAC_Key *) key1->opaque;
+ hkey2 = (HMAC_Key *) key2->opaque;
+
+ if (hkey1 == NULL && hkey2 == NULL)
+ return (ISC_TRUE);
+ else if (hkey1 == NULL || hkey2 == NULL)
+ return (ISC_FALSE);
+
+ if (memcmp(hkey1->ipad, hkey2->ipad, HMAC_LEN) == 0)
+ return (ISC_TRUE);
+ else
+ return (ISC_FALSE);
+}
diff --git a/lib/dns/sec/dst/include/.cvsignore b/lib/dns/sec/dst/include/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/lib/dns/sec/dst/include/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/lib/dns/sec/dst/include/Makefile.in b/lib/dns/sec/dst/include/Makefile.in
new file mode 100644
index 00000000..a0a07886
--- /dev/null
+++ b/lib/dns/sec/dst/include/Makefile.in
@@ -0,0 +1,23 @@
+# Copyright (C) 1998, 1999, 2000 Internet Software Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+# CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+# SOFTWARE.
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+SUBDIRS = dst
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/dns/sec/dst/include/dst/.cvsignore b/lib/dns/sec/dst/include/dst/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/lib/dns/sec/dst/include/dst/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/lib/dns/sec/dst/include/dst/Makefile.in b/lib/dns/sec/dst/include/dst/Makefile.in
new file mode 100644
index 00000000..89cb459f
--- /dev/null
+++ b/lib/dns/sec/dst/include/dst/Makefile.in
@@ -0,0 +1,40 @@
+# Copyright (C) 1998, 1999, 2000 Internet Software Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+# CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+# SOFTWARE.
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+HEADERS = dst.h lib.h result.h
+
+SUBDIRS =
+TARGETS =
+
+@BIND9_MAKE_RULES@
+
+installdirs:
+ if [ ! -d ${includedir} ]; then \
+ mkdir ${includedir} ; \
+ fi
+ if [ ! -d ${includedir}/dst ]; then \
+ mkdir ${includedir}/dst ; \
+ fi
+
+install:: installdirs
+ for i in ${HEADERS}; do \
+ ${INSTALL_DATA} ${srcdir}/$$i ${includedir}/dst ; \
+ done
diff --git a/lib/dns/sec/dst/include/dst/dst.h b/lib/dns/sec/dst/include/dst/dst.h
new file mode 100644
index 00000000..bc013cb6
--- /dev/null
+++ b/lib/dns/sec/dst/include/dst/dst.h
@@ -0,0 +1,332 @@
+#ifndef DST_DST_H
+#define DST_DST_H 1
+
+#include <isc/boolean.h>
+#include <isc/buffer.h>
+#include <isc/int.h>
+#include <isc/lang.h>
+#include <isc/mem.h>
+#include <isc/region.h>
+
+#include <dst/result.h>
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Types
+ ***/
+
+/*
+ * The dst_key structure is opaque. Applications should use the accessor
+ * functions provided to retrieve key attributes. If an application needs
+ * to set attributes, new accessor functions will be written.
+ */
+
+typedef struct dst_key dst_key_t;
+typedef void * dst_context_t;
+
+/* DST algorithm codes */
+#define DST_ALG_UNKNOWN 0
+#define DST_ALG_RSA 1
+#define DST_ALG_DH 2
+#define DST_ALG_DSA 3
+#define DST_ALG_HMACMD5 157
+#define DST_ALG_HMACSHA1 158 /* not implemented */
+#define DST_ALG_PRIVATE 254
+#define DST_ALG_EXPAND 255
+#define DST_MAX_ALGS DST_ALG_HMACSHA1
+
+/* DST algorithm codes */
+#define DST_DIGEST_MD5 258
+#define DST_DIGEST_SHA1 259
+
+/* 'Mode' passed into dst_sign() and dst_verify() */
+#define DST_SIGMODE_INIT 1 /* initialize digest */
+#define DST_SIGMODE_UPDATE 2 /* add data to digest */
+#define DST_SIGMODE_FINAL 4 /* generate/verify signature */
+#define DST_SIGMODE_ALL (DST_SIGMODE_INIT | \
+ DST_SIGMODE_UPDATE | \
+ DST_SIGMODE_FINAL)
+
+/* A buffer of this size is large enough to hold any key */
+#define DST_KEY_MAXSIZE 1024
+
+/* 'Type' for dst_read_key() */
+#define DST_TYPE_PRIVATE 0x2000000
+#define DST_TYPE_PUBLIC 0x4000000
+
+/***
+ *** Functions
+ ***/
+
+/*
+ * Check that a given algorithm is supported
+ */
+isc_boolean_t
+dst_supported_algorithm(const int alg);
+
+/* Sign a block of data.
+ *
+ * Requires:
+ * "mode" is some combination of DST_SIGMODE_INIT, DST_SIGMODE_UPDATE,
+ * and DST_SIGMODE_FINAL.
+ * "key" is a valid key.
+ * "context" contains a value appropriate for the value of "mode".
+ * "data" is a valid region.
+ * "sig" is a valid buffer.
+ *
+ * Ensures:
+ * All allocated memory will be freed after the FINAL call. "sig"
+ * will contain a signature if all operations completed successfully.
+ */
+dst_result_t
+dst_sign(const unsigned int mode, dst_key_t *key, dst_context_t *context,
+ isc_region_t *data, isc_buffer_t *sig);
+
+/* Verify a signature on a block of data.
+ *
+ * Requires:
+ * "mode" is some combination of DST_SIGMODE_INIT, DST_SIGMODE_UPDATE,
+ * and DST_SIGMODE_FINAL.
+ * "key" is a valid key.
+ * "context" contains a value appropriate for the value of "mode".
+ * "data" is a valid region.
+ * "sig" is a valid region.
+ *
+ * Ensures:
+ * All allocated memory will be freed after the FINAL call.
+ */
+dst_result_t
+dst_verify(const unsigned int mode, dst_key_t *key, dst_context_t *context,
+ isc_region_t *data, isc_region_t *sig);
+
+/* Digest a block of data.
+ *
+ * Requires:
+ * "mode" is some combination of DST_SIGMODE_INIT, DST_SIGMODE_UPDATE,
+ * and DST_SIGMODE_FINAL.
+ * "alg" is a valid digest algorithm
+ * "context" contains a value appropriate for the value of "mode".
+ * "data" is a valid region.
+ * "digest" is a valid buffer.
+ *
+ * Ensures:
+ * All allocated memory will be freed after the FINAL call. "digest"
+ * will contain a digest if all operations completed successfully.
+ */
+dst_result_t
+dst_digest(const unsigned int mode, const unsigned int alg,
+ dst_context_t *context, isc_region_t *data, isc_buffer_t *digest);
+
+/*
+ * dst_computesecret
+ * A function to compute a shared secret from two (Diffie-Hellman) keys.
+ *
+ * Requires:
+ * "pub" is a valid key that can be used to derive a shared secret
+ * "priv" is a valid private key that can be used to derive a shared secret
+ * "secret" is a valid buffer
+ *
+ * Ensures:
+ * If successful, secret will contain the derived shared secret.
+ */
+dst_result_t
+dst_computesecret(const dst_key_t *pub, const dst_key_t *priv,
+ isc_buffer_t *secret);
+
+/* Reads a key from permanent storage.
+ *
+ * Requires:
+ * "name" is not NULL.
+ * "id" is a valid key tag identifier.
+ * "alg" is a supported key algorithm.
+ * "type" is either DST_TYPE_PUBLIC or DST_TYPE_PRIVATE.
+ * "mctx" is a valid memory context.
+ * "keyp" is not NULL.
+ *
+ * Ensures:
+ * If successful, *keyp will contain a valid key.
+ */
+dst_result_t
+dst_key_fromfile(const char *name, const isc_uint16_t id, const int alg,
+ const int type, isc_mem_t *mctx, dst_key_t **keyp);
+
+/* Writes a key to permanent storage.
+ *
+ * Requires:
+ * "key" is a valid key.
+ * "type" is either DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or both.
+ */
+dst_result_t
+dst_key_tofile(const dst_key_t *key, const int type);
+
+/* Converts a DNS KEY record into a DST key.
+ *
+ * Requires:
+ * "name" is not NULL.
+ * "source" is a valid buffer. There must be at least 4 bytes available.
+ * "mctx" is a valid memory context.
+ * "keyp" is not NULL.
+ *
+ * Ensures:
+ * If successful, *keyp will contain a valid key, and the consumed
+ * pointer in data will be advanced.
+ */
+dst_result_t
+dst_key_fromdns(const char *name, isc_buffer_t *source, isc_mem_t *mctx,
+ dst_key_t **keyp);
+
+/* Converts a DST key into a DNS KEY record.
+ *
+ * Requires:
+ * "key" is a valid key.
+ * "target" is a valid buffer. There must be at least 4 bytes unused.
+ *
+ * Ensures:
+ * If successful, the used pointer in 'target' is advanced by at least 4.
+ */
+dst_result_t
+dst_key_todns(const dst_key_t *key, isc_buffer_t *target);
+
+/* Converts a buffer containing DNS KEY RDATA into a DST key.
+ *
+ * Requires:
+ * "name" is not NULL.
+ * "alg" is a supported key algorithm.
+ * "source" is a valid buffer.
+ * "mctx" is a valid memory context.
+ * "keyp" is not NULL.
+ *
+ * Ensures:
+ * If successful, *keyp will contain a valid key, and the consumed
+ * pointer in source will be advanced.
+ */
+dst_result_t
+dst_key_frombuffer(const char *name, const int alg, const int flags,
+ const int protocol, isc_buffer_t *source, isc_mem_t *mctx,
+ dst_key_t **keyp);
+
+/* Converts a DST key into DNS KEY RDATA format.
+ *
+ * Requires:
+ * "key" is a valid key.
+ * "target" is a valid buffer.
+ *
+ * Ensures:
+ * If successful, the used pointer in 'target' is advanced.
+ */
+dst_result_t
+dst_key_tobuffer(const dst_key_t *key, isc_buffer_t *target);
+
+/* Generate a DST key (or keypair)
+ *
+ * Requires:
+ * "name" is not NULL
+ * "alg" is a supported algorithm
+ * "bits" is a valid key size for the given algorithm
+ * "keyp" is not NULL.
+ *
+ * Ensures:
+ * If successful, *keyp will contain a valid key.
+ */
+dst_result_t
+dst_key_generate(const char *name, const int alg, const int bits,
+ const int param, const int flags, const int protocol,
+ isc_mem_t *mctx, dst_key_t **keyp);
+
+/* Compares two DST keys.
+ *
+ * Requires:
+ * "key1" is a valid key.
+ * "key2" is a valid key.
+ */
+isc_boolean_t
+dst_key_compare(const dst_key_t *key1, const dst_key_t *key2);
+
+/* Compares the parameters of two DST keys.
+ *
+ * Requires:
+ * "key1" is a valid key.
+ * "key2" is a valid key.
+ */
+isc_boolean_t
+dst_key_paramcompare(const dst_key_t *key1, const dst_key_t *key2);
+
+/* Free a DST key.
+ *
+ * Requires:
+ * "key" is a valid key.
+ *
+ * Ensures:
+ * All memory associated with "key" will be freed.
+ */
+void
+dst_key_free(dst_key_t *key);
+
+/* Accessor functions to obtain key fields.
+ *
+ * Require:
+ * "key" is a valid key.
+ */
+char *
+dst_key_name(const dst_key_t *key);
+
+int
+dst_key_size(const dst_key_t *key);
+
+int
+dst_key_proto(const dst_key_t *key);
+
+int
+dst_key_alg(const dst_key_t *key);
+
+isc_uint32_t
+dst_key_flags(const dst_key_t *key);
+
+isc_uint16_t
+dst_key_id(const dst_key_t *key);
+
+isc_boolean_t
+dst_key_isprivate(const dst_key_t *key);
+
+/* Computes the size of a signature generated by the given key.
+ *
+ * Requires:
+ * "key" is a valid key.
+ * "n" is not NULL
+ *
+ * Returns:
+ * ISC_R_SUCCESS
+ * DST_R_UNSUPPORTEDALG
+ */
+isc_result_t
+dst_sig_size(const dst_key_t *key, unsigned int *n);
+
+/* Computes the size of a shared secret generated by the given key.
+ *
+ * Requires:
+ * "key" is a valid key.
+ * "n" is not NULL
+ *
+ * Returns:
+ * ISC_R_SUCCESS
+ * DST_R_UNSUPPORTEDALG
+ */
+isc_result_t
+dst_secret_size(const dst_key_t *key, unsigned int *n);
+
+/* Generate random data.
+ *
+ * Requires:
+ * "data" is a valid buffer, with at least "wanted" bytes available.
+ *
+ * Ensures:
+ * <= wanted bytes will be written to "data", and the used pointer will
+ * be advanced.
+ */
+dst_result_t
+dst_random_get(const unsigned int wanted, isc_buffer_t *data);
+
+ISC_LANG_ENDDECLS
+
+#endif /* DST_DST_H */
diff --git a/lib/dns/sec/dst/include/dst/lib.h b/lib/dns/sec/dst/include/dst/lib.h
new file mode 100644
index 00000000..309c67fd
--- /dev/null
+++ b/lib/dns/sec/dst/include/dst/lib.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 1999 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifndef DST_LIB_H
+#define DST_LIB_H 1
+
+#include <isc/types.h>
+#include <isc/lang.h>
+
+ISC_LANG_BEGINDECLS
+
+extern isc_msgcat_t *dst_msgcat;
+
+void
+dst_lib_initmsgcat(void);
+/*
+ * Initialize the DST library's message catalog, dst_msgcat, if it
+ * has not already been initialized.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* DST_LIB_H */
diff --git a/lib/dns/sec/dst/include/dst/result.h b/lib/dns/sec/dst/include/dst/result.h
new file mode 100644
index 00000000..38a58aad
--- /dev/null
+++ b/lib/dns/sec/dst/include/dst/result.h
@@ -0,0 +1,40 @@
+#ifndef DST_RESULT_H
+#define DST_RESULT_H 1
+
+#include <isc/lang.h>
+#include <isc/result.h>
+#include <isc/resultclass.h>
+
+ISC_LANG_BEGINDECLS
+
+typedef unsigned int dst_result_t;
+
+#define DST_R_UNSUPPORTEDALG (ISC_RESULTCLASS_DST + 0)
+#define DST_R_UNSUPPORTEDTYPE (ISC_RESULTCLASS_DST + 1)
+#define DST_R_UNSUPPORTEDMODE (ISC_RESULTCLASS_DST + 2)
+#define DST_R_NULLKEY (ISC_RESULTCLASS_DST + 3)
+#define DST_R_INVALIDPUBLICKEY (ISC_RESULTCLASS_DST + 4)
+#define DST_R_INVALIDPRIVATEKEY (ISC_RESULTCLASS_DST + 5)
+#define DST_R_NAMETOOLONG (ISC_RESULTCLASS_DST + 6)
+#define DST_R_WRITEERROR (ISC_RESULTCLASS_DST + 7)
+#define DST_R_INVALIDPARAM (ISC_RESULTCLASS_DST + 8)
+#define DST_R_SIGNINITFAILURE (ISC_RESULTCLASS_DST + 9)
+#define DST_R_SIGNUPDATEFAILURE (ISC_RESULTCLASS_DST + 10)
+#define DST_R_SIGNFINALFAILURE (ISC_RESULTCLASS_DST + 11)
+#define DST_R_VERIFYINITFAILURE (ISC_RESULTCLASS_DST + 12)
+#define DST_R_VERIFYUPDATEFAILURE (ISC_RESULTCLASS_DST + 13)
+#define DST_R_VERIFYFINALFAILURE (ISC_RESULTCLASS_DST + 14)
+#define DST_R_NOTPUBLICKEY (ISC_RESULTCLASS_DST + 15)
+#define DST_R_NOTPRIVATEKEY (ISC_RESULTCLASS_DST + 16)
+#define DST_R_KEYCANNOTCOMPUTESECRET (ISC_RESULTCLASS_DST + 17)
+#define DST_R_COMPUTESECRETFAILURE (ISC_RESULTCLASS_DST + 18)
+
+#define DST_R_NRESULTS 19 /* Number of results */
+
+
+char * dst_result_totext(dst_result_t);
+void dst_result_register(void);
+
+ISC_LANG_ENDDECLS
+
+#endif /* DST_RESULT_H */
diff --git a/lib/dns/sec/dst/openssl_link.c b/lib/dns/sec/dst/openssl_link.c
new file mode 100644
index 00000000..b718aec1
--- /dev/null
+++ b/lib/dns/sec/dst/openssl_link.c
@@ -0,0 +1,628 @@
+#if defined(OPENSSL)
+
+/*
+ * Portions Copyright (c) 1995-1998 by Network Associates, Inc.
+ *
+ * Permission to use, copy modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND NETWORK ASSOCIATES
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * NETWORK ASSOCIATES BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THE SOFTWARE.
+ */
+
+/*
+ * Principal Author: Brian Wellington
+ * $Id: openssl_link.c,v 1.12 1999/10/29 12:56:57 marka Exp $
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+
+#include <isc/assertions.h>
+#include <isc/buffer.h>
+#include <isc/int.h>
+#include <isc/region.h>
+
+#include "dst_internal.h"
+#include "dst_parse.h"
+
+#include <openssl/crypto.h>
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/sha.h>
+
+static struct dst_func openssl_functions;
+
+static dst_result_t dst_openssl_sign(const unsigned int mode,
+ dst_key_t *key,
+ void **context, isc_region_t *data,
+ isc_buffer_t *sig, isc_mem_t *mctx);
+static dst_result_t dst_openssl_verify(const unsigned int mode,
+ dst_key_t *key,
+ void **context, isc_region_t *data,
+ isc_region_t *sig, isc_mem_t *mctx);
+static isc_boolean_t dst_openssl_compare(const dst_key_t *key1,
+ const dst_key_t *key2);
+static dst_result_t dst_openssl_generate(dst_key_t *key, int unused,
+ isc_mem_t *mctx);
+static isc_boolean_t dst_openssl_isprivate(const dst_key_t *key);
+static void dst_openssl_destroy(void *key, isc_mem_t *mctx);
+static dst_result_t dst_openssl_to_dns(const dst_key_t *in_key,
+ isc_buffer_t *data);
+static dst_result_t dst_openssl_from_dns(dst_key_t *key, isc_buffer_t *data,
+ isc_mem_t *mctx);
+static dst_result_t dst_openssl_to_file(const dst_key_t *key);
+static dst_result_t dst_openssl_from_file(dst_key_t *key,
+ const isc_uint16_t id,
+ isc_mem_t *mctx);
+
+static int BN_bn2bin_fixed(BIGNUM *bn, unsigned char *buf,
+ int size);
+
+
+/*
+ * dst_s_openssldsa_init()
+ * Sets up function pointers for OpenSSL related functions
+ */
+void
+dst_s_openssldsa_init() {
+ REQUIRE(dst_t_func[DST_ALG_DSA] == NULL);
+ dst_t_func[DST_ALG_DSA] = &openssl_functions;
+ memset(&openssl_functions, 0, sizeof(struct dst_func));
+ openssl_functions.sign = dst_openssl_sign;
+ openssl_functions.verify = dst_openssl_verify;
+ openssl_functions.computesecret = NULL;
+ openssl_functions.compare = dst_openssl_compare;
+ openssl_functions.paramcompare = NULL; /* is this useful for DSA? */
+ openssl_functions.generate = dst_openssl_generate;
+ openssl_functions.isprivate = dst_openssl_isprivate;
+ openssl_functions.destroy = dst_openssl_destroy;
+ openssl_functions.to_dns = dst_openssl_to_dns;
+ openssl_functions.from_dns = dst_openssl_from_dns;
+ openssl_functions.to_file = dst_openssl_to_file;
+ openssl_functions.from_file = dst_openssl_from_file;
+ CRYPTO_set_mem_functions(dst_mem_alloc, dst_mem_realloc, dst_mem_free);
+}
+
+/*
+ * dst_openssl_sign
+ * Call OpenSSL signing functions to sign a block of data.
+ * There are three steps to signing, INIT (initialize structures),
+ * UPDATE (hash (more) data), FINAL (generate a signature). This
+ * routine performs one or more of these steps.
+ * Parameters
+ * mode DST_SIGMODE_{INIT_UPDATE_FINAL|ALL}
+ * key key to use for signing
+ * context the context to use for this computation
+ * data data to be signed
+ * signature buffer to store signature
+ * mctx memory context for temporary allocations
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+static dst_result_t
+dst_openssl_sign(const unsigned int mode, dst_key_t *key, void **context,
+ isc_region_t *data, isc_buffer_t *sig, isc_mem_t *mctx)
+{
+ isc_region_t r;
+ SHA_CTX *ctx = NULL;
+
+ if (mode & DST_SIGMODE_INIT) {
+ ctx = (SHA_CTX *) isc_mem_get(mctx, sizeof(SHA_CTX));
+ if (ctx == NULL)
+ return (ISC_R_NOMEMORY);
+ }
+ else if (context != NULL)
+ ctx = (SHA_CTX *) *context;
+ REQUIRE (ctx != NULL);
+
+ if (mode & DST_SIGMODE_INIT)
+ SHA1_Init(ctx);
+
+ if ((mode & DST_SIGMODE_UPDATE))
+ SHA1_Update(ctx, data->base, data->length);
+
+ if (mode & DST_SIGMODE_FINAL) {
+ DSA *dsa;
+ DSA_SIG *dsasig;
+ unsigned char digest[SHA_DIGEST_LENGTH];
+
+ isc_buffer_available(sig, &r);
+ if (r.length < SHA_DIGEST_LENGTH * 2 + 1)
+ return (ISC_R_NOSPACE);
+
+ dsa = key->opaque;
+
+ SHA1_Final(digest, ctx);
+ isc_mem_put(mctx, ctx, sizeof(SHA_CTX));
+
+ dsasig = DSA_do_sign(digest, SHA_DIGEST_LENGTH, dsa);
+ if (dsasig == NULL)
+ return (DST_R_SIGNFINALFAILURE);
+
+ *r.base++ = (key->key_size - 512)/64;
+ BN_bn2bin_fixed(dsasig->r, r.base, SHA_DIGEST_LENGTH);
+ r.base += SHA_DIGEST_LENGTH;
+ BN_bn2bin_fixed(dsasig->s, r.base, SHA_DIGEST_LENGTH);
+ r.base += SHA_DIGEST_LENGTH;
+ DSA_SIG_free(dsasig);
+ isc_buffer_add(sig, SHA_DIGEST_LENGTH * 2 + 1);
+ }
+ else
+ *context = ctx;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+/*
+ * dst_openssl_verify
+ * Calls OpenSSL verification routines. There are three steps to
+ * verification, INIT (initialize structures), UPDATE (hash (more) data),
+ * FINAL (generate a signature). This routine performs one or more of
+ * these steps.
+ * Parameters
+ * mode DST_SIGMODE_{INIT_UPDATE_FINAL|ALL}
+ * key key to use for verifying
+ * context the context to use for this computation
+ * data signed data
+ * signature signature
+ * mctx memory context for temporary allocations
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+static dst_result_t
+dst_openssl_verify(const unsigned int mode, dst_key_t *key, void **context,
+ isc_region_t *data, isc_region_t *sig, isc_mem_t *mctx)
+{
+ int status = 0;
+ SHA_CTX *ctx = NULL;
+
+ if (mode & DST_SIGMODE_INIT) {
+ ctx = (SHA_CTX *) isc_mem_get(mctx, sizeof(SHA_CTX));
+ if (ctx == NULL)
+ return (ISC_R_NOMEMORY);
+ }
+ else if (context != NULL)
+ ctx = (SHA_CTX *) *context;
+ REQUIRE (ctx != NULL);
+
+ if (mode & DST_SIGMODE_INIT)
+ SHA1_Init(ctx);
+
+ if ((mode & DST_SIGMODE_UPDATE))
+ SHA1_Update(ctx, data->base, data->length);
+
+ if (mode & DST_SIGMODE_FINAL) {
+ DSA *dsa;
+ DSA_SIG *dsasig;
+ unsigned char digest[SHA_DIGEST_LENGTH];
+ unsigned char *cp = sig->base;
+
+ dsa = key->opaque;
+
+ SHA1_Final(digest, ctx);
+ isc_mem_put(mctx, ctx, sizeof(SHA_CTX));
+
+ if (sig->length < 2 * SHA_DIGEST_LENGTH + 1)
+ return (DST_R_VERIFYFINALFAILURE);
+
+ cp++; /* Skip T */
+ dsasig = DSA_SIG_new();
+ dsasig->r = BN_bin2bn(cp, SHA_DIGEST_LENGTH, NULL);
+ cp += SHA_DIGEST_LENGTH;
+ dsasig->s = BN_bin2bn(cp, SHA_DIGEST_LENGTH, NULL);
+ cp += SHA_DIGEST_LENGTH;
+
+ status = DSA_do_verify(digest, SHA_DIGEST_LENGTH, dsasig, dsa);
+ DSA_SIG_free(dsasig);
+ if (status == 0)
+ return (DST_R_VERIFYFINALFAILURE);
+ }
+ else
+ *context = ctx;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+/*
+ * dst_openssl_isprivate
+ * Is this a private key?
+ * Parameters
+ * key DST KEY structure
+ * Returns
+ * ISC_TRUE
+ * ISC_FALSE
+ */
+static isc_boolean_t
+dst_openssl_isprivate(const dst_key_t *key) {
+ DSA *dsa = (DSA *) key->opaque;
+ return (ISC_TF(dsa != NULL && dsa->priv_key != NULL));
+}
+
+
+/*
+ * dst_openssl_to_dns
+ * Converts key from DSA to DNS distribution format
+ * Parameters
+ * key DST KEY structure
+ * data output data
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+
+static dst_result_t
+dst_openssl_to_dns(const dst_key_t *key, isc_buffer_t *data) {
+ DSA *dsa;
+ isc_region_t r;
+ int dnslen;
+ unsigned int t;
+
+ REQUIRE(key->opaque != NULL);
+
+ dsa = (DSA *) key->opaque;
+
+ isc_buffer_available(data, &r);
+
+ t = (BN_num_bytes(dsa->p) - 64) / 8;
+ if (t > 8)
+ return (DST_R_INVALIDPUBLICKEY);
+
+ dnslen = 1 + (key->key_size * 3)/8 + SHA_DIGEST_LENGTH;
+ if (r.length < (unsigned int) dnslen)
+ return (ISC_R_NOSPACE);
+
+ *r.base++ = t;
+ BN_bn2bin_fixed(dsa->q, r.base, SHA_DIGEST_LENGTH);
+ r.base += SHA_DIGEST_LENGTH;
+ BN_bn2bin_fixed(dsa->p, r.base, key->key_size/8);
+ r.base += key->key_size/8;
+ BN_bn2bin_fixed(dsa->g, r.base, key->key_size/8);
+ r.base += key->key_size/8;
+ BN_bn2bin_fixed(dsa->pub_key, r.base, key->key_size/8);
+ r.base += key->key_size/8;
+
+ isc_buffer_add(data, dnslen);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+/*
+ * dst_openssl_from_dns
+ * Converts from a DNS KEY RR format to a DSA KEY.
+ * Parameters
+ * key Partially filled key structure
+ * data Buffer containing key in DNS format
+ * Return
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+static dst_result_t
+dst_openssl_from_dns(dst_key_t *key, isc_buffer_t *data, isc_mem_t *mctx) {
+ DSA *dsa;
+ isc_region_t r;
+ unsigned int t, p_bytes;
+
+ mctx = mctx; /* make the compiler happy */
+
+ isc_buffer_remaining(data, &r);
+ if (r.length == 0)
+ return (ISC_R_SUCCESS);
+
+ dsa = DSA_new();
+/* dsa = (DSA *) isc_mem_get(mctx, sizeof(DSA));*/
+ if (dsa == NULL)
+ return (ISC_R_NOMEMORY);
+
+ memset(dsa, 0, sizeof(DSA));
+
+ t = (unsigned int) *r.base++;
+ if (t > 8) {
+ DSA_free(dsa);
+ return (DST_R_INVALIDPUBLICKEY);
+ }
+ p_bytes = 64 + 8 * t;
+
+ if (r.length < 1 + SHA_DIGEST_LENGTH + 3 * p_bytes) {
+ DSA_free(dsa);
+ return (DST_R_INVALIDPUBLICKEY);
+ }
+
+ dsa->q = BN_bin2bn(r.base, SHA_DIGEST_LENGTH, NULL);
+ r.base += SHA_DIGEST_LENGTH;
+
+ dsa->p = BN_bin2bn(r.base, p_bytes, NULL);
+ r.base += SHA_DIGEST_LENGTH;
+
+ dsa->g = BN_bin2bn(r.base, p_bytes, NULL);
+ r.base += SHA_DIGEST_LENGTH;
+
+ dsa->pub_key = BN_bin2bn(r.base, p_bytes, NULL);
+ r.base += SHA_DIGEST_LENGTH;
+
+ isc_buffer_remaining(data, &r);
+ key->key_id = dst_s_id_calc(r.base,
+ 1 + SHA_DIGEST_LENGTH + 3 * p_bytes);
+ key->key_size = p_bytes * 8;
+
+ isc_buffer_forward(data, SHA_DIGEST_LENGTH + 3 * p_bytes);
+
+ key->opaque = (void *) dsa;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+/*
+ * dst_openssl_to_file
+ * Encodes a DSA Key into the portable file format.
+ * Parameters
+ * key DST KEY structure
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+static dst_result_t
+dst_openssl_to_file(const dst_key_t *key) {
+ int cnt = 0;
+ DSA *dsa;
+ dst_private_t priv;
+ unsigned char bufs[5][128];
+
+ if (key->opaque == NULL)
+ return (DST_R_NULLKEY);
+
+ dsa = (DSA *) key->opaque;
+
+ priv.elements[cnt].tag = TAG_DSA_PRIME;
+ priv.elements[cnt].length = BN_num_bytes(dsa->p);
+ BN_bn2bin(dsa->p, bufs[cnt]);
+ priv.elements[cnt].data = bufs[cnt];
+ cnt++;
+
+ priv.elements[cnt].tag = TAG_DSA_SUBPRIME;
+ priv.elements[cnt].length = BN_num_bytes(dsa->q);
+ BN_bn2bin(dsa->q, bufs[cnt]);
+ priv.elements[cnt].data = bufs[cnt];
+ cnt++;
+
+ priv.elements[cnt].tag = TAG_DSA_BASE;
+ priv.elements[cnt].length = BN_num_bytes(dsa->g);
+ BN_bn2bin(dsa->g, bufs[cnt]);
+ priv.elements[cnt].data = bufs[cnt];
+ cnt++;
+
+ priv.elements[cnt].tag = TAG_DSA_PRIVATE;
+ priv.elements[cnt].length = BN_num_bytes(dsa->priv_key);
+ BN_bn2bin(dsa->priv_key, bufs[cnt]);
+ priv.elements[cnt].data = bufs[cnt];
+ cnt++;
+
+ priv.elements[cnt].tag = TAG_DSA_PUBLIC;
+ priv.elements[cnt].length = BN_num_bytes(dsa->pub_key);
+ BN_bn2bin(dsa->pub_key, bufs[cnt]);
+ priv.elements[cnt].data = bufs[cnt];
+ cnt++;
+
+ priv.nelements = cnt;
+ return (dst_s_write_private_key_file(key->key_name, key->key_alg,
+ key->key_id, &priv));
+}
+
+
+/*
+ * dst_openssl_from_file
+ * Converts contents of a private key file into a private DSA key.
+ * Parameters
+ * key Partially filled DSA KEY structure
+ * id The key id
+ * path The directory that the file will be read from
+ * Return
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+
+static dst_result_t
+dst_openssl_from_file(dst_key_t *key, const isc_uint16_t id, isc_mem_t *mctx) {
+ dst_private_t priv;
+ dst_result_t ret;
+ isc_buffer_t dns;
+ isc_region_t r;
+ unsigned char dns_array[1024];
+ int i;
+ DSA *dsa = NULL;
+#define DST_RET(a) {ret = a; goto err;}
+
+ /* read private key file */
+ ret = dst_s_parse_private_key_file(key->key_name, key->key_alg,
+ id, &priv, mctx);
+ if (ret != ISC_R_SUCCESS)
+ return (ret);
+
+ dsa = DSA_new();
+ if (dsa == NULL)
+ DST_RET(ISC_R_NOMEMORY);
+ memset(dsa, 0, sizeof(DSA));
+ key->opaque = dsa;
+
+ for (i=0; i < priv.nelements; i++) {
+ BIGNUM *bn;
+ bn = BN_bin2bn(priv.elements[i].data,
+ priv.elements[i].length, NULL);
+ if (bn == NULL)
+ DST_RET(ISC_R_NOMEMORY);
+
+ switch (priv.elements[i].tag) {
+ case TAG_DSA_PRIME:
+ dsa->p = bn;
+ break;
+ case TAG_DSA_SUBPRIME:
+ dsa->q = bn;
+ break;
+ case TAG_DSA_BASE:
+ dsa->g = bn;
+ break;
+ case TAG_DSA_PRIVATE:
+ dsa->priv_key = bn;
+ break;
+ case TAG_DSA_PUBLIC:
+ dsa->pub_key = bn;
+ break;
+ }
+ }
+ dst_s_free_private_structure_fields(&priv, mctx);
+
+ key->key_size = BN_num_bits(dsa->p);
+ isc_buffer_init(&dns, dns_array, sizeof(dns_array),
+ ISC_BUFFERTYPE_BINARY);
+ ret = dst_openssl_to_dns(key, &dns);
+ if (ret != ISC_R_SUCCESS)
+ DST_RET(ret);
+ isc_buffer_used(&dns, &r);
+ key->key_id = dst_s_id_calc(r.base, r.length);
+
+ if (key->key_id != id)
+ DST_RET(DST_R_INVALIDPRIVATEKEY);
+
+ return (ISC_R_SUCCESS);
+
+ err:
+ key->opaque = NULL;
+ dst_openssl_destroy(dsa, mctx);
+ dst_s_free_private_structure_fields(&priv, mctx);
+ memset(&priv, 0, sizeof(priv));
+ return (ret);
+}
+
+/*
+ * dst_openssl_destroy
+ * Frees all dynamically allocated structures in key.
+ */
+static void
+dst_openssl_destroy(void *key, isc_mem_t *mctx) {
+ DSA *dsa = (DSA *) key;
+ if (dsa == NULL)
+ return;
+
+ mctx = mctx; /* make the compiler happy */
+
+ DSA_free(dsa);
+}
+
+
+/*
+ * dst_openssl_generate
+ * Generates unique keys that are hard to predict.
+ * Parameters
+ * key DST Key structure
+ * unused algorithm specific data, unused for DSA.
+ * mctx memory context to allocate key
+ * Return
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+
+static dst_result_t
+dst_openssl_generate(dst_key_t *key, int unused, isc_mem_t *mctx) {
+ DSA *dsa;
+ unsigned char dns_array[1024];
+ unsigned char rand_array[SHA_DIGEST_LENGTH];
+ isc_buffer_t dns, rand;
+ dst_result_t ret;
+ isc_region_t r;
+
+ unused = unused; /* make the compiler happy */
+ mctx = mctx; /* make the compiler happy */
+
+ isc_buffer_init(&rand, rand_array, sizeof(rand_array),
+ ISC_BUFFERTYPE_BINARY);
+ ret = dst_random_get(SHA_DIGEST_LENGTH, &rand);
+ if (ret != ISC_R_SUCCESS)
+ return (ret);
+
+ dsa = DSA_generate_parameters(key->key_size, rand_array,
+ SHA_DIGEST_LENGTH, NULL, NULL,
+ NULL, NULL);
+
+ if (dsa == NULL)
+ return (ISC_R_NOMEMORY);
+
+ if (DSA_generate_key(dsa) == 0)
+ return (ISC_R_NOMEMORY);
+
+ key->opaque = dsa;
+
+ isc_buffer_init(&dns, dns_array, sizeof(dns_array),
+ ISC_BUFFERTYPE_BINARY);
+ dst_openssl_to_dns(key, &dns);
+ isc_buffer_used(&dns, &r);
+ key->key_id = dst_s_id_calc(r.base, r.length);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+/**************************************************************************
+ * dst_openssl_compare
+ * Compare two keys for equality.
+ * Return
+ * ISC_TRUE The keys are equal
+ * ISC_FALSE The keys are not equal
+ */
+static isc_boolean_t
+dst_openssl_compare(const dst_key_t *key1, const dst_key_t *key2) {
+ int status;
+ DSA *dsa1, *dsa2;
+
+ dsa1 = (DSA *) key1->opaque;
+ dsa2 = (DSA *) key2->opaque;
+
+ if (dsa1 == NULL && dsa2 == NULL)
+ return (ISC_TRUE);
+ else if (dsa1 == NULL || dsa2 == NULL)
+ return (ISC_FALSE);
+
+ status = BN_cmp(dsa1->p, dsa2->p) ||
+ BN_cmp(dsa1->q, dsa2->q) ||
+ BN_cmp(dsa1->g, dsa2->g) ||
+ BN_cmp(dsa1->pub_key, dsa2->pub_key);
+
+ if (status != 0)
+ return (ISC_FALSE);
+
+ if (dsa1->priv_key != NULL || dsa2->priv_key != NULL) {
+ if (dsa1->priv_key == NULL || dsa2->priv_key == NULL)
+ return (ISC_FALSE);
+ if (BN_cmp(dsa1->priv_key, dsa2->priv_key))
+ return (ISC_FALSE);
+ }
+ return (ISC_TRUE);
+}
+
+static int
+BN_bn2bin_fixed(BIGNUM *bn, unsigned char *buf, int size) {
+ int bytes = size - BN_num_bytes(bn);
+ while (bytes-- > 0)
+ *buf++ = 0;
+ BN_bn2bin(bn, buf);
+ return (size);
+}
+
+#endif
diff --git a/lib/dns/sec/dst/openssldh_link.c b/lib/dns/sec/dst/openssldh_link.c
new file mode 100644
index 00000000..37bebfcd
--- /dev/null
+++ b/lib/dns/sec/dst/openssldh_link.c
@@ -0,0 +1,694 @@
+#if defined(OPENSSL)
+
+/*
+ * Portions Copyright (c) 1995-1998 by Network Associates, Inc.
+ *
+ * Permission to use, copy modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND NETWORK ASSOCIATES
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * NETWORK ASSOCIATES BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THE SOFTWARE.
+ */
+
+/*
+ * Principal Author: Brian Wellington
+ * $Id: openssldh_link.c,v 1.6 1999/10/29 12:56:57 marka Exp $
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+#include <ctype.h>
+
+#include <isc/assertions.h>
+#include <isc/buffer.h>
+#include <isc/error.h>
+#include <isc/int.h>
+#include <isc/region.h>
+
+#include "dst_internal.h"
+#include "dst_parse.h"
+
+#include <openssl/crypto.h>
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+
+#define PRIME768 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF"
+
+#define PRIME1024 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF"
+
+static struct dst_func openssldh_functions;
+
+static dst_result_t dst_openssldh_computesecret(const dst_key_t *pub,
+ const dst_key_t *priv,
+ isc_buffer_t *secret);
+static isc_boolean_t dst_openssldh_compare(const dst_key_t *key1,
+ const dst_key_t *key2);
+static isc_boolean_t dst_openssldh_paramcompare(const dst_key_t *key1,
+ const dst_key_t *key2);
+static dst_result_t dst_openssldh_generate(dst_key_t *key, int generator,
+ isc_mem_t *mctx);
+static isc_boolean_t dst_openssldh_isprivate(const dst_key_t *key);
+static void dst_openssldh_destroy(void *key, isc_mem_t *mctx);
+static dst_result_t dst_openssldh_to_dns(const dst_key_t *in_key,
+ isc_buffer_t *data);
+static dst_result_t dst_openssldh_from_dns(dst_key_t *key,
+ isc_buffer_t *data,
+ isc_mem_t *mctx);
+static dst_result_t dst_openssldh_to_file(const dst_key_t *key);
+static dst_result_t dst_openssldh_from_file(dst_key_t *key,
+ const isc_uint16_t id,
+ isc_mem_t *mctx);
+
+static void uint16_toregion(isc_uint16_t val, isc_region_t *region);
+static isc_uint16_t uint16_fromregion(isc_region_t *region);
+static void BN_fromhex(BIGNUM *b, const char *str);
+
+static BIGNUM bn2, bn768, bn1024;
+
+/*
+ * dst_s_openssldh_init()
+ * Sets up function pointers for OpenSSL related functions
+ */
+void
+dst_s_openssldh_init()
+{
+ REQUIRE(dst_t_func[DST_ALG_DH] == NULL);
+ dst_t_func[DST_ALG_DH] = &openssldh_functions;
+ memset(&openssldh_functions, 0, sizeof(struct dst_func));
+ openssldh_functions.sign = NULL;
+ openssldh_functions.verify = NULL;
+ openssldh_functions.computesecret = dst_openssldh_computesecret;
+ openssldh_functions.compare = dst_openssldh_compare;
+ openssldh_functions.paramcompare = dst_openssldh_paramcompare;
+ openssldh_functions.generate = dst_openssldh_generate;
+ openssldh_functions.isprivate = dst_openssldh_isprivate;
+ openssldh_functions.destroy = dst_openssldh_destroy;
+ openssldh_functions.to_dns = dst_openssldh_to_dns;
+ openssldh_functions.from_dns = dst_openssldh_from_dns;
+ openssldh_functions.to_file = dst_openssldh_to_file;
+ openssldh_functions.from_file = dst_openssldh_from_file;
+ CRYPTO_set_mem_functions(dst_mem_alloc, dst_mem_realloc, dst_mem_free);
+
+ BN_init(&bn2);
+ BN_init(&bn768);
+ BN_init(&bn1024);
+ BN_set_word(&bn2, 2);
+ BN_fromhex(&bn768, PRIME768);
+ BN_fromhex(&bn1024, PRIME1024);
+}
+
+/*
+ * dst_openssldh_computesecret
+ * Compute a shared secret from this public and private key
+ * Parameters
+ * pub The public key
+ * priv The private key
+ * secret A buffer into which the secret is written
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+static dst_result_t
+dst_openssldh_computesecret(const dst_key_t *pub, const dst_key_t *priv,
+ isc_buffer_t *secret)
+{
+ DH *dhpub, *dhpriv;
+ int ret;
+ isc_region_t r;
+ unsigned int len;
+
+ REQUIRE(pub->opaque != NULL);
+ REQUIRE(priv->opaque != NULL);
+
+ dhpub = (DH *) pub->opaque;
+ dhpriv = (DH *) priv->opaque;
+
+ len = DH_size(dhpriv);
+ isc_buffer_available(secret, &r);
+ if (r.length < len)
+ return (ISC_R_NOSPACE);
+ ret = DH_compute_key(r.base, dhpub->pub_key, dhpriv);
+ if (ret == 0)
+ return (DST_R_COMPUTESECRETFAILURE);
+ isc_buffer_add(secret, len);
+ return (ISC_R_SUCCESS);
+}
+
+/*
+ * dst_openssldh_isprivate
+ * Is this a private key?
+ * Parameters
+ * key DST KEY structure
+ * Returns
+ * ISC_TRUE
+ * ISC_FALSE
+ */
+static isc_boolean_t
+dst_openssldh_isprivate(const dst_key_t *key) {
+ DH *dh = (DH *) key->opaque;
+ return (ISC_TF(dh != NULL && dh->priv_key != NULL));
+}
+
+
+/*
+ * dst_openssldh_to_dns
+ * Converts key from DH to DNS distribution format
+ * Parameters
+ * key DST KEY structure
+ * data output data
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+
+static dst_result_t
+dst_openssldh_to_dns(const dst_key_t *key, isc_buffer_t *data) {
+ DH *dh;
+ isc_region_t r;
+ isc_uint16_t dnslen, plen, glen, publen;
+
+ REQUIRE(key->opaque != NULL);
+
+ dh = (DH *) key->opaque;
+
+ isc_buffer_available(data, &r);
+
+ if (dh->g == &bn2 && (dh->p == &bn768 || dh->p == &bn1024)) {
+ plen = 1;
+ glen = 0;
+ }
+ else {
+ plen = BN_num_bytes(dh->p);
+ glen = BN_num_bytes(dh->g);
+ }
+ publen = BN_num_bytes(dh->pub_key);
+ dnslen = plen + glen + publen + 6;
+ if (r.length < (unsigned int) dnslen)
+ return (ISC_R_NOSPACE);
+
+ uint16_toregion(plen, &r);
+ if (plen == 1) {
+ if (dh->p == &bn768)
+ *r.base = 1;
+ else
+ *r.base = 2;
+ }
+ else
+ BN_bn2bin(dh->p, r.base);
+ r.base += plen;
+
+ uint16_toregion(glen, &r);
+ if (glen > 0)
+ BN_bn2bin(dh->g, r.base);
+ r.base += glen;
+
+ uint16_toregion(publen, &r);
+ BN_bn2bin(dh->pub_key, r.base);
+ r.base += publen;
+
+ isc_buffer_add(data, dnslen);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+/*
+ * dst_openssldh_from_dns
+ * Converts from a DNS KEY RR format to a DH KEY.
+ * Parameters
+ * key Partially filled key structure
+ * data Buffer containing key in DNS format
+ * Return
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+static dst_result_t
+dst_openssldh_from_dns(dst_key_t *key, isc_buffer_t *data, isc_mem_t *mctx) {
+ DH *dh;
+ isc_region_t r;
+ isc_uint16_t plen, glen, publen;
+ int special = 0;
+
+ mctx = mctx; /* make the compiler happy */
+
+ isc_buffer_remaining(data, &r);
+ if (r.length == 0)
+ return (ISC_R_SUCCESS);
+
+ dh = DH_new();
+ if (dh == NULL)
+ return (ISC_R_NOMEMORY);
+
+ memset(dh, 0, sizeof(DH));
+
+ /*
+ * Read the prime length. 1 & 2 are table entries, > 16 means a
+ * prime follows, otherwise an error.
+ */
+ if (r.length < 2) {
+ DH_free(dh);
+ return (DST_R_INVALIDPUBLICKEY);
+ }
+ plen = uint16_fromregion(&r);
+ if (plen < 16 && plen != 1 && plen != 2) {
+ DH_free(dh);
+ return (DST_R_INVALIDPUBLICKEY);
+ }
+ if (r.length < plen) {
+ DH_free(dh);
+ return (DST_R_INVALIDPUBLICKEY);
+ }
+ if (plen == 1 || plen == 2) {
+ if (plen == 1)
+ special = *r.base++;
+ else
+ special = uint16_fromregion(&r);
+ switch (special) {
+ case 1:
+ dh->p = &bn768;
+ break;
+ case 2:
+ dh->p = &bn1024;
+ break;
+ default:
+ DH_free(dh);
+ return (DST_R_INVALIDPUBLICKEY);
+ }
+ }
+ else {
+ dh->p = BN_bin2bn(r.base, plen, NULL);
+ r.base += plen;
+ }
+
+ /*
+ * Read the generator length. This should be 0 if the prime was
+ * special, but it might not be. If it's 0 and the prime is not
+ * special, we have a problem.
+ */
+ if (r.length < 2) {
+ DH_free(dh);
+ return (DST_R_INVALIDPUBLICKEY);
+ }
+ glen = uint16_fromregion(&r);
+ if (r.length < glen) {
+ DH_free(dh);
+ return (DST_R_INVALIDPUBLICKEY);
+ }
+ if (special != 0) {
+ if (glen == 0)
+ dh->g = &bn2;
+ else {
+ dh->g = BN_bin2bn(r.base, glen, NULL);
+ if (BN_cmp(dh->g, &bn2) == 0) {
+ BN_free(dh->g);
+ dh->g = &bn2;
+ }
+ else {
+ DH_free(dh);
+ return (DST_R_INVALIDPUBLICKEY);
+ }
+ }
+ }
+ else {
+ if (glen == 0) {
+ DH_free(dh);
+ return (DST_R_INVALIDPUBLICKEY);
+ }
+ dh->g = BN_bin2bn(r.base, glen, NULL);
+ }
+ r.base += glen;
+
+ if (r.length < 2) {
+ DH_free(dh);
+ return (DST_R_INVALIDPUBLICKEY);
+ }
+ publen = uint16_fromregion(&r);
+ if (r.length < publen) {
+ DH_free(dh);
+ return (DST_R_INVALIDPUBLICKEY);
+ }
+ dh->pub_key = BN_bin2bn(r.base, publen, NULL);
+ r.base += publen;
+
+ isc_buffer_remaining(data, &r);
+ key->key_id = dst_s_id_calc(r.base, plen + glen + publen + 6);
+ key->key_size = BN_num_bits(dh->p);
+
+ isc_buffer_forward(data, plen + glen + publen + 6);
+
+ key->opaque = (void *) dh;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+/*
+ * dst_openssldh_to_file
+ * Encodes a DH Key into the portable file format.
+ * Parameters
+ * key DST KEY structure
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+static dst_result_t
+dst_openssldh_to_file(const dst_key_t *key) {
+ int cnt = 0;
+ DH *dh;
+ dst_private_t priv;
+ unsigned char bufs[4][128];
+
+ if (key->opaque == NULL)
+ return (DST_R_NULLKEY);
+
+ dh = (DH *) key->opaque;
+
+ priv.elements[cnt].tag = TAG_DH_PRIME;
+ priv.elements[cnt].length = BN_num_bytes(dh->p);
+ BN_bn2bin(dh->p, bufs[cnt]);
+ priv.elements[cnt].data = bufs[cnt];
+ cnt++;
+
+ priv.elements[cnt].tag = TAG_DH_GENERATOR;
+ priv.elements[cnt].length = BN_num_bytes(dh->g);
+ BN_bn2bin(dh->g, bufs[cnt]);
+ priv.elements[cnt].data = bufs[cnt];
+ cnt++;
+
+ priv.elements[cnt].tag = TAG_DH_PRIVATE;
+ priv.elements[cnt].length = BN_num_bytes(dh->priv_key);
+ BN_bn2bin(dh->priv_key, bufs[cnt]);
+ priv.elements[cnt].data = bufs[cnt];
+ cnt++;
+
+ priv.elements[cnt].tag = TAG_DH_PUBLIC;
+ priv.elements[cnt].length = BN_num_bytes(dh->pub_key);
+ BN_bn2bin(dh->pub_key, bufs[cnt]);
+ priv.elements[cnt].data = bufs[cnt];
+ cnt++;
+
+ priv.nelements = cnt;
+ return (dst_s_write_private_key_file(key->key_name, key->key_alg,
+ key->key_id, &priv));
+}
+
+
+/*
+ * dst_openssldh_from_file
+ * Converts contents of a private key file into a private DH key.
+ * Parameters
+ * key Partially filled DH KEY structure
+ * id The key id
+ * path The directory that the file will be read from
+ * Return
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+
+static dst_result_t
+dst_openssldh_from_file(dst_key_t *key, const isc_uint16_t id, isc_mem_t *mctx) {
+ dst_private_t priv;
+ dst_result_t ret;
+ isc_buffer_t dns;
+ isc_region_t r;
+ unsigned char dns_array[1024];
+ int i;
+ DH *dh = NULL;
+#define DST_RET(a) {ret = a; goto err;}
+
+ /* read private key file */
+ ret = dst_s_parse_private_key_file(key->key_name, key->key_alg,
+ id, &priv, mctx);
+ if (ret != ISC_R_SUCCESS)
+ return (ret);
+
+ dh = DH_new();
+ if (dh == NULL)
+ DST_RET(ISC_R_NOMEMORY);
+ memset(dh, 0, sizeof(DH));
+ key->opaque = dh;
+
+ for (i=0; i < priv.nelements; i++) {
+ BIGNUM *bn;
+ bn = BN_bin2bn(priv.elements[i].data,
+ priv.elements[i].length, NULL);
+ if (bn == NULL)
+ DST_RET(ISC_R_NOMEMORY);
+
+ switch (priv.elements[i].tag) {
+ case TAG_DH_PRIME:
+ dh->p = bn;
+ break;
+ case TAG_DH_GENERATOR:
+ dh->g = bn;
+ break;
+ case TAG_DH_PRIVATE:
+ dh->priv_key = bn;
+ break;
+ case TAG_DH_PUBLIC:
+ dh->pub_key = bn;
+ break;
+ }
+ }
+ dst_s_free_private_structure_fields(&priv, mctx);
+
+ key->key_size = BN_num_bits(dh->p);
+
+ if ((key->key_size == 768 || key->key_size == 1024) &&
+ BN_cmp(dh->g, &bn2) == 0)
+ {
+ if (key->key_size == 768 && BN_cmp(dh->p, &bn768) == 0) {
+ BN_free(dh->p);
+ BN_free(dh->g);
+ dh->p = &bn768;
+ dh->g = &bn2;
+ }
+ else if (key->key_size == 1024 && BN_cmp(dh->p, &bn1024) == 0) {
+ BN_free(dh->p);
+ BN_free(dh->g);
+ dh->p = &bn1024;
+ dh->g = &bn2;
+ }
+ }
+ isc_buffer_init(&dns, dns_array, sizeof(dns_array),
+ ISC_BUFFERTYPE_BINARY);
+ ret = dst_openssldh_to_dns(key, &dns);
+ if (ret != ISC_R_SUCCESS)
+ DST_RET(ret);
+ isc_buffer_used(&dns, &r);
+ key->key_id = dst_s_id_calc(r.base, r.length);
+
+ if (key->key_id != id)
+ DST_RET(DST_R_INVALIDPRIVATEKEY);
+
+ return (ISC_R_SUCCESS);
+
+ err:
+ key->opaque = NULL;
+ dst_openssldh_destroy(dh, mctx);
+ dst_s_free_private_structure_fields(&priv, mctx);
+ memset(&priv, 0, sizeof(priv));
+ return (ret);
+}
+
+/*
+ * dst_openssldh_destroy
+ * Frees all dynamically allocated structures in key.
+ */
+static void
+dst_openssldh_destroy(void *key, isc_mem_t *mctx) {
+ DH *dh = (DH *) key;
+ if (dh == NULL)
+ return;
+
+ mctx = mctx; /* make the compiler happy */
+
+ if (dh->p == &bn768 || dh->p == &bn1024)
+ dh->p = NULL;
+ if (dh->g == &bn2)
+ dh->g = NULL;
+ DH_free(dh);
+}
+
+
+/*
+ * dst_openssldh_generate
+ * Generates unique keys that are hard to predict.
+ * Parameters
+ * key DST Key structure
+ * generator generator
+ * mctx memory context to allocate key
+ * Return
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+
+static dst_result_t
+dst_openssldh_generate(dst_key_t *key, int generator, isc_mem_t *mctx) {
+ DH *dh = NULL;
+ unsigned char dns_array[1024];
+ isc_buffer_t dns;
+ isc_region_t r;
+
+ mctx = mctx; /* make the compiler happy */
+
+ if (generator == 0) {
+ if (key->key_size == 768 || key->key_size == 1024) {
+ dh = DH_new();
+ if (dh == NULL)
+ return (ISC_R_NOMEMORY);
+ if (key->key_size == 768)
+ dh->p = &bn768;
+ else
+ dh->p = &bn1024;
+ dh->g = &bn2;
+ }
+ else
+ generator = 2;
+ }
+
+ if (generator != 0)
+ dh = DH_generate_parameters(key->key_size, generator,
+ NULL, NULL);
+
+ if (dh == NULL)
+ return (DST_R_INVALIDPARAM);
+
+ if (DH_generate_key(dh) == 0) {
+ DH_free(dh);
+ return (ISC_R_NOMEMORY);
+ }
+
+ key->opaque = dh;
+
+ isc_buffer_init(&dns, dns_array, sizeof(dns_array),
+ ISC_BUFFERTYPE_BINARY);
+ dst_openssldh_to_dns(key, &dns);
+ isc_buffer_used(&dns, &r);
+ key->key_id = dst_s_id_calc(r.base, r.length);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+/**************************************************************************
+ * dst_openssldh_compare
+ * Compare two keys for equality.
+ * Return
+ * ISC_TRUE The keys are equal
+ * ISC_FALSE The keys are not equal
+ */
+static isc_boolean_t
+dst_openssldh_compare(const dst_key_t *key1, const dst_key_t *key2) {
+ int status;
+ DH *dh1, *dh2;
+
+ dh1 = (DH *) key1->opaque;
+ dh2 = (DH *) key2->opaque;
+
+ if (dh1 == NULL && dh2 == NULL)
+ return (ISC_TRUE);
+ else if (dh1 == NULL || dh2 == NULL)
+ return (ISC_FALSE);
+
+ status = BN_cmp(dh1->p, dh2->p) ||
+ BN_cmp(dh1->g, dh2->g) ||
+ BN_cmp(dh1->pub_key, dh2->pub_key);
+
+ if (status != 0)
+ return (ISC_FALSE);
+
+ if (dh1->priv_key != NULL || dh2->priv_key != NULL) {
+ if (dh1->priv_key == NULL || dh2->priv_key == NULL)
+ return (ISC_FALSE);
+ if (BN_cmp(dh1->priv_key, dh2->priv_key) != 0)
+ return (ISC_FALSE);
+ }
+ return (ISC_TRUE);
+}
+
+/**************************************************************************
+ * dst_openssldh_paramcompare
+ * Compare two keys' parameters for equality.
+ * Return
+ * ISC_TRUE The keys are equal
+ * ISC_FALSE The keys are not equal
+ */
+static isc_boolean_t
+dst_openssldh_paramcompare(const dst_key_t *key1, const dst_key_t *key2) {
+ int status;
+ DH *dh1, *dh2;
+
+ dh1 = (DH *) key1->opaque;
+ dh2 = (DH *) key2->opaque;
+
+ if (dh1 == NULL && dh2 == NULL)
+ return (ISC_TRUE);
+ else if (dh1 == NULL || dh2 == NULL)
+ return (ISC_FALSE);
+
+ status = BN_cmp(dh1->p, dh2->p) ||
+ BN_cmp(dh1->g, dh2->g);
+
+ if (status != 0)
+ return (ISC_FALSE);
+ return (ISC_TRUE);
+}
+
+static void
+uint16_toregion(isc_uint16_t val, isc_region_t *region) {
+ *region->base++ = (val & 0xff00) >> 8;
+ *region->base++ = (val & 0x00ff);
+}
+
+static isc_uint16_t
+uint16_fromregion(isc_region_t *region) {
+ isc_uint16_t val;
+ unsigned char *cp = region->base;
+
+ val = ((unsigned int)(cp[0])) << 8;
+ val |= ((unsigned int)(cp[1]));
+
+ region->base += 2;
+ return (val);
+}
+
+static void
+BN_fromhex(BIGNUM *b, const char *str) {
+ static const char hexdigits[] = "0123456789abcdef";
+ unsigned char data[512];
+ unsigned int i;
+ BIGNUM *out;
+
+ RUNTIME_CHECK(strlen(str) < 1024 && strlen(str) % 2 == 0);
+ for (i = 0; i < strlen(str); i += 2) {
+ char *s;
+ unsigned int high, low;
+
+ s = strchr(hexdigits, tolower(str[i]));
+ RUNTIME_CHECK(s != NULL);
+ high = s - hexdigits;
+
+ s = strchr(hexdigits, tolower(str[i + 1]));
+ RUNTIME_CHECK(s != NULL);
+ low = s - hexdigits;
+
+ data[i/2] = (unsigned char)((high << 4) + low);
+ }
+ out = BN_bin2bn(data, strlen(str)/2, b);
+ RUNTIME_CHECK(out != NULL);
+}
+
+#endif
diff --git a/lib/dns/sec/dst/opensslmd5_link.c b/lib/dns/sec/dst/opensslmd5_link.c
new file mode 100644
index 00000000..86493409
--- /dev/null
+++ b/lib/dns/sec/dst/opensslmd5_link.c
@@ -0,0 +1,102 @@
+#if defined(OPENSSL)
+
+/*
+ * Portions Copyright (c) 1995-1998 by Network Associates, Inc.
+ *
+ * Permission to use, copy modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND NETWORK ASSOCIATES
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * NETWORK ASSOCIATES BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THE SOFTWARE.
+ */
+
+/*
+ * Principal Author: Brian Wellington
+ * $Id: opensslmd5_link.c,v 1.2 1999/10/20 22:14:15 bwelling Exp $
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+
+#include <isc/assertions.h>
+#include <isc/buffer.h>
+#include <isc/int.h>
+#include <isc/region.h>
+
+#include "dst_internal.h"
+#include "dst_parse.h"
+
+#include <openssl/crypto.h>
+#include <openssl/bn.h>
+#include <openssl/md5.h>
+
+#define MD5Init MD5_Init
+#define MD5Update MD5_Update
+#define MD5Final MD5_Final
+
+/*
+ * dst_s_md5
+ * Call MD5 functions to digest a block of data.
+ * There are three steps to signing, INIT (initialize structures),
+ * UPDATE (hash (more) data), FINAL (generate a digest). This
+ * routine performs one or more of these steps.
+ * Parameters
+ * mode DST_SIGMODE_{INIT_UPDATE_FINAL|ALL}
+ * context the context to use for this computation
+ * data data to be signed
+ * digest buffer to store digest
+ * mctx memory context for temporary allocations
+ * Returns
+ * ISC_R_SUCCESS Success
+ * !ISC_R_SUCCESS Failure
+ */
+dst_result_t
+dst_s_md5(const unsigned int mode, void **context, isc_region_t *data,
+ isc_buffer_t *digest, isc_mem_t *mctx)
+{
+ isc_region_t r;
+ MD5_CTX *ctx = NULL;
+
+ if (mode & DST_SIGMODE_INIT) {
+ ctx = (MD5_CTX *) isc_mem_get(mctx, sizeof(MD5_CTX));
+ if (ctx == NULL)
+ return (ISC_R_NOMEMORY);
+ }
+ else if (context != NULL)
+ ctx = (MD5_CTX *) *context;
+ REQUIRE (ctx != NULL);
+
+ if (mode & DST_SIGMODE_INIT)
+ MD5Init(ctx);
+
+ if (mode & DST_SIGMODE_UPDATE)
+ MD5Update(ctx, data->base, data->length);
+
+ if (mode & DST_SIGMODE_FINAL) {
+ isc_buffer_available(digest, &r);
+ if (r.length < MD5_DIGEST_LENGTH)
+ return (ISC_R_NOSPACE);
+
+ MD5Final(r.base, ctx);
+ isc_buffer_add(digest, MD5_DIGEST_LENGTH);
+ isc_mem_put(mctx, ctx, sizeof(MD5_CTX));
+ }
+ else
+ *context = ctx;
+
+ return (ISC_R_SUCCESS);
+}
+
+#endif
diff --git a/lib/dns/sec/openssl/.cvsignore b/lib/dns/sec/openssl/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/lib/dns/sec/openssl/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/lib/dns/sec/openssl/Makefile.in b/lib/dns/sec/openssl/Makefile.in
new file mode 100644
index 00000000..8a77c44c
--- /dev/null
+++ b/lib/dns/sec/openssl/Makefile.in
@@ -0,0 +1,55 @@
+# Copyright (C) 1998, 1999, 2000 Internet Software Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+# CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+# SOFTWARE.
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+CINCLUDES = -I${srcdir}/include
+
+CDEFINES = -DMFUNC
+CWARNINGS =
+
+LIBS = @LIBS@
+
+# Alphabetically
+OBJS = bn_add.@O@ bn_asm.@O@ bn_comba.@O@ bn_div.@O@ \
+ bn_err.@O@ bn_exp.@O@ bn_exp2.@O@ bn_gcd.@O@ \
+ bn_lib.@O@ bn_mont.@O@ bn_mul.@O@ \
+ bn_prime.@O@ bn_print.@O@ bn_rand.@O@ bn_recp.@O@ \
+ bn_shift.@O@ bn_sqr.@O@ bn_word.@O@ buffer.@O@ \
+ cryptlib.@O@ dh_err.@O@ dh_gen.@O@ dh_key.@O@ \
+ dh_lib.@O@ dsa_asn1.@O@ dsa_err.@O@ dsa_gen.@O@ \
+ dsa_key.@O@ dsa_lib.@O@ dsa_sign.@O@ dsa_vrf.@O@ \
+ err.@O@ lhash.@O@ md_rand.@O@ md5_dgst.@O@ mem.@O@ \
+ rand_lib.@O@ sha1_one.@O@ sha1dgst.@O@ stack.@O@ \
+ th-lock.@O@
+
+SRCS = bn_add.c bn_asm.c bn_comba.c bn_div.c \
+ bn_err.c bn_exp.c bn_exp2.c bn_gcd.c \
+ bn_lib.c bn_mont.c bn_mul.c \
+ bn_prime.c bn_print.c bn_rand.c bn_recp.c \
+ bn_shift.c bn_sqr.c bn_word.c buffer.c \
+ cryptlib.c dh_err.c dh_gen.c dh_key.c dh_lib.c \
+ dsa_asn1.c dsa_err.c dsa_gen.c \
+ dsa_key.c dsa_lib.c dsa_sign.c dsa_vrf.c \
+ err.c lhash.c md_rand.c md5_dgst.c mem.c \
+ rand_lib.c sha1_one.c sha1dgst.c stack.c \
+ th-lock.c
+
+SUBDIRS = include
+TARGETS = ${OBJS}
+
+@BIND9_MAKE_RULES@
diff --git a/lib/dns/sec/openssl/bn_add.c b/lib/dns/sec/openssl/bn_add.c
new file mode 100644
index 00000000..c5ab066c
--- /dev/null
+++ b/lib/dns/sec/openssl/bn_add.c
@@ -0,0 +1,307 @@
+/* crypto/bn/bn_add.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/* r can == a or b */
+int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b)
+ {
+ BIGNUM *tmp;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ /* a + b a+b
+ * a + -b a-b
+ * -a + b b-a
+ * -a + -b -(a+b)
+ */
+ if (a->neg ^ b->neg)
+ {
+ /* only one is negative */
+ if (a->neg)
+ { tmp=a; a=b; b=tmp; }
+
+ /* we are now a - b */
+
+ if (BN_ucmp(a,b) < 0)
+ {
+ if (!BN_usub(r,b,a)) return(0);
+ r->neg=1;
+ }
+ else
+ {
+ if (!BN_usub(r,a,b)) return(0);
+ r->neg=0;
+ }
+ return(1);
+ }
+
+ if (a->neg) /* both are neg */
+ r->neg=1;
+ else
+ r->neg=0;
+
+ if (!BN_uadd(r,a,b)) return(0);
+ return(1);
+ }
+
+/* unsigned add of b to a, r must be large enough */
+int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+ {
+ register int i;
+ int max,min;
+ BN_ULONG *ap,*bp,*rp,carry,t1;
+ const BIGNUM *tmp;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ if (a->top < b->top)
+ { tmp=a; a=b; b=tmp; }
+ max=a->top;
+ min=b->top;
+
+ if (bn_wexpand(r,max+1) == NULL)
+ return(0);
+
+ r->top=max;
+
+
+ ap=a->d;
+ bp=b->d;
+ rp=r->d;
+ carry=0;
+
+ carry=bn_add_words(rp,ap,bp,min);
+ rp+=min;
+ ap+=min;
+ bp+=min;
+ i=min;
+
+ if (carry)
+ {
+ while (i < max)
+ {
+ i++;
+ t1= *(ap++);
+ if ((*(rp++)=(t1+1)&BN_MASK2) >= t1)
+ {
+ carry=0;
+ break;
+ }
+ }
+ if ((i >= max) && carry)
+ {
+ *(rp++)=1;
+ r->top++;
+ }
+ }
+ if (rp != ap)
+ {
+ for (; i<max; i++)
+ *(rp++)= *(ap++);
+ }
+ /* memcpy(rp,ap,sizeof(*ap)*(max-i));*/
+ return(1);
+ }
+
+/* unsigned subtraction of b from a, a must be larger than b. */
+int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+ {
+ int max,min;
+ register BN_ULONG t1,t2,*ap,*bp,*rp;
+ int i,carry;
+#if defined(IRIX_CC_BUG) && !defined(LINT)
+ int dummy;
+#endif
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ if (a->top < b->top) /* hmm... should not be happening */
+ {
+ BNerr(BN_F_BN_USUB,BN_R_ARG2_LT_ARG3);
+ return(0);
+ }
+
+ max=a->top;
+ min=b->top;
+ if (bn_wexpand(r,max) == NULL) return(0);
+
+ ap=a->d;
+ bp=b->d;
+ rp=r->d;
+
+#if 1
+ carry=0;
+ for (i=0; i<min; i++)
+ {
+ t1= *(ap++);
+ t2= *(bp++);
+ if (carry)
+ {
+ carry=(t1 <= t2);
+ t1=(t1-t2-1)&BN_MASK2;
+ }
+ else
+ {
+ carry=(t1 < t2);
+ t1=(t1-t2)&BN_MASK2;
+ }
+#if defined(IRIX_CC_BUG) && !defined(LINT)
+ dummy=t1;
+#endif
+ *(rp++)=t1&BN_MASK2;
+ }
+#else
+ carry=bn_sub_words(rp,ap,bp,min);
+ ap+=min;
+ bp+=min;
+ rp+=min;
+ i=min;
+#endif
+ if (carry) /* subtracted */
+ {
+ while (i < max)
+ {
+ i++;
+ t1= *(ap++);
+ t2=(t1-1)&BN_MASK2;
+ *(rp++)=t2;
+ if (t1 > t2) break;
+ }
+ }
+#if 0
+ memcpy(rp,ap,sizeof(*rp)*(max-i));
+#else
+ if (rp != ap)
+ {
+ for (;;)
+ {
+ if (i++ >= max) break;
+ rp[0]=ap[0];
+ if (i++ >= max) break;
+ rp[1]=ap[1];
+ if (i++ >= max) break;
+ rp[2]=ap[2];
+ if (i++ >= max) break;
+ rp[3]=ap[3];
+ rp+=4;
+ ap+=4;
+ }
+ }
+#endif
+
+ r->top=max;
+ bn_fix_top(r);
+ return(1);
+ }
+
+int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+ {
+ int max;
+ int add=0,neg=0;
+ const BIGNUM *tmp;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ /* a - b a-b
+ * a - -b a+b
+ * -a - b -(a+b)
+ * -a - -b b-a
+ */
+ if (a->neg)
+ {
+ if (b->neg)
+ { tmp=a; a=b; b=tmp; }
+ else
+ { add=1; neg=1; }
+ }
+ else
+ {
+ if (b->neg) { add=1; neg=0; }
+ }
+
+ if (add)
+ {
+ if (!BN_uadd(r,a,b)) return(0);
+ r->neg=neg;
+ return(1);
+ }
+
+ /* We are actually doing a - b :-) */
+
+ max=(a->top > b->top)?a->top:b->top;
+ if (bn_wexpand(r,max) == NULL) return(0);
+ if (BN_ucmp(a,b) < 0)
+ {
+ if (!BN_usub(r,b,a)) return(0);
+ r->neg=1;
+ }
+ else
+ {
+ if (!BN_usub(r,a,b)) return(0);
+ r->neg=0;
+ }
+ return(1);
+ }
+
diff --git a/lib/dns/sec/openssl/bn_asm.c b/lib/dns/sec/openssl/bn_asm.c
new file mode 100644
index 00000000..4d3da16a
--- /dev/null
+++ b/lib/dns/sec/openssl/bn_asm.c
@@ -0,0 +1,802 @@
+/* crypto/bn/bn_asm.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+#ifdef BN_LLONG
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+ {
+ BN_ULONG c1=0;
+
+ bn_check_num(num);
+ if (num <= 0) return(c1);
+
+ for (;;)
+ {
+ mul_add(rp[0],ap[0],w,c1);
+ if (--num == 0) break;
+ mul_add(rp[1],ap[1],w,c1);
+ if (--num == 0) break;
+ mul_add(rp[2],ap[2],w,c1);
+ if (--num == 0) break;
+ mul_add(rp[3],ap[3],w,c1);
+ if (--num == 0) break;
+ ap+=4;
+ rp+=4;
+ }
+
+ return(c1);
+ }
+
+BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+ {
+ BN_ULONG c1=0;
+
+ bn_check_num(num);
+ if (num <= 0) return(c1);
+
+ /* for (;;) */
+ while (1) /* circumvent egcs-1.1.2 bug */
+ {
+ mul(rp[0],ap[0],w,c1);
+ if (--num == 0) break;
+ mul(rp[1],ap[1],w,c1);
+ if (--num == 0) break;
+ mul(rp[2],ap[2],w,c1);
+ if (--num == 0) break;
+ mul(rp[3],ap[3],w,c1);
+ if (--num == 0) break;
+ ap+=4;
+ rp+=4;
+ }
+ return(c1);
+ }
+
+void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n)
+ {
+ bn_check_num(n);
+ if (n <= 0) return;
+ for (;;)
+ {
+ BN_ULLONG t;
+
+ t=(BN_ULLONG)(a[0])*(a[0]);
+ r[0]=Lw(t); r[1]=Hw(t);
+ if (--n == 0) break;
+
+ t=(BN_ULLONG)(a[1])*(a[1]);
+ r[2]=Lw(t); r[3]=Hw(t);
+ if (--n == 0) break;
+
+ t=(BN_ULLONG)(a[2])*(a[2]);
+ r[4]=Lw(t); r[5]=Hw(t);
+ if (--n == 0) break;
+
+ t=(BN_ULLONG)(a[3])*(a[3]);
+ r[6]=Lw(t); r[7]=Hw(t);
+ if (--n == 0) break;
+
+ a+=4;
+ r+=8;
+ }
+ }
+
+#else
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+ {
+ BN_ULONG c=0;
+ BN_ULONG bl,bh;
+
+ bn_check_num(num);
+ if (num <= 0) return((BN_ULONG)0);
+
+ bl=LBITS(w);
+ bh=HBITS(w);
+
+ for (;;)
+ {
+ mul_add(rp[0],ap[0],bl,bh,c);
+ if (--num == 0) break;
+ mul_add(rp[1],ap[1],bl,bh,c);
+ if (--num == 0) break;
+ mul_add(rp[2],ap[2],bl,bh,c);
+ if (--num == 0) break;
+ mul_add(rp[3],ap[3],bl,bh,c);
+ if (--num == 0) break;
+ ap+=4;
+ rp+=4;
+ }
+ return(c);
+ }
+
+BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+ {
+ BN_ULONG carry=0;
+ BN_ULONG bl,bh;
+
+ bn_check_num(num);
+ if (num <= 0) return((BN_ULONG)0);
+
+ bl=LBITS(w);
+ bh=HBITS(w);
+
+ for (;;)
+ {
+ mul(rp[0],ap[0],bl,bh,carry);
+ if (--num == 0) break;
+ mul(rp[1],ap[1],bl,bh,carry);
+ if (--num == 0) break;
+ mul(rp[2],ap[2],bl,bh,carry);
+ if (--num == 0) break;
+ mul(rp[3],ap[3],bl,bh,carry);
+ if (--num == 0) break;
+ ap+=4;
+ rp+=4;
+ }
+ return(carry);
+ }
+
+void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n)
+ {
+ bn_check_num(n);
+ if (n <= 0) return;
+ for (;;)
+ {
+ sqr64(r[0],r[1],a[0]);
+ if (--n == 0) break;
+
+ sqr64(r[2],r[3],a[1]);
+ if (--n == 0) break;
+
+ sqr64(r[4],r[5],a[2]);
+ if (--n == 0) break;
+
+ sqr64(r[6],r[7],a[3]);
+ if (--n == 0) break;
+
+ a+=4;
+ r+=8;
+ }
+ }
+
+#endif
+
+#if defined(BN_LLONG) && defined(BN_DIV2W)
+
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
+ {
+ return((BN_ULONG)(((((BN_ULLONG)h)<<BN_BITS2)|l)/(BN_ULLONG)d));
+ }
+
+#else
+
+/* Divide h-l by d and return the result. */
+/* I need to test this some more :-( */
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
+ {
+ BN_ULONG dh,dl,q,ret=0,th,tl,t;
+ int i,count=2;
+
+ if (d == 0) return(BN_MASK2);
+
+ i=BN_num_bits_word(d);
+ if ((i != BN_BITS2) && (h > (BN_ULONG)1<<i))
+ {
+#if !defined(NO_STDIO) && !defined(WIN16)
+ fprintf(stderr,"Division would overflow (%d)\n",i);
+#endif
+ abort();
+ }
+ i=BN_BITS2-i;
+ if (h >= d) h-=d;
+
+ if (i)
+ {
+ d<<=i;
+ h=(h<<i)|(l>>(BN_BITS2-i));
+ l<<=i;
+ }
+ dh=(d&BN_MASK2h)>>BN_BITS4;
+ dl=(d&BN_MASK2l);
+ for (;;)
+ {
+ if ((h>>BN_BITS4) == dh)
+ q=BN_MASK2l;
+ else
+ q=h/dh;
+
+ th=q*dh;
+ tl=dl*q;
+ for (;;)
+ {
+ t=h-th;
+ if ((t&BN_MASK2h) ||
+ ((tl) <= (
+ (t<<BN_BITS4)|
+ ((l&BN_MASK2h)>>BN_BITS4))))
+ break;
+ q--;
+ th-=dh;
+ tl-=dl;
+ }
+ t=(tl>>BN_BITS4);
+ tl=(tl<<BN_BITS4)&BN_MASK2h;
+ th+=t;
+
+ if (l < tl) th++;
+ l-=tl;
+ if (h < th)
+ {
+ h+=d;
+ q--;
+ }
+ h-=th;
+
+ if (--count == 0) break;
+
+ ret=q<<BN_BITS4;
+ h=((h<<BN_BITS4)|(l>>BN_BITS4))&BN_MASK2;
+ l=(l&BN_MASK2l)<<BN_BITS4;
+ }
+ ret|=q;
+ return(ret);
+ }
+#endif
+
+#ifdef BN_LLONG
+BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+ {
+ BN_ULLONG ll=0;
+
+ bn_check_num(n);
+ if (n <= 0) return((BN_ULONG)0);
+
+ for (;;)
+ {
+ ll+=(BN_ULLONG)a[0]+b[0];
+ r[0]=(BN_ULONG)ll&BN_MASK2;
+ ll>>=BN_BITS2;
+ if (--n <= 0) break;
+
+ ll+=(BN_ULLONG)a[1]+b[1];
+ r[1]=(BN_ULONG)ll&BN_MASK2;
+ ll>>=BN_BITS2;
+ if (--n <= 0) break;
+
+ ll+=(BN_ULLONG)a[2]+b[2];
+ r[2]=(BN_ULONG)ll&BN_MASK2;
+ ll>>=BN_BITS2;
+ if (--n <= 0) break;
+
+ ll+=(BN_ULLONG)a[3]+b[3];
+ r[3]=(BN_ULONG)ll&BN_MASK2;
+ ll>>=BN_BITS2;
+ if (--n <= 0) break;
+
+ a+=4;
+ b+=4;
+ r+=4;
+ }
+ return((BN_ULONG)ll);
+ }
+#else
+BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+ {
+ BN_ULONG c,l,t;
+
+ bn_check_num(n);
+ if (n <= 0) return((BN_ULONG)0);
+
+ c=0;
+ for (;;)
+ {
+ t=a[0];
+ t=(t+c)&BN_MASK2;
+ c=(t < c);
+ l=(t+b[0])&BN_MASK2;
+ c+=(l < t);
+ r[0]=l;
+ if (--n <= 0) break;
+
+ t=a[1];
+ t=(t+c)&BN_MASK2;
+ c=(t < c);
+ l=(t+b[1])&BN_MASK2;
+ c+=(l < t);
+ r[1]=l;
+ if (--n <= 0) break;
+
+ t=a[2];
+ t=(t+c)&BN_MASK2;
+ c=(t < c);
+ l=(t+b[2])&BN_MASK2;
+ c+=(l < t);
+ r[2]=l;
+ if (--n <= 0) break;
+
+ t=a[3];
+ t=(t+c)&BN_MASK2;
+ c=(t < c);
+ l=(t+b[3])&BN_MASK2;
+ c+=(l < t);
+ r[3]=l;
+ if (--n <= 0) break;
+
+ a+=4;
+ b+=4;
+ r+=4;
+ }
+ return((BN_ULONG)c);
+ }
+#endif
+
+BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+ {
+ BN_ULONG t1,t2;
+ int c=0;
+
+ bn_check_num(n);
+ if (n <= 0) return((BN_ULONG)0);
+
+ for (;;)
+ {
+ t1=a[0]; t2=b[0];
+ r[0]=(t1-t2-c)&BN_MASK2;
+ if (t1 != t2) c=(t1 < t2);
+ if (--n <= 0) break;
+
+ t1=a[1]; t2=b[1];
+ r[1]=(t1-t2-c)&BN_MASK2;
+ if (t1 != t2) c=(t1 < t2);
+ if (--n <= 0) break;
+
+ t1=a[2]; t2=b[2];
+ r[2]=(t1-t2-c)&BN_MASK2;
+ if (t1 != t2) c=(t1 < t2);
+ if (--n <= 0) break;
+
+ t1=a[3]; t2=b[3];
+ r[3]=(t1-t2-c)&BN_MASK2;
+ if (t1 != t2) c=(t1 < t2);
+ if (--n <= 0) break;
+
+ a+=4;
+ b+=4;
+ r+=4;
+ }
+ return(c);
+ }
+
+#ifdef BN_MUL_COMBA
+
+#undef bn_mul_comba8
+#undef bn_mul_comba4
+#undef bn_sqr_comba8
+#undef bn_sqr_comba4
+
+#ifdef BN_LLONG
+#define mul_add_c(a,b,c0,c1,c2) \
+ t=(BN_ULLONG)a*b; \
+ t1=(BN_ULONG)Lw(t); \
+ t2=(BN_ULONG)Hw(t); \
+ c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
+ c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define mul_add_c2(a,b,c0,c1,c2) \
+ t=(BN_ULLONG)a*b; \
+ tt=(t+t)&BN_MASK; \
+ if (tt < t) c2++; \
+ t1=(BN_ULONG)Lw(tt); \
+ t2=(BN_ULONG)Hw(tt); \
+ c0=(c0+t1)&BN_MASK2; \
+ if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \
+ c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define sqr_add_c(a,i,c0,c1,c2) \
+ t=(BN_ULLONG)a[i]*a[i]; \
+ t1=(BN_ULONG)Lw(t); \
+ t2=(BN_ULONG)Hw(t); \
+ c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
+ c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define sqr_add_c2(a,i,j,c0,c1,c2) \
+ mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+#else
+#define mul_add_c(a,b,c0,c1,c2) \
+ t1=LBITS(a); t2=HBITS(a); \
+ bl=LBITS(b); bh=HBITS(b); \
+ mul64(t1,t2,bl,bh); \
+ c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
+ c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define mul_add_c2(a,b,c0,c1,c2) \
+ t1=LBITS(a); t2=HBITS(a); \
+ bl=LBITS(b); bh=HBITS(b); \
+ mul64(t1,t2,bl,bh); \
+ if (t2 & BN_TBIT) c2++; \
+ t2=(t2+t2)&BN_MASK2; \
+ if (t1 & BN_TBIT) t2++; \
+ t1=(t1+t1)&BN_MASK2; \
+ c0=(c0+t1)&BN_MASK2; \
+ if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \
+ c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define sqr_add_c(a,i,c0,c1,c2) \
+ sqr64(t1,t2,(a)[i]); \
+ c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
+ c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define sqr_add_c2(a,i,j,c0,c1,c2) \
+ mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+#endif
+
+void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+ {
+#ifdef BN_LLONG
+ BN_ULLONG t;
+#else
+ BN_ULONG bl,bh;
+#endif
+ BN_ULONG t1,t2;
+ BN_ULONG c1,c2,c3;
+
+ c1=0;
+ c2=0;
+ c3=0;
+ mul_add_c(a[0],b[0],c1,c2,c3);
+ r[0]=c1;
+ c1=0;
+ mul_add_c(a[0],b[1],c2,c3,c1);
+ mul_add_c(a[1],b[0],c2,c3,c1);
+ r[1]=c2;
+ c2=0;
+ mul_add_c(a[2],b[0],c3,c1,c2);
+ mul_add_c(a[1],b[1],c3,c1,c2);
+ mul_add_c(a[0],b[2],c3,c1,c2);
+ r[2]=c3;
+ c3=0;
+ mul_add_c(a[0],b[3],c1,c2,c3);
+ mul_add_c(a[1],b[2],c1,c2,c3);
+ mul_add_c(a[2],b[1],c1,c2,c3);
+ mul_add_c(a[3],b[0],c1,c2,c3);
+ r[3]=c1;
+ c1=0;
+ mul_add_c(a[4],b[0],c2,c3,c1);
+ mul_add_c(a[3],b[1],c2,c3,c1);
+ mul_add_c(a[2],b[2],c2,c3,c1);
+ mul_add_c(a[1],b[3],c2,c3,c1);
+ mul_add_c(a[0],b[4],c2,c3,c1);
+ r[4]=c2;
+ c2=0;
+ mul_add_c(a[0],b[5],c3,c1,c2);
+ mul_add_c(a[1],b[4],c3,c1,c2);
+ mul_add_c(a[2],b[3],c3,c1,c2);
+ mul_add_c(a[3],b[2],c3,c1,c2);
+ mul_add_c(a[4],b[1],c3,c1,c2);
+ mul_add_c(a[5],b[0],c3,c1,c2);
+ r[5]=c3;
+ c3=0;
+ mul_add_c(a[6],b[0],c1,c2,c3);
+ mul_add_c(a[5],b[1],c1,c2,c3);
+ mul_add_c(a[4],b[2],c1,c2,c3);
+ mul_add_c(a[3],b[3],c1,c2,c3);
+ mul_add_c(a[2],b[4],c1,c2,c3);
+ mul_add_c(a[1],b[5],c1,c2,c3);
+ mul_add_c(a[0],b[6],c1,c2,c3);
+ r[6]=c1;
+ c1=0;
+ mul_add_c(a[0],b[7],c2,c3,c1);
+ mul_add_c(a[1],b[6],c2,c3,c1);
+ mul_add_c(a[2],b[5],c2,c3,c1);
+ mul_add_c(a[3],b[4],c2,c3,c1);
+ mul_add_c(a[4],b[3],c2,c3,c1);
+ mul_add_c(a[5],b[2],c2,c3,c1);
+ mul_add_c(a[6],b[1],c2,c3,c1);
+ mul_add_c(a[7],b[0],c2,c3,c1);
+ r[7]=c2;
+ c2=0;
+ mul_add_c(a[7],b[1],c3,c1,c2);
+ mul_add_c(a[6],b[2],c3,c1,c2);
+ mul_add_c(a[5],b[3],c3,c1,c2);
+ mul_add_c(a[4],b[4],c3,c1,c2);
+ mul_add_c(a[3],b[5],c3,c1,c2);
+ mul_add_c(a[2],b[6],c3,c1,c2);
+ mul_add_c(a[1],b[7],c3,c1,c2);
+ r[8]=c3;
+ c3=0;
+ mul_add_c(a[2],b[7],c1,c2,c3);
+ mul_add_c(a[3],b[6],c1,c2,c3);
+ mul_add_c(a[4],b[5],c1,c2,c3);
+ mul_add_c(a[5],b[4],c1,c2,c3);
+ mul_add_c(a[6],b[3],c1,c2,c3);
+ mul_add_c(a[7],b[2],c1,c2,c3);
+ r[9]=c1;
+ c1=0;
+ mul_add_c(a[7],b[3],c2,c3,c1);
+ mul_add_c(a[6],b[4],c2,c3,c1);
+ mul_add_c(a[5],b[5],c2,c3,c1);
+ mul_add_c(a[4],b[6],c2,c3,c1);
+ mul_add_c(a[3],b[7],c2,c3,c1);
+ r[10]=c2;
+ c2=0;
+ mul_add_c(a[4],b[7],c3,c1,c2);
+ mul_add_c(a[5],b[6],c3,c1,c2);
+ mul_add_c(a[6],b[5],c3,c1,c2);
+ mul_add_c(a[7],b[4],c3,c1,c2);
+ r[11]=c3;
+ c3=0;
+ mul_add_c(a[7],b[5],c1,c2,c3);
+ mul_add_c(a[6],b[6],c1,c2,c3);
+ mul_add_c(a[5],b[7],c1,c2,c3);
+ r[12]=c1;
+ c1=0;
+ mul_add_c(a[6],b[7],c2,c3,c1);
+ mul_add_c(a[7],b[6],c2,c3,c1);
+ r[13]=c2;
+ c2=0;
+ mul_add_c(a[7],b[7],c3,c1,c2);
+ r[14]=c3;
+ r[15]=c1;
+ }
+
+void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+ {
+#ifdef BN_LLONG
+ BN_ULLONG t;
+#else
+ BN_ULONG bl,bh;
+#endif
+ BN_ULONG t1,t2;
+ BN_ULONG c1,c2,c3;
+
+ c1=0;
+ c2=0;
+ c3=0;
+ mul_add_c(a[0],b[0],c1,c2,c3);
+ r[0]=c1;
+ c1=0;
+ mul_add_c(a[0],b[1],c2,c3,c1);
+ mul_add_c(a[1],b[0],c2,c3,c1);
+ r[1]=c2;
+ c2=0;
+ mul_add_c(a[2],b[0],c3,c1,c2);
+ mul_add_c(a[1],b[1],c3,c1,c2);
+ mul_add_c(a[0],b[2],c3,c1,c2);
+ r[2]=c3;
+ c3=0;
+ mul_add_c(a[0],b[3],c1,c2,c3);
+ mul_add_c(a[1],b[2],c1,c2,c3);
+ mul_add_c(a[2],b[1],c1,c2,c3);
+ mul_add_c(a[3],b[0],c1,c2,c3);
+ r[3]=c1;
+ c1=0;
+ mul_add_c(a[3],b[1],c2,c3,c1);
+ mul_add_c(a[2],b[2],c2,c3,c1);
+ mul_add_c(a[1],b[3],c2,c3,c1);
+ r[4]=c2;
+ c2=0;
+ mul_add_c(a[2],b[3],c3,c1,c2);
+ mul_add_c(a[3],b[2],c3,c1,c2);
+ r[5]=c3;
+ c3=0;
+ mul_add_c(a[3],b[3],c1,c2,c3);
+ r[6]=c1;
+ r[7]=c2;
+ }
+
+void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
+ {
+#ifdef BN_LLONG
+ BN_ULLONG t,tt;
+#else
+ BN_ULONG bl,bh;
+#endif
+ BN_ULONG t1,t2;
+ BN_ULONG c1,c2,c3;
+
+ c1=0;
+ c2=0;
+ c3=0;
+ sqr_add_c(a,0,c1,c2,c3);
+ r[0]=c1;
+ c1=0;
+ sqr_add_c2(a,1,0,c2,c3,c1);
+ r[1]=c2;
+ c2=0;
+ sqr_add_c(a,1,c3,c1,c2);
+ sqr_add_c2(a,2,0,c3,c1,c2);
+ r[2]=c3;
+ c3=0;
+ sqr_add_c2(a,3,0,c1,c2,c3);
+ sqr_add_c2(a,2,1,c1,c2,c3);
+ r[3]=c1;
+ c1=0;
+ sqr_add_c(a,2,c2,c3,c1);
+ sqr_add_c2(a,3,1,c2,c3,c1);
+ sqr_add_c2(a,4,0,c2,c3,c1);
+ r[4]=c2;
+ c2=0;
+ sqr_add_c2(a,5,0,c3,c1,c2);
+ sqr_add_c2(a,4,1,c3,c1,c2);
+ sqr_add_c2(a,3,2,c3,c1,c2);
+ r[5]=c3;
+ c3=0;
+ sqr_add_c(a,3,c1,c2,c3);
+ sqr_add_c2(a,4,2,c1,c2,c3);
+ sqr_add_c2(a,5,1,c1,c2,c3);
+ sqr_add_c2(a,6,0,c1,c2,c3);
+ r[6]=c1;
+ c1=0;
+ sqr_add_c2(a,7,0,c2,c3,c1);
+ sqr_add_c2(a,6,1,c2,c3,c1);
+ sqr_add_c2(a,5,2,c2,c3,c1);
+ sqr_add_c2(a,4,3,c2,c3,c1);
+ r[7]=c2;
+ c2=0;
+ sqr_add_c(a,4,c3,c1,c2);
+ sqr_add_c2(a,5,3,c3,c1,c2);
+ sqr_add_c2(a,6,2,c3,c1,c2);
+ sqr_add_c2(a,7,1,c3,c1,c2);
+ r[8]=c3;
+ c3=0;
+ sqr_add_c2(a,7,2,c1,c2,c3);
+ sqr_add_c2(a,6,3,c1,c2,c3);
+ sqr_add_c2(a,5,4,c1,c2,c3);
+ r[9]=c1;
+ c1=0;
+ sqr_add_c(a,5,c2,c3,c1);
+ sqr_add_c2(a,6,4,c2,c3,c1);
+ sqr_add_c2(a,7,3,c2,c3,c1);
+ r[10]=c2;
+ c2=0;
+ sqr_add_c2(a,7,4,c3,c1,c2);
+ sqr_add_c2(a,6,5,c3,c1,c2);
+ r[11]=c3;
+ c3=0;
+ sqr_add_c(a,6,c1,c2,c3);
+ sqr_add_c2(a,7,5,c1,c2,c3);
+ r[12]=c1;
+ c1=0;
+ sqr_add_c2(a,7,6,c2,c3,c1);
+ r[13]=c2;
+ c2=0;
+ sqr_add_c(a,7,c3,c1,c2);
+ r[14]=c3;
+ r[15]=c1;
+ }
+
+void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
+ {
+#ifdef BN_LLONG
+ BN_ULLONG t,tt;
+#else
+ BN_ULONG bl,bh;
+#endif
+ BN_ULONG t1,t2;
+ BN_ULONG c1,c2,c3;
+
+ c1=0;
+ c2=0;
+ c3=0;
+ sqr_add_c(a,0,c1,c2,c3);
+ r[0]=c1;
+ c1=0;
+ sqr_add_c2(a,1,0,c2,c3,c1);
+ r[1]=c2;
+ c2=0;
+ sqr_add_c(a,1,c3,c1,c2);
+ sqr_add_c2(a,2,0,c3,c1,c2);
+ r[2]=c3;
+ c3=0;
+ sqr_add_c2(a,3,0,c1,c2,c3);
+ sqr_add_c2(a,2,1,c1,c2,c3);
+ r[3]=c1;
+ c1=0;
+ sqr_add_c(a,2,c2,c3,c1);
+ sqr_add_c2(a,3,1,c2,c3,c1);
+ r[4]=c2;
+ c2=0;
+ sqr_add_c2(a,3,2,c3,c1,c2);
+ r[5]=c3;
+ c3=0;
+ sqr_add_c(a,3,c1,c2,c3);
+ r[6]=c1;
+ r[7]=c2;
+ }
+#else
+
+/* hmm... is it faster just to do a multiply? */
+#undef bn_sqr_comba4
+void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
+ {
+ BN_ULONG t[8];
+ bn_sqr_normal(r,a,4,t);
+ }
+
+#undef bn_sqr_comba8
+void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
+ {
+ BN_ULONG t[16];
+ bn_sqr_normal(r,a,8,t);
+ }
+
+void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+ {
+ r[4]=bn_mul_words( &(r[0]),a,4,b[0]);
+ r[5]=bn_mul_add_words(&(r[1]),a,4,b[1]);
+ r[6]=bn_mul_add_words(&(r[2]),a,4,b[2]);
+ r[7]=bn_mul_add_words(&(r[3]),a,4,b[3]);
+ }
+
+void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+ {
+ r[ 8]=bn_mul_words( &(r[0]),a,8,b[0]);
+ r[ 9]=bn_mul_add_words(&(r[1]),a,8,b[1]);
+ r[10]=bn_mul_add_words(&(r[2]),a,8,b[2]);
+ r[11]=bn_mul_add_words(&(r[3]),a,8,b[3]);
+ r[12]=bn_mul_add_words(&(r[4]),a,8,b[4]);
+ r[13]=bn_mul_add_words(&(r[5]),a,8,b[5]);
+ r[14]=bn_mul_add_words(&(r[6]),a,8,b[6]);
+ r[15]=bn_mul_add_words(&(r[7]),a,8,b[7]);
+ }
+
+#endif /* BN_COMBA */
diff --git a/lib/dns/sec/openssl/bn_comba.c b/lib/dns/sec/openssl/bn_comba.c
new file mode 100644
index 00000000..7ad09b4a
--- /dev/null
+++ b/lib/dns/sec/openssl/bn_comba.c
@@ -0,0 +1,345 @@
+/* crypto/bn/bn_comba.c */
+#include <stdio.h>
+#include "bn_lcl.h"
+/* Auto generated from crypto/bn/comba.pl
+ */
+
+#undef bn_mul_comba8
+#undef bn_mul_comba4
+#undef bn_sqr_comba8
+#undef bn_sqr_comba4
+
+#ifdef BN_LLONG
+#define mul_add_c(a,b,c0,c1,c2) \
+ t=(BN_ULLONG)a*b; \
+ t1=(BN_ULONG)Lw(t); \
+ t2=(BN_ULONG)Hw(t); \
+ c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
+ c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define mul_add_c2(a,b,c0,c1,c2) \
+ t=(BN_ULLONG)a*b; \
+ tt=(t+t)&BN_MASK; \
+ if (tt < t) c2++; \
+ t1=(BN_ULONG)Lw(tt); \
+ t2=(BN_ULONG)Hw(tt); \
+ c0=(c0+t1)&BN_MASK2; \
+ if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \
+ c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define sqr_add_c(a,i,c0,c1,c2) \
+ t=(BN_ULLONG)a[i]*a[i]; \
+ t1=(BN_ULONG)Lw(t); \
+ t2=(BN_ULONG)Hw(t); \
+ c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
+ c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define sqr_add_c2(a,i,j,c0,c1,c2) \
+ mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+#else
+#define mul_add_c(a,b,c0,c1,c2) \
+ t1=LBITS(a); t2=HBITS(a); \
+ bl=LBITS(b); bh=HBITS(b); \
+ mul64(t1,t2,bl,bh); \
+ c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
+ c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define mul_add_c2(a,b,c0,c1,c2) \
+ t1=LBITS(a); t2=HBITS(a); \
+ bl=LBITS(b); bh=HBITS(b); \
+ mul64(t1,t2,bl,bh); \
+ if (t2 & BN_TBIT) c2++; \
+ t2=(t2+t2)&BN_MASK2; \
+ if (t1 & BN_TBIT) t2++; \
+ t1=(t1+t1)&BN_MASK2; \
+ c0=(c0+t1)&BN_MASK2; \
+ if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \
+ c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define sqr_add_c(a,i,c0,c1,c2) \
+ sqr64(t1,t2,(a)[i]); \
+ c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
+ c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+#define sqr_add_c2(a,i,j,c0,c1,c2) \
+ mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+#endif
+
+void bn_mul_comba88(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
+void bn_mul_comba44(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
+void bn_sqr_comba88(BN_ULONG *r,BN_ULONG *a);
+void bn_sqr_comba44(BN_ULONG *r,BN_ULONG *a);
+
+void bn_mul_comba88(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+ {
+#ifdef BN_LLONG
+ BN_ULLONG t;
+#else
+ BN_ULONG bl,bh;
+#endif
+ BN_ULONG t1,t2;
+ BN_ULONG c1,c2,c3;
+
+ c1=0;
+ c2=0;
+ c3=0;
+ mul_add_c(a[0],b[0],c1,c2,c3);
+ r[0]=c1;
+ c1=0;
+ mul_add_c(a[0],b[1],c2,c3,c1);
+ mul_add_c(a[1],b[0],c2,c3,c1);
+ r[1]=c2;
+ c2=0;
+ mul_add_c(a[2],b[0],c3,c1,c2);
+ mul_add_c(a[1],b[1],c3,c1,c2);
+ mul_add_c(a[0],b[2],c3,c1,c2);
+ r[2]=c3;
+ c3=0;
+ mul_add_c(a[0],b[3],c1,c2,c3);
+ mul_add_c(a[1],b[2],c1,c2,c3);
+ mul_add_c(a[2],b[1],c1,c2,c3);
+ mul_add_c(a[3],b[0],c1,c2,c3);
+ r[3]=c1;
+ c1=0;
+ mul_add_c(a[4],b[0],c2,c3,c1);
+ mul_add_c(a[3],b[1],c2,c3,c1);
+ mul_add_c(a[2],b[2],c2,c3,c1);
+ mul_add_c(a[1],b[3],c2,c3,c1);
+ mul_add_c(a[0],b[4],c2,c3,c1);
+ r[4]=c2;
+ c2=0;
+ mul_add_c(a[0],b[5],c3,c1,c2);
+ mul_add_c(a[1],b[4],c3,c1,c2);
+ mul_add_c(a[2],b[3],c3,c1,c2);
+ mul_add_c(a[3],b[2],c3,c1,c2);
+ mul_add_c(a[4],b[1],c3,c1,c2);
+ mul_add_c(a[5],b[0],c3,c1,c2);
+ r[5]=c3;
+ c3=0;
+ mul_add_c(a[6],b[0],c1,c2,c3);
+ mul_add_c(a[5],b[1],c1,c2,c3);
+ mul_add_c(a[4],b[2],c1,c2,c3);
+ mul_add_c(a[3],b[3],c1,c2,c3);
+ mul_add_c(a[2],b[4],c1,c2,c3);
+ mul_add_c(a[1],b[5],c1,c2,c3);
+ mul_add_c(a[0],b[6],c1,c2,c3);
+ r[6]=c1;
+ c1=0;
+ mul_add_c(a[0],b[7],c2,c3,c1);
+ mul_add_c(a[1],b[6],c2,c3,c1);
+ mul_add_c(a[2],b[5],c2,c3,c1);
+ mul_add_c(a[3],b[4],c2,c3,c1);
+ mul_add_c(a[4],b[3],c2,c3,c1);
+ mul_add_c(a[5],b[2],c2,c3,c1);
+ mul_add_c(a[6],b[1],c2,c3,c1);
+ mul_add_c(a[7],b[0],c2,c3,c1);
+ r[7]=c2;
+ c2=0;
+ mul_add_c(a[7],b[1],c3,c1,c2);
+ mul_add_c(a[6],b[2],c3,c1,c2);
+ mul_add_c(a[5],b[3],c3,c1,c2);
+ mul_add_c(a[4],b[4],c3,c1,c2);
+ mul_add_c(a[3],b[5],c3,c1,c2);
+ mul_add_c(a[2],b[6],c3,c1,c2);
+ mul_add_c(a[1],b[7],c3,c1,c2);
+ r[8]=c3;
+ c3=0;
+ mul_add_c(a[2],b[7],c1,c2,c3);
+ mul_add_c(a[3],b[6],c1,c2,c3);
+ mul_add_c(a[4],b[5],c1,c2,c3);
+ mul_add_c(a[5],b[4],c1,c2,c3);
+ mul_add_c(a[6],b[3],c1,c2,c3);
+ mul_add_c(a[7],b[2],c1,c2,c3);
+ r[9]=c1;
+ c1=0;
+ mul_add_c(a[7],b[3],c2,c3,c1);
+ mul_add_c(a[6],b[4],c2,c3,c1);
+ mul_add_c(a[5],b[5],c2,c3,c1);
+ mul_add_c(a[4],b[6],c2,c3,c1);
+ mul_add_c(a[3],b[7],c2,c3,c1);
+ r[10]=c2;
+ c2=0;
+ mul_add_c(a[4],b[7],c3,c1,c2);
+ mul_add_c(a[5],b[6],c3,c1,c2);
+ mul_add_c(a[6],b[5],c3,c1,c2);
+ mul_add_c(a[7],b[4],c3,c1,c2);
+ r[11]=c3;
+ c3=0;
+ mul_add_c(a[7],b[5],c1,c2,c3);
+ mul_add_c(a[6],b[6],c1,c2,c3);
+ mul_add_c(a[5],b[7],c1,c2,c3);
+ r[12]=c1;
+ c1=0;
+ mul_add_c(a[6],b[7],c2,c3,c1);
+ mul_add_c(a[7],b[6],c2,c3,c1);
+ r[13]=c2;
+ c2=0;
+ mul_add_c(a[7],b[7],c3,c1,c2);
+ r[14]=c3;
+ r[15]=c1;
+ }
+
+void bn_mul_comba44(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+ {
+#ifdef BN_LLONG
+ BN_ULLONG t;
+#else
+ BN_ULONG bl,bh;
+#endif
+ BN_ULONG t1,t2;
+ BN_ULONG c1,c2,c3;
+
+ c1=0;
+ c2=0;
+ c3=0;
+ mul_add_c(a[0],b[0],c1,c2,c3);
+ r[0]=c1;
+ c1=0;
+ mul_add_c(a[0],b[1],c2,c3,c1);
+ mul_add_c(a[1],b[0],c2,c3,c1);
+ r[1]=c2;
+ c2=0;
+ mul_add_c(a[2],b[0],c3,c1,c2);
+ mul_add_c(a[1],b[1],c3,c1,c2);
+ mul_add_c(a[0],b[2],c3,c1,c2);
+ r[2]=c3;
+ c3=0;
+ mul_add_c(a[0],b[3],c1,c2,c3);
+ mul_add_c(a[1],b[2],c1,c2,c3);
+ mul_add_c(a[2],b[1],c1,c2,c3);
+ mul_add_c(a[3],b[0],c1,c2,c3);
+ r[3]=c1;
+ c1=0;
+ mul_add_c(a[3],b[1],c2,c3,c1);
+ mul_add_c(a[2],b[2],c2,c3,c1);
+ mul_add_c(a[1],b[3],c2,c3,c1);
+ r[4]=c2;
+ c2=0;
+ mul_add_c(a[2],b[3],c3,c1,c2);
+ mul_add_c(a[3],b[2],c3,c1,c2);
+ r[5]=c3;
+ c3=0;
+ mul_add_c(a[3],b[3],c1,c2,c3);
+ r[6]=c1;
+ r[7]=c2;
+ }
+
+void bn_sqr_comba88(BN_ULONG *r, BN_ULONG *a)
+ {
+#ifdef BN_LLONG
+ BN_ULLONG t,tt;
+#else
+ BN_ULONG bl,bh;
+#endif
+ BN_ULONG t1,t2;
+ BN_ULONG c1,c2,c3;
+
+ c1=0;
+ c2=0;
+ c3=0;
+ sqr_add_c(a,0,c1,c2,c3);
+ r[0]=c1;
+ c1=0;
+ sqr_add_c2(a,1,0,c2,c3,c1);
+ r[1]=c2;
+ c2=0;
+ sqr_add_c(a,1,c3,c1,c2);
+ sqr_add_c2(a,2,0,c3,c1,c2);
+ r[2]=c3;
+ c3=0;
+ sqr_add_c2(a,3,0,c1,c2,c3);
+ sqr_add_c2(a,2,1,c1,c2,c3);
+ r[3]=c1;
+ c1=0;
+ sqr_add_c(a,2,c2,c3,c1);
+ sqr_add_c2(a,3,1,c2,c3,c1);
+ sqr_add_c2(a,4,0,c2,c3,c1);
+ r[4]=c2;
+ c2=0;
+ sqr_add_c2(a,5,0,c3,c1,c2);
+ sqr_add_c2(a,4,1,c3,c1,c2);
+ sqr_add_c2(a,3,2,c3,c1,c2);
+ r[5]=c3;
+ c3=0;
+ sqr_add_c(a,3,c1,c2,c3);
+ sqr_add_c2(a,4,2,c1,c2,c3);
+ sqr_add_c2(a,5,1,c1,c2,c3);
+ sqr_add_c2(a,6,0,c1,c2,c3);
+ r[6]=c1;
+ c1=0;
+ sqr_add_c2(a,7,0,c2,c3,c1);
+ sqr_add_c2(a,6,1,c2,c3,c1);
+ sqr_add_c2(a,5,2,c2,c3,c1);
+ sqr_add_c2(a,4,3,c2,c3,c1);
+ r[7]=c2;
+ c2=0;
+ sqr_add_c(a,4,c3,c1,c2);
+ sqr_add_c2(a,5,3,c3,c1,c2);
+ sqr_add_c2(a,6,2,c3,c1,c2);
+ sqr_add_c2(a,7,1,c3,c1,c2);
+ r[8]=c3;
+ c3=0;
+ sqr_add_c2(a,7,2,c1,c2,c3);
+ sqr_add_c2(a,6,3,c1,c2,c3);
+ sqr_add_c2(a,5,4,c1,c2,c3);
+ r[9]=c1;
+ c1=0;
+ sqr_add_c(a,5,c2,c3,c1);
+ sqr_add_c2(a,6,4,c2,c3,c1);
+ sqr_add_c2(a,7,3,c2,c3,c1);
+ r[10]=c2;
+ c2=0;
+ sqr_add_c2(a,7,4,c3,c1,c2);
+ sqr_add_c2(a,6,5,c3,c1,c2);
+ r[11]=c3;
+ c3=0;
+ sqr_add_c(a,6,c1,c2,c3);
+ sqr_add_c2(a,7,5,c1,c2,c3);
+ r[12]=c1;
+ c1=0;
+ sqr_add_c2(a,7,6,c2,c3,c1);
+ r[13]=c2;
+ c2=0;
+ sqr_add_c(a,7,c3,c1,c2);
+ r[14]=c3;
+ r[15]=c1;
+ }
+
+void bn_sqr_comba44(BN_ULONG *r, BN_ULONG *a)
+ {
+#ifdef BN_LLONG
+ BN_ULLONG t,tt;
+#else
+ BN_ULONG bl,bh;
+#endif
+ BN_ULONG t1,t2;
+ BN_ULONG c1,c2,c3;
+
+ c1=0;
+ c2=0;
+ c3=0;
+ sqr_add_c(a,0,c1,c2,c3);
+ r[0]=c1;
+ c1=0;
+ sqr_add_c2(a,1,0,c2,c3,c1);
+ r[1]=c2;
+ c2=0;
+ sqr_add_c(a,1,c3,c1,c2);
+ sqr_add_c2(a,2,0,c3,c1,c2);
+ r[2]=c3;
+ c3=0;
+ sqr_add_c2(a,3,0,c1,c2,c3);
+ sqr_add_c2(a,2,1,c1,c2,c3);
+ r[3]=c1;
+ c1=0;
+ sqr_add_c(a,2,c2,c3,c1);
+ sqr_add_c2(a,3,1,c2,c3,c1);
+ r[4]=c2;
+ c2=0;
+ sqr_add_c2(a,3,2,c3,c1,c2);
+ r[5]=c3;
+ c3=0;
+ sqr_add_c(a,3,c1,c2,c3);
+ r[6]=c1;
+ r[7]=c2;
+ }
diff --git a/lib/dns/sec/openssl/bn_div.c b/lib/dns/sec/openssl/bn_div.c
new file mode 100644
index 00000000..150dd289
--- /dev/null
+++ b/lib/dns/sec/openssl/bn_div.c
@@ -0,0 +1,358 @@
+/* crypto/bn/bn_div.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/bn.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/* The old slow way */
+#if 0
+int BN_div(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, BIGNUM *d, BN_CTX *ctx)
+ {
+ int i,nm,nd;
+ BIGNUM *D;
+
+ bn_check_top(m);
+ bn_check_top(d);
+ if (BN_is_zero(d))
+ {
+ BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO);
+ return(0);
+ }
+
+ if (BN_ucmp(m,d) < 0)
+ {
+ if (rem != NULL)
+ { if (BN_copy(rem,m) == NULL) return(0); }
+ if (dv != NULL) BN_zero(dv);
+ return(1);
+ }
+
+ D= &(ctx->bn[ctx->tos]);
+ if (dv == NULL) dv= &(ctx->bn[ctx->tos+1]);
+ if (rem == NULL) rem= &(ctx->bn[ctx->tos+2]);
+
+ nd=BN_num_bits(d);
+ nm=BN_num_bits(m);
+ if (BN_copy(D,d) == NULL) return(0);
+ if (BN_copy(rem,m) == NULL) return(0);
+
+ /* The next 2 are needed so we can do a dv->d[0]|=1 later
+ * since BN_lshift1 will only work once there is a value :-) */
+ BN_zero(dv);
+ bn_wexpand(dv,1);
+ dv->top=1;
+
+ if (!BN_lshift(D,D,nm-nd)) return(0);
+ for (i=nm-nd; i>=0; i--)
+ {
+ if (!BN_lshift1(dv,dv)) return(0);
+ if (BN_ucmp(rem,D) >= 0)
+ {
+ dv->d[0]|=1;
+ if (!BN_usub(rem,rem,D)) return(0);
+ }
+/* CAN IMPROVE (and have now :=) */
+ if (!BN_rshift1(D,D)) return(0);
+ }
+ rem->neg=BN_is_zero(rem)?0:m->neg;
+ dv->neg=m->neg^d->neg;
+ return(1);
+ }
+
+#else
+
+int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
+ BN_CTX *ctx)
+ {
+ int norm_shift,i,j,loop;
+ BIGNUM *tmp,wnum,*snum,*sdiv,*res;
+ BN_ULONG *resp,*wnump;
+ BN_ULONG d0,d1;
+ int num_n,div_n;
+
+ bn_check_top(num);
+ bn_check_top(divisor);
+
+ if (BN_is_zero(divisor))
+ {
+ BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO);
+ return(0);
+ }
+
+ if (BN_ucmp(num,divisor) < 0)
+ {
+ if (rm != NULL)
+ { if (BN_copy(rm,num) == NULL) return(0); }
+ if (dv != NULL) BN_zero(dv);
+ return(1);
+ }
+
+ tmp= &(ctx->bn[ctx->tos]);
+ tmp->neg=0;
+ snum= &(ctx->bn[ctx->tos+1]);
+ sdiv= &(ctx->bn[ctx->tos+2]);
+ if (dv == NULL)
+ res= &(ctx->bn[ctx->tos+3]);
+ else res=dv;
+
+ /* First we normalise the numbers */
+ norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2);
+ BN_lshift(sdiv,divisor,norm_shift);
+ sdiv->neg=0;
+ norm_shift+=BN_BITS2;
+ BN_lshift(snum,num,norm_shift);
+ snum->neg=0;
+ div_n=sdiv->top;
+ num_n=snum->top;
+ loop=num_n-div_n;
+
+ /* Lets setup a 'window' into snum
+ * This is the part that corresponds to the current
+ * 'area' being divided */
+ BN_init(&wnum);
+ wnum.d= &(snum->d[loop]);
+ wnum.top= div_n;
+ wnum.max= snum->max+1; /* a bit of a lie */
+
+ /* Get the top 2 words of sdiv */
+ /* i=sdiv->top; */
+ d0=sdiv->d[div_n-1];
+ d1=(div_n == 1)?0:sdiv->d[div_n-2];
+
+ /* pointer to the 'top' of snum */
+ wnump= &(snum->d[num_n-1]);
+
+ /* Setup to 'res' */
+ res->neg= (num->neg^divisor->neg);
+ if (!bn_wexpand(res,(loop+1))) goto err;
+ res->top=loop;
+ resp= &(res->d[loop-1]);
+
+ /* space for temp */
+ if (!bn_wexpand(tmp,(div_n+1))) goto err;
+
+ if (BN_ucmp(&wnum,sdiv) >= 0)
+ {
+ if (!BN_usub(&wnum,&wnum,sdiv)) goto err;
+ *resp=1;
+ res->d[res->top-1]=1;
+ }
+ else
+ res->top--;
+ resp--;
+
+ for (i=0; i<loop-1; i++)
+ {
+ BN_ULONG q,l0;
+#ifdef BN_DIV3W
+ q=bn_div_3_words(wnump,d0,d1);
+#else
+
+#if !defined(NO_ASM) && !defined(PEDANTIC)
+# if defined(__GNUC__) && __GNUC__>=2
+# if defined(__i386)
+ /*
+ * There were two reasons for implementing this template:
+ * - GNU C generates a call to a function (__udivdi3 to be exact)
+ * in reply to ((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0 (I fail to
+ * understand why...);
+ * - divl doesn't only calculate quotient, but also leaves
+ * remainder in %edx which we can definitely use here:-)
+ *
+ * <appro@fy.chalmers.se>
+ */
+# define bn_div_words(n0,n1,d0) \
+ ({ asm volatile ( \
+ "divl %4" \
+ : "=a"(q), "=d"(rem) \
+ : "a"(n1), "d"(n0), "g"(d0) \
+ : "cc"); \
+ q; \
+ })
+# define REMINDER_IS_ALREADY_CALCULATED
+# endif /* __<cpu> */
+# endif /* __GNUC__ */
+#endif /* NO_ASM */
+ BN_ULONG n0,n1,rem=0;
+
+ n0=wnump[0];
+ n1=wnump[-1];
+ if (n0 == d0)
+ q=BN_MASK2;
+ else
+#if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words)
+ q=((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0;
+#else
+ q=bn_div_words(n0,n1,d0);
+#endif
+ {
+#ifdef BN_LLONG
+ BN_ULLONG t2;
+
+#ifndef REMINDER_IS_ALREADY_CALCULATED
+ /*
+ * rem doesn't have to be BN_ULLONG. The least we
+ * know it's less that d0, isn't it?
+ */
+ rem=(n1-q*d0)&BN_MASK2;
+#endif
+ t2=(BN_ULLONG)d1*q;
+
+ for (;;)
+ {
+ if (t2 <= ((((BN_ULLONG)rem)<<BN_BITS2)|wnump[-2]))
+ break;
+ q--;
+ rem += d0;
+ if (rem < d0) break; /* don't let rem overflow */
+ t2 -= d1;
+ }
+#else
+ BN_ULONG t2l,t2h,ql,qh;
+
+#ifndef REMINDER_IS_ALREADY_CALCULATED
+ /*
+ * It's more than enough with the only multiplication.
+ * See the comment above in BN_LLONG section...
+ */
+ rem=(n1-q*d0)&BN_MASK2;
+#endif
+ t2l=LBITS(d1); t2h=HBITS(d1);
+ ql =LBITS(q); qh =HBITS(q);
+ mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */
+
+ for (;;)
+ {
+ if ((t2h < rem) ||
+ ((t2h == rem) && (t2l <= wnump[-2])))
+ break;
+ q--;
+ rem += d0;
+ if (rem < d0) break; /* don't let rem overflow */
+ if (t2l < d1) t2h--; t2l -= d1;
+ }
+#endif
+ }
+#endif /* !BN_DIV3W */
+ wnum.d--; wnum.top++;
+ l0=bn_mul_words(tmp->d,sdiv->d,div_n,q);
+ tmp->d[div_n]=l0;
+ for (j=div_n+1; j>0; j--)
+ if (tmp->d[j-1]) break;
+ tmp->top=j;
+
+ j=wnum.top;
+ BN_sub(&wnum,&wnum,tmp);
+
+ snum->top=snum->top+wnum.top-j;
+
+ if (wnum.neg)
+ {
+ q--;
+ j=wnum.top;
+ BN_add(&wnum,&wnum,sdiv);
+ snum->top+=wnum.top-j;
+ }
+ *(resp--)=q;
+ wnump--;
+ }
+ if (rm != NULL)
+ {
+ BN_rshift(rm,snum,norm_shift);
+ rm->neg=num->neg;
+ }
+ return(1);
+err:
+ return(0);
+ }
+
+#endif
+
+/* rem != m */
+int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
+ {
+#if 0 /* The old slow way */
+ int i,nm,nd;
+ BIGNUM *dv;
+
+ if (BN_ucmp(m,d) < 0)
+ return((BN_copy(rem,m) == NULL)?0:1);
+
+ dv= &(ctx->bn[ctx->tos]);
+
+ if (!BN_copy(rem,m)) return(0);
+
+ nm=BN_num_bits(rem);
+ nd=BN_num_bits(d);
+ if (!BN_lshift(dv,d,nm-nd)) return(0);
+ for (i=nm-nd; i>=0; i--)
+ {
+ if (BN_cmp(rem,dv) >= 0)
+ {
+ if (!BN_sub(rem,rem,dv)) return(0);
+ }
+ if (!BN_rshift1(dv,dv)) return(0);
+ }
+ return(1);
+#else
+ return(BN_div(NULL,rem,m,d,ctx));
+#endif
+ }
+
diff --git a/lib/dns/sec/openssl/bn_err.c b/lib/dns/sec/openssl/bn_err.c
new file mode 100644
index 00000000..73e80774
--- /dev/null
+++ b/lib/dns/sec/openssl/bn_err.c
@@ -0,0 +1,116 @@
+/* crypto/bn/bn_err.c */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+
+/* BEGIN ERROR CODES */
+#ifndef NO_ERR
+static ERR_STRING_DATA BN_str_functs[]=
+ {
+{ERR_PACK(0,BN_F_BN_BLINDING_CONVERT,0), "BN_BLINDING_convert"},
+{ERR_PACK(0,BN_F_BN_BLINDING_INVERT,0), "BN_BLINDING_invert"},
+{ERR_PACK(0,BN_F_BN_BLINDING_NEW,0), "BN_BLINDING_new"},
+{ERR_PACK(0,BN_F_BN_BLINDING_UPDATE,0), "BN_BLINDING_update"},
+{ERR_PACK(0,BN_F_BN_BN2DEC,0), "BN_bn2dec"},
+{ERR_PACK(0,BN_F_BN_BN2HEX,0), "BN_bn2hex"},
+{ERR_PACK(0,BN_F_BN_CTX_NEW,0), "BN_CTX_new"},
+{ERR_PACK(0,BN_F_BN_DIV,0), "BN_div"},
+{ERR_PACK(0,BN_F_BN_EXPAND2,0), "bn_expand2"},
+{ERR_PACK(0,BN_F_BN_MOD_EXP_MONT,0), "BN_mod_exp_mont"},
+{ERR_PACK(0,BN_F_BN_MOD_INVERSE,0), "BN_mod_inverse"},
+{ERR_PACK(0,BN_F_BN_MOD_MUL_RECIPROCAL,0), "BN_mod_mul_reciprocal"},
+{ERR_PACK(0,BN_F_BN_MPI2BN,0), "BN_mpi2bn"},
+{ERR_PACK(0,BN_F_BN_NEW,0), "BN_new"},
+{ERR_PACK(0,BN_F_BN_RAND,0), "BN_rand"},
+{ERR_PACK(0,BN_F_BN_USUB,0), "BN_usub"},
+{0,NULL}
+ };
+
+static ERR_STRING_DATA BN_str_reasons[]=
+ {
+{BN_R_ARG2_LT_ARG3 ,"arg2 lt arg3"},
+{BN_R_BAD_RECIPROCAL ,"bad reciprocal"},
+{BN_R_CALLED_WITH_EVEN_MODULUS ,"called with even modulus"},
+{BN_R_DIV_BY_ZERO ,"div by zero"},
+{BN_R_ENCODING_ERROR ,"encoding error"},
+{BN_R_EXPAND_ON_STATIC_BIGNUM_DATA ,"expand on static bignum data"},
+{BN_R_INVALID_LENGTH ,"invalid length"},
+{BN_R_NOT_INITIALIZED ,"not initialized"},
+{BN_R_NO_INVERSE ,"no inverse"},
+{0,NULL}
+ };
+
+#endif
+
+void ERR_load_BN_strings(void)
+ {
+ static int init=1;
+
+ if (init)
+ {
+ init=0;
+#ifndef NO_ERR
+ ERR_load_strings(ERR_LIB_BN,BN_str_functs);
+ ERR_load_strings(ERR_LIB_BN,BN_str_reasons);
+#endif
+
+ }
+ }
diff --git a/lib/dns/sec/openssl/bn_exp.c b/lib/dns/sec/openssl/bn_exp.c
new file mode 100644
index 00000000..2df1614a
--- /dev/null
+++ b/lib/dns/sec/openssl/bn_exp.c
@@ -0,0 +1,549 @@
+/* crypto/bn/bn_exp.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+#define TABLE_SIZE 16
+
+/* slow but works */
+int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx)
+ {
+ BIGNUM *t;
+ int r=0;
+
+ bn_check_top(a);
+ bn_check_top(b);
+ bn_check_top(m);
+
+ t= &(ctx->bn[ctx->tos++]);
+ if (a == b)
+ { if (!BN_sqr(t,a,ctx)) goto err; }
+ else
+ { if (!BN_mul(t,a,b,ctx)) goto err; }
+ if (!BN_mod(ret,t,m,ctx)) goto err;
+ r=1;
+err:
+ ctx->tos--;
+ return(r);
+ }
+
+#if 0
+/* this one works - simple but works */
+int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, BN_CTX *ctx)
+ {
+ int i,bits,ret=0;
+ BIGNUM *v,*tmp;
+
+ v= &(ctx->bn[ctx->tos++]);
+ tmp= &(ctx->bn[ctx->tos++]);
+
+ if (BN_copy(v,a) == NULL) goto err;
+ bits=BN_num_bits(p);
+
+ if (BN_is_odd(p))
+ { if (BN_copy(r,a) == NULL) goto err; }
+ else { if (!BN_one(r)) goto err; }
+
+ for (i=1; i<bits; i++)
+ {
+ if (!BN_sqr(tmp,v,ctx)) goto err;
+ if (!BN_mod(v,tmp,m,ctx)) goto err;
+ if (BN_is_bit_set(p,i))
+ {
+ if (!BN_mul(tmp,r,v,ctx)) goto err;
+ if (!BN_mod(r,tmp,m,ctx)) goto err;
+ }
+ }
+ ret=1;
+err:
+ ctx->tos-=2;
+ return(ret);
+ }
+
+#endif
+
+/* this one works - simple but works */
+int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx)
+ {
+ int i,bits,ret=0,tos;
+ BIGNUM *v,*rr;
+
+ tos=ctx->tos;
+ v= &(ctx->bn[ctx->tos++]);
+ if ((r == a) || (r == p))
+ rr= &(ctx->bn[ctx->tos++]);
+ else
+ rr=r;
+
+ if (BN_copy(v,a) == NULL) goto err;
+ bits=BN_num_bits(p);
+
+ if (BN_is_odd(p))
+ { if (BN_copy(rr,a) == NULL) goto err; }
+ else { if (!BN_one(rr)) goto err; }
+
+ for (i=1; i<bits; i++)
+ {
+ if (!BN_sqr(v,v,ctx)) goto err;
+ if (BN_is_bit_set(p,i))
+ {
+ if (!BN_mul(rr,rr,v,ctx)) goto err;
+ }
+ }
+ ret=1;
+err:
+ ctx->tos=tos;
+ if (r != rr) BN_copy(r,rr);
+ return(ret);
+ }
+
+int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
+ BN_CTX *ctx)
+ {
+ int ret;
+
+ bn_check_top(a);
+ bn_check_top(p);
+ bn_check_top(m);
+
+#ifdef MONT_MUL_MOD
+ /* I have finally been able to take out this pre-condition of
+ * the top bit being set. It was caused by an error in BN_div
+ * with negatives. There was also another problem when for a^b%m
+ * a >= m. eay 07-May-97 */
+/* if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */
+
+ if (BN_is_odd(m))
+ { ret=BN_mod_exp_mont(r,a,p,m,ctx,NULL); }
+ else
+#endif
+#ifdef RECP_MUL_MOD
+ { ret=BN_mod_exp_recp(r,a,p,m,ctx); }
+#else
+ { ret=BN_mod_exp_simple(r,a,p,m,ctx); }
+#endif
+
+ return(ret);
+ }
+
+/* #ifdef RECP_MUL_MOD */
+int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx)
+ {
+ int i,j,bits,ret=0,wstart,wend,window,wvalue;
+ int start=1,ts=0;
+ BIGNUM *aa;
+ BIGNUM val[TABLE_SIZE];
+ BN_RECP_CTX recp;
+
+ aa= &(ctx->bn[ctx->tos++]);
+ bits=BN_num_bits(p);
+
+ if (bits == 0)
+ {
+ BN_one(r);
+ return(1);
+ }
+ BN_RECP_CTX_init(&recp);
+ if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err;
+
+ BN_init(&(val[0]));
+ ts=1;
+
+ if (!BN_mod(&(val[0]),a,m,ctx)) goto err; /* 1 */
+ if (!BN_mod_mul_reciprocal(aa,&(val[0]),&(val[0]),&recp,ctx))
+ goto err; /* 2 */
+
+ if (bits <= 17) /* This is probably 3 or 0x10001, so just do singles */
+ window=1;
+ else if (bits >= 256)
+ window=5; /* max size of window */
+ else if (bits >= 128)
+ window=4;
+ else
+ window=3;
+
+ j=1<<(window-1);
+ for (i=1; i<j; i++)
+ {
+ BN_init(&val[i]);
+ if (!BN_mod_mul_reciprocal(&(val[i]),&(val[i-1]),aa,&recp,ctx))
+ goto err;
+ }
+ ts=i;
+
+ start=1; /* This is used to avoid multiplication etc
+ * when there is only the value '1' in the
+ * buffer. */
+ wvalue=0; /* The 'value' of the window */
+ wstart=bits-1; /* The top bit of the window */
+ wend=0; /* The bottom bit of the window */
+
+ if (!BN_one(r)) goto err;
+
+ for (;;)
+ {
+ if (BN_is_bit_set(p,wstart) == 0)
+ {
+ if (!start)
+ if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
+ goto err;
+ if (wstart == 0) break;
+ wstart--;
+ continue;
+ }
+ /* We now have wstart on a 'set' bit, we now need to work out
+ * how bit a window to do. To do this we need to scan
+ * forward until the last set bit before the end of the
+ * window */
+ j=wstart;
+ wvalue=1;
+ wend=0;
+ for (i=1; i<window; i++)
+ {
+ if (wstart-i < 0) break;
+ if (BN_is_bit_set(p,wstart-i))
+ {
+ wvalue<<=(i-wend);
+ wvalue|=1;
+ wend=i;
+ }
+ }
+
+ /* wend is the size of the current window */
+ j=wend+1;
+ /* add the 'bytes above' */
+ if (!start)
+ for (i=0; i<j; i++)
+ {
+ if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
+ goto err;
+ }
+
+ /* wvalue will be an odd number < 2^window */
+ if (!BN_mod_mul_reciprocal(r,r,&(val[wvalue>>1]),&recp,ctx))
+ goto err;
+
+ /* move the 'window' down further */
+ wstart-=wend+1;
+ wvalue=0;
+ start=0;
+ if (wstart < 0) break;
+ }
+ ret=1;
+err:
+ ctx->tos--;
+ for (i=0; i<ts; i++)
+ BN_clear_free(&(val[i]));
+ BN_RECP_CTX_free(&recp);
+ return(ret);
+ }
+/* #endif */
+
+/* #ifdef MONT_MUL_MOD */
+int BN_mod_exp_mont(BIGNUM *rr, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
+ {
+ int i,j,bits,ret=0,wstart,wend,window,wvalue;
+ int start=1,ts=0;
+ BIGNUM *d,*r;
+ BIGNUM *aa;
+ BIGNUM val[TABLE_SIZE];
+ BN_MONT_CTX *mont=NULL;
+
+ bn_check_top(a);
+ bn_check_top(p);
+ bn_check_top(m);
+
+ if (!(m->d[0] & 1))
+ {
+ BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS);
+ return(0);
+ }
+ d= &(ctx->bn[ctx->tos++]);
+ r= &(ctx->bn[ctx->tos++]);
+ bits=BN_num_bits(p);
+ if (bits == 0)
+ {
+ BN_one(r);
+ return(1);
+ }
+
+ /* If this is not done, things will break in the montgomery
+ * part */
+
+#if 1
+ if (in_mont != NULL)
+ mont=in_mont;
+ else
+#endif
+ {
+ if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
+ if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
+ }
+
+ BN_init(&val[0]);
+ ts=1;
+ if (BN_ucmp(a,m) >= 0)
+ {
+ BN_mod(&(val[0]),a,m,ctx);
+ aa= &(val[0]);
+ }
+ else
+ aa=a;
+ if (!BN_to_montgomery(&(val[0]),aa,mont,ctx)) goto err; /* 1 */
+ if (!BN_mod_mul_montgomery(d,&(val[0]),&(val[0]),mont,ctx)) goto err; /* 2 */
+
+ if (bits <= 20) /* This is probably 3 or 0x10001, so just do singles */
+ window=1;
+ else if (bits >= 256)
+ window=5; /* max size of window */
+ else if (bits >= 128)
+ window=4;
+ else
+ window=3;
+
+ j=1<<(window-1);
+ for (i=1; i<j; i++)
+ {
+ BN_init(&(val[i]));
+ if (!BN_mod_mul_montgomery(&(val[i]),&(val[i-1]),d,mont,ctx))
+ goto err;
+ }
+ ts=i;
+
+ start=1; /* This is used to avoid multiplication etc
+ * when there is only the value '1' in the
+ * buffer. */
+ wvalue=0; /* The 'value' of the window */
+ wstart=bits-1; /* The top bit of the window */
+ wend=0; /* The bottom bit of the window */
+
+ if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;
+ for (;;)
+ {
+ if (BN_is_bit_set(p,wstart) == 0)
+ {
+ if (!start)
+ {
+ if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
+ goto err;
+ }
+ if (wstart == 0) break;
+ wstart--;
+ continue;
+ }
+ /* We now have wstart on a 'set' bit, we now need to work out
+ * how bit a window to do. To do this we need to scan
+ * forward until the last set bit before the end of the
+ * window */
+ j=wstart;
+ wvalue=1;
+ wend=0;
+ for (i=1; i<window; i++)
+ {
+ if (wstart-i < 0) break;
+ if (BN_is_bit_set(p,wstart-i))
+ {
+ wvalue<<=(i-wend);
+ wvalue|=1;
+ wend=i;
+ }
+ }
+
+ /* wend is the size of the current window */
+ j=wend+1;
+ /* add the 'bytes above' */
+ if (!start)
+ for (i=0; i<j; i++)
+ {
+ if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
+ goto err;
+ }
+
+ /* wvalue will be an odd number < 2^window */
+ if (!BN_mod_mul_montgomery(r,r,&(val[wvalue>>1]),mont,ctx))
+ goto err;
+
+ /* move the 'window' down further */
+ wstart-=wend+1;
+ wvalue=0;
+ start=0;
+ if (wstart < 0) break;
+ }
+ BN_from_montgomery(rr,r,mont,ctx);
+ ret=1;
+err:
+ if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
+ ctx->tos-=2;
+ for (i=0; i<ts; i++)
+ BN_clear_free(&(val[i]));
+ return(ret);
+ }
+/* #endif */
+
+/* The old fallback, simple version :-) */
+int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,
+ BN_CTX *ctx)
+ {
+ int i,j,bits,ret=0,wstart,wend,window,wvalue,ts=0;
+ int start=1;
+ BIGNUM *d;
+ BIGNUM val[TABLE_SIZE];
+
+ d= &(ctx->bn[ctx->tos++]);
+ bits=BN_num_bits(p);
+
+ if (bits == 0)
+ {
+ BN_one(r);
+ return(1);
+ }
+
+ BN_init(&(val[0]));
+ ts=1;
+ if (!BN_mod(&(val[0]),a,m,ctx)) goto err; /* 1 */
+ if (!BN_mod_mul(d,&(val[0]),&(val[0]),m,ctx))
+ goto err; /* 2 */
+
+ if (bits <= 17) /* This is probably 3 or 0x10001, so just do singles */
+ window=1;
+ else if (bits >= 256)
+ window=5; /* max size of window */
+ else if (bits >= 128)
+ window=4;
+ else
+ window=3;
+
+ j=1<<(window-1);
+ for (i=1; i<j; i++)
+ {
+ BN_init(&(val[i]));
+ if (!BN_mod_mul(&(val[i]),&(val[i-1]),d,m,ctx))
+ goto err;
+ }
+ ts=i;
+
+ start=1; /* This is used to avoid multiplication etc
+ * when there is only the value '1' in the
+ * buffer. */
+ wvalue=0; /* The 'value' of the window */
+ wstart=bits-1; /* The top bit of the window */
+ wend=0; /* The bottom bit of the window */
+
+ if (!BN_one(r)) goto err;
+
+ for (;;)
+ {
+ if (BN_is_bit_set(p,wstart) == 0)
+ {
+ if (!start)
+ if (!BN_mod_mul(r,r,r,m,ctx))
+ goto err;
+ if (wstart == 0) break;
+ wstart--;
+ continue;
+ }
+ /* We now have wstart on a 'set' bit, we now need to work out
+ * how bit a window to do. To do this we need to scan
+ * forward until the last set bit before the end of the
+ * window */
+ j=wstart;
+ wvalue=1;
+ wend=0;
+ for (i=1; i<window; i++)
+ {
+ if (wstart-i < 0) break;
+ if (BN_is_bit_set(p,wstart-i))
+ {
+ wvalue<<=(i-wend);
+ wvalue|=1;
+ wend=i;
+ }
+ }
+
+ /* wend is the size of the current window */
+ j=wend+1;
+ /* add the 'bytes above' */
+ if (!start)
+ for (i=0; i<j; i++)
+ {
+ if (!BN_mod_mul(r,r,r,m,ctx))
+ goto err;
+ }
+
+ /* wvalue will be an odd number < 2^window */
+ if (!BN_mod_mul(r,r,&(val[wvalue>>1]),m,ctx))
+ goto err;
+
+ /* move the 'window' down further */
+ wstart-=wend+1;
+ wvalue=0;
+ start=0;
+ if (wstart < 0) break;
+ }
+ ret=1;
+err:
+ ctx->tos--;
+ for (i=0; i<ts; i++)
+ BN_clear_free(&(val[i]));
+ return(ret);
+ }
+
diff --git a/lib/dns/sec/openssl/bn_exp2.c b/lib/dns/sec/openssl/bn_exp2.c
new file mode 100644
index 00000000..1132d533
--- /dev/null
+++ b/lib/dns/sec/openssl/bn_exp2.c
@@ -0,0 +1,195 @@
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/* I've done some timing with different table sizes.
+ * The main hassle is that even with bits set at 3, this requires
+ * 63 BIGNUMs to store the pre-calculated values.
+ * 512 1024
+ * bits=1 75.4% 79.4%
+ * bits=2 61.2% 62.4%
+ * bits=3 61.3% 59.3%
+ * The lack of speed improvment is also a function of the pre-calculation
+ * which could be removed.
+ */
+#define EXP2_TABLE_BITS 2 /* 1 2 3 4 5 */
+#define EXP2_TABLE_SIZE 4 /* 2 4 8 16 32 */
+
+int BN_mod_exp2_mont(BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, BIGNUM *a2,
+ BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
+ {
+ int i,j,k,bits,bits1,bits2,ret=0,wstart,wend,window,xvalue,yvalue;
+ int start=1,ts=0,x,y;
+ BIGNUM *d,*aa1,*aa2,*r;
+ BIGNUM val[EXP2_TABLE_SIZE][EXP2_TABLE_SIZE];
+ BN_MONT_CTX *mont=NULL;
+
+ bn_check_top(a1);
+ bn_check_top(p1);
+ bn_check_top(a2);
+ bn_check_top(p2);
+ bn_check_top(m);
+
+ if (!(m->d[0] & 1))
+ {
+ BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS);
+ return(0);
+ }
+ d= &(ctx->bn[ctx->tos++]);
+ r= &(ctx->bn[ctx->tos++]);
+ bits1=BN_num_bits(p1);
+ bits2=BN_num_bits(p2);
+ if ((bits1 == 0) && (bits2 == 0))
+ {
+ BN_one(r);
+ return(1);
+ }
+ bits=(bits1 > bits2)?bits1:bits2;
+
+ /* If this is not done, things will break in the montgomery
+ * part */
+
+ if (in_mont != NULL)
+ mont=in_mont;
+ else
+ {
+ if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
+ if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
+ }
+
+ BN_init(&(val[0][0]));
+ BN_init(&(val[1][1]));
+ BN_init(&(val[0][1]));
+ BN_init(&(val[1][0]));
+ ts=1;
+ if (BN_ucmp(a1,m) >= 0)
+ {
+ BN_mod(&(val[1][0]),a1,m,ctx);
+ aa1= &(val[1][0]);
+ }
+ else
+ aa1=a1;
+ if (BN_ucmp(a2,m) >= 0)
+ {
+ BN_mod(&(val[0][1]),a2,m,ctx);
+ aa2= &(val[0][1]);
+ }
+ else
+ aa2=a2;
+ if (!BN_to_montgomery(&(val[1][0]),aa1,mont,ctx)) goto err;
+ if (!BN_to_montgomery(&(val[0][1]),aa2,mont,ctx)) goto err;
+ if (!BN_mod_mul_montgomery(&(val[1][1]),
+ &(val[1][0]),&(val[0][1]),mont,ctx))
+ goto err;
+
+#if 0
+ if (bits <= 20) /* This is probably 3 or 0x10001, so just do singles */
+ window=1;
+ else if (bits > 250)
+ window=5; /* max size of window */
+ else if (bits >= 120)
+ window=4;
+ else
+ window=3;
+#else
+ window=EXP2_TABLE_BITS;
+#endif
+
+ k=1<<window;
+ for (x=0; x<k; x++)
+ {
+ if (x >= 2)
+ {
+ BN_init(&(val[x][0]));
+ BN_init(&(val[x][1]));
+ if (!BN_mod_mul_montgomery(&(val[x][0]),
+ &(val[1][0]),&(val[x-1][0]),mont,ctx)) goto err;
+ if (!BN_mod_mul_montgomery(&(val[x][1]),
+ &(val[1][0]),&(val[x-1][1]),mont,ctx)) goto err;
+ }
+ for (y=2; y<k; y++)
+ {
+ BN_init(&(val[x][y]));
+ if (!BN_mod_mul_montgomery(&(val[x][y]),
+ &(val[x][y-1]),&(val[0][1]),mont,ctx))
+ goto err;
+ }
+ }
+ ts=k;
+
+ start=1; /* This is used to avoid multiplication etc
+ * when there is only the value '1' in the
+ * buffer. */
+ xvalue=0; /* The 'x value' of the window */
+ yvalue=0; /* The 'y value' of the window */
+ wstart=bits-1; /* The top bit of the window */
+ wend=0; /* The bottom bit of the window */
+
+ if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;
+ for (;;)
+ {
+ xvalue=BN_is_bit_set(p1,wstart);
+ yvalue=BN_is_bit_set(p2,wstart);
+ if (!(xvalue || yvalue))
+ {
+ if (!start)
+ {
+ if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
+ goto err;
+ }
+ wstart--;
+ if (wstart < 0) break;
+ continue;
+ }
+ /* We now have wstart on a 'set' bit, we now need to work out
+ * how bit a window to do. To do this we need to scan
+ * forward until the last set bit before the end of the
+ * window */
+ j=wstart;
+ /* xvalue=BN_is_bit_set(p1,wstart); already set */
+ /* yvalue=BN_is_bit_set(p1,wstart); already set */
+ wend=0;
+ for (i=1; i<window; i++)
+ {
+ if (wstart-i < 0) break;
+ xvalue+=xvalue;
+ xvalue|=BN_is_bit_set(p1,wstart-i);
+ yvalue+=yvalue;
+ yvalue|=BN_is_bit_set(p2,wstart-i);
+ }
+
+ /* i is the size of the current window */
+ /* add the 'bytes above' */
+ if (!start)
+ for (j=0; j<i; j++)
+ {
+ if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
+ goto err;
+ }
+
+ /* wvalue will be an odd number < 2^window */
+ if (xvalue || yvalue)
+ {
+ if (!BN_mod_mul_montgomery(r,r,&(val[xvalue][yvalue]),
+ mont,ctx)) goto err;
+ }
+
+ /* move the 'window' down further */
+ wstart-=i;
+ start=0;
+ if (wstart < 0) break;
+ }
+ BN_from_montgomery(rr,r,mont,ctx);
+ ret=1;
+err:
+ if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
+ ctx->tos-=2;
+ for (i=0; i<ts; i++)
+ {
+ for (j=0; j<ts; j++)
+ {
+ BN_clear_free(&(val[i][j]));
+ }
+ }
+ return(ret);
+ }
diff --git a/lib/dns/sec/openssl/bn_gcd.c b/lib/dns/sec/openssl/bn_gcd.c
new file mode 100644
index 00000000..64a76f44
--- /dev/null
+++ b/lib/dns/sec/openssl/bn_gcd.c
@@ -0,0 +1,204 @@
+/* crypto/bn/bn_gcd.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+static BIGNUM *euclid(BIGNUM *a, BIGNUM *b);
+int BN_gcd(BIGNUM *r, BIGNUM *in_a, BIGNUM *in_b, BN_CTX *ctx)
+ {
+ BIGNUM *a,*b,*t;
+ int ret=0;
+
+ bn_check_top(in_a);
+ bn_check_top(in_b);
+
+ a= &(ctx->bn[ctx->tos]);
+ b= &(ctx->bn[ctx->tos+1]);
+
+ if (BN_copy(a,in_a) == NULL) goto err;
+ if (BN_copy(b,in_b) == NULL) goto err;
+
+ if (BN_cmp(a,b) < 0) { t=a; a=b; b=t; }
+ t=euclid(a,b);
+ if (t == NULL) goto err;
+
+ if (BN_copy(r,t) == NULL) goto err;
+ ret=1;
+err:
+ return(ret);
+ }
+
+static BIGNUM *euclid(BIGNUM *a, BIGNUM *b)
+ {
+ BIGNUM *t;
+ int shifts=0;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ for (;;)
+ {
+ if (BN_is_zero(b))
+ break;
+
+ if (BN_is_odd(a))
+ {
+ if (BN_is_odd(b))
+ {
+ if (!BN_sub(a,a,b)) goto err;
+ if (!BN_rshift1(a,a)) goto err;
+ if (BN_cmp(a,b) < 0)
+ { t=a; a=b; b=t; }
+ }
+ else /* a odd - b even */
+ {
+ if (!BN_rshift1(b,b)) goto err;
+ if (BN_cmp(a,b) < 0)
+ { t=a; a=b; b=t; }
+ }
+ }
+ else /* a is even */
+ {
+ if (BN_is_odd(b))
+ {
+ if (!BN_rshift1(a,a)) goto err;
+ if (BN_cmp(a,b) < 0)
+ { t=a; a=b; b=t; }
+ }
+ else /* a even - b even */
+ {
+ if (!BN_rshift1(a,a)) goto err;
+ if (!BN_rshift1(b,b)) goto err;
+ shifts++;
+ }
+ }
+ }
+ if (shifts)
+ {
+ if (!BN_lshift(a,a,shifts)) goto err;
+ }
+ return(a);
+err:
+ return(NULL);
+ }
+
+/* solves ax == 1 (mod n) */
+BIGNUM *BN_mod_inverse(BIGNUM *in, BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
+ {
+ BIGNUM *A,*B,*X,*Y,*M,*D,*R;
+ BIGNUM *T,*ret=NULL;
+ int sign;
+
+ bn_check_top(a);
+ bn_check_top(n);
+
+ A= &(ctx->bn[ctx->tos]);
+ B= &(ctx->bn[ctx->tos+1]);
+ X= &(ctx->bn[ctx->tos+2]);
+ D= &(ctx->bn[ctx->tos+3]);
+ M= &(ctx->bn[ctx->tos+4]);
+ Y= &(ctx->bn[ctx->tos+5]);
+ ctx->tos+=6;
+ if (in == NULL)
+ R=BN_new();
+ else
+ R=in;
+ if (R == NULL) goto err;
+
+ BN_zero(X);
+ BN_one(Y);
+ if (BN_copy(A,a) == NULL) goto err;
+ if (BN_copy(B,n) == NULL) goto err;
+ sign=1;
+
+ while (!BN_is_zero(B))
+ {
+ if (!BN_div(D,M,A,B,ctx)) goto err;
+ T=A;
+ A=B;
+ B=M;
+ /* T has a struct, M does not */
+
+ if (!BN_mul(T,D,X,ctx)) goto err;
+ if (!BN_add(T,T,Y)) goto err;
+ M=Y;
+ Y=X;
+ X=T;
+ sign= -sign;
+ }
+ if (sign < 0)
+ {
+ if (!BN_sub(Y,n,Y)) goto err;
+ }
+
+ if (BN_is_one(A))
+ { if (!BN_mod(R,Y,n,ctx)) goto err; }
+ else
+ {
+ BNerr(BN_F_BN_MOD_INVERSE,BN_R_NO_INVERSE);
+ goto err;
+ }
+ ret=R;
+err:
+ if ((ret == NULL) && (in == NULL)) BN_free(R);
+ ctx->tos-=6;
+ return(ret);
+ }
+
diff --git a/lib/dns/sec/openssl/bn_lcl.h b/lib/dns/sec/openssl/bn_lcl.h
new file mode 100644
index 00000000..de4a1d94
--- /dev/null
+++ b/lib/dns/sec/openssl/bn_lcl.h
@@ -0,0 +1,272 @@
+/* crypto/bn/bn_lcl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BN_LCL_H
+#define HEADER_BN_LCL_H
+
+#include <openssl/bn.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Pentium pro 16,16,16,32,64 */
+/* Alpha 16,16,16,16.64 */
+#define BN_MULL_SIZE_NORMAL (16) /* 32 */
+#define BN_MUL_RECURSIVE_SIZE_NORMAL (16) /* 32 less than */
+#define BN_SQR_RECURSIVE_SIZE_NORMAL (16) /* 32 */
+#define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL (32) /* 32 */
+#define BN_MONT_CTX_SET_SIZE_WORD (64) /* 32 */
+
+#if 0
+#ifndef BN_MUL_COMBA
+/* #define bn_mul_comba8(r,a,b) bn_mul_normal(r,a,8,b,8) */
+/* #define bn_mul_comba4(r,a,b) bn_mul_normal(r,a,4,b,4) */
+#endif
+
+#ifndef BN_SQR_COMBA
+/* This is probably faster than using the C code - I need to check */
+#define bn_sqr_comba8(r,a) bn_mul_normal(r,a,8,a,8)
+#define bn_sqr_comba4(r,a) bn_mul_normal(r,a,4,a,4)
+#endif
+#endif
+
+/*************************************************************
+ * Using the long long type
+ */
+#define Lw(t) (((BN_ULONG)(t))&BN_MASK2)
+#define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
+
+/* These are used for internal error checking and are not normally used */
+#ifdef BN_DEBUG
+#define bn_check_top(a) \
+ { if (((a)->top < 0) || ((a)->top > (a)->max)) \
+ { char *nullp=NULL; *nullp='z'; } }
+#define bn_check_num(a) if ((a) < 0) { char *nullp=NULL; *nullp='z'; }
+#else
+#define bn_check_top(a)
+#define bn_check_num(a)
+#endif
+
+/* This macro is to add extra stuff for development checking */
+#ifdef BN_DEBUG
+#define bn_set_max(r) ((r)->max=(r)->top,BN_set_flags((r),BN_FLG_STATIC_DATA))
+#else
+#define bn_set_max(r)
+#endif
+
+/* These macros are used to 'take' a section of a bignum for read only use */
+#define bn_set_low(r,a,n) \
+ { \
+ (r)->top=((a)->top > (n))?(n):(a)->top; \
+ (r)->d=(a)->d; \
+ (r)->neg=(a)->neg; \
+ (r)->flags|=BN_FLG_STATIC_DATA; \
+ bn_set_max(r); \
+ }
+
+#define bn_set_high(r,a,n) \
+ { \
+ if ((a)->top > (n)) \
+ { \
+ (r)->top=(a)->top-n; \
+ (r)->d= &((a)->d[n]); \
+ } \
+ else \
+ (r)->top=0; \
+ (r)->neg=(a)->neg; \
+ (r)->flags|=BN_FLG_STATIC_DATA; \
+ bn_set_max(r); \
+ }
+
+/* #define bn_expand(n,b) ((((b)/BN_BITS2) <= (n)->max)?(n):bn_expand2((n),(b))) */
+
+#ifdef BN_LLONG
+#define mul_add(r,a,w,c) { \
+ BN_ULLONG t; \
+ t=(BN_ULLONG)w * (a) + (r) + (c); \
+ (r)= Lw(t); \
+ (c)= Hw(t); \
+ }
+
+#define mul(r,a,w,c) { \
+ BN_ULLONG t; \
+ t=(BN_ULLONG)w * (a) + (c); \
+ (r)= Lw(t); \
+ (c)= Hw(t); \
+ }
+
+#else
+/*************************************************************
+ * No long long type
+ */
+
+#define LBITS(a) ((a)&BN_MASK2l)
+#define HBITS(a) (((a)>>BN_BITS4)&BN_MASK2l)
+#define L2HBITS(a) ((BN_ULONG)((a)&BN_MASK2l)<<BN_BITS4)
+
+#define LLBITS(a) ((a)&BN_MASKl)
+#define LHBITS(a) (((a)>>BN_BITS2)&BN_MASKl)
+#define LL2HBITS(a) ((BN_ULLONG)((a)&BN_MASKl)<<BN_BITS2)
+
+#define mul64(l,h,bl,bh) \
+ { \
+ BN_ULONG m,m1,lt,ht; \
+ \
+ lt=l; \
+ ht=h; \
+ m =(bh)*(lt); \
+ lt=(bl)*(lt); \
+ m1=(bl)*(ht); \
+ ht =(bh)*(ht); \
+ m=(m+m1)&BN_MASK2; if (m < m1) ht+=L2HBITS(1L); \
+ ht+=HBITS(m); \
+ m1=L2HBITS(m); \
+ lt=(lt+m1)&BN_MASK2; if (lt < m1) ht++; \
+ (l)=lt; \
+ (h)=ht; \
+ }
+
+#define sqr64(lo,ho,in) \
+ { \
+ BN_ULONG l,h,m; \
+ \
+ h=(in); \
+ l=LBITS(h); \
+ h=HBITS(h); \
+ m =(l)*(h); \
+ l*=l; \
+ h*=h; \
+ h+=(m&BN_MASK2h1)>>(BN_BITS4-1); \
+ m =(m&BN_MASK2l)<<(BN_BITS4+1); \
+ l=(l+m)&BN_MASK2; if (l < m) h++; \
+ (lo)=l; \
+ (ho)=h; \
+ }
+
+#define mul_add(r,a,bl,bh,c) { \
+ BN_ULONG l,h; \
+ \
+ h= (a); \
+ l=LBITS(h); \
+ h=HBITS(h); \
+ mul64(l,h,(bl),(bh)); \
+ \
+ /* non-multiply part */ \
+ l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
+ (c)=(r); \
+ l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
+ (c)=h&BN_MASK2; \
+ (r)=l; \
+ }
+
+#define mul(r,a,bl,bh,c) { \
+ BN_ULONG l,h; \
+ \
+ h= (a); \
+ l=LBITS(h); \
+ h=HBITS(h); \
+ mul64(l,h,(bl),(bh)); \
+ \
+ /* non-multiply part */ \
+ l+=(c); if ((l&BN_MASK2) < (c)) h++; \
+ (c)=h&BN_MASK2; \
+ (r)=l&BN_MASK2; \
+ }
+
+#endif
+
+/* BEW */
+#define OPENSSL_EXTERN extern
+#define NO_BIO
+
+OPENSSL_EXTERN int bn_limit_bits;
+OPENSSL_EXTERN int bn_limit_num; /* (1<<bn_limit_bits) */
+/* Recursive 'low' limit */
+OPENSSL_EXTERN int bn_limit_bits_low;
+OPENSSL_EXTERN int bn_limit_num_low; /* (1<<bn_limit_bits_low) */
+/* Do modified 'high' part calculation' */
+OPENSSL_EXTERN int bn_limit_bits_high;
+OPENSSL_EXTERN int bn_limit_num_high; /* (1<<bn_limit_bits_high) */
+OPENSSL_EXTERN int bn_limit_bits_mont;
+OPENSSL_EXTERN int bn_limit_num_mont; /* (1<<bn_limit_bits_mont) */
+
+BIGNUM *bn_expand2(BIGNUM *b, int bits);
+
+void bn_mul_normal(BN_ULONG *r,BN_ULONG *a,int na,BN_ULONG *b,int nb);
+void bn_mul_comba8(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
+void bn_mul_comba4(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
+void bn_sqr_normal(BN_ULONG *r, BN_ULONG *a, int n, BN_ULONG *tmp);
+void bn_sqr_comba8(BN_ULONG *r,BN_ULONG *a);
+void bn_sqr_comba4(BN_ULONG *r,BN_ULONG *a);
+int bn_cmp_words(BN_ULONG *a,BN_ULONG *b,int n);
+void bn_mul_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,BN_ULONG *t);
+void bn_mul_part_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,
+ int tn, int n,BN_ULONG *t);
+void bn_sqr_recursive(BN_ULONG *r,BN_ULONG *a, int n2, BN_ULONG *t);
+void bn_mul_low_normal(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b, int n);
+void bn_mul_low_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,
+ BN_ULONG *t);
+void bn_mul_high(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,BN_ULONG *l,int n2,
+ BN_ULONG *t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/dns/sec/openssl/bn_lib.c b/lib/dns/sec/openssl/bn_lib.c
new file mode 100644
index 00000000..26b11c41
--- /dev/null
+++ b/lib/dns/sec/openssl/bn_lib.c
@@ -0,0 +1,787 @@
+/* crypto/bn/bn_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+const char *BN_version="Big Number" OPENSSL_VERSION_PTEXT;
+
+/* For a 32 bit machine
+ * 2 - 4 == 128
+ * 3 - 8 == 256
+ * 4 - 16 == 512
+ * 5 - 32 == 1024
+ * 6 - 64 == 2048
+ * 7 - 128 == 4096
+ * 8 - 256 == 8192
+ */
+OPENSSL_GLOBAL int bn_limit_bits=0;
+OPENSSL_GLOBAL int bn_limit_num=8; /* (1<<bn_limit_bits) */
+OPENSSL_GLOBAL int bn_limit_bits_low=0;
+OPENSSL_GLOBAL int bn_limit_num_low=8; /* (1<<bn_limit_bits_low) */
+OPENSSL_GLOBAL int bn_limit_bits_high=0;
+OPENSSL_GLOBAL int bn_limit_num_high=8; /* (1<<bn_limit_bits_high) */
+OPENSSL_GLOBAL int bn_limit_bits_mont=0;
+OPENSSL_GLOBAL int bn_limit_num_mont=8; /* (1<<bn_limit_bits_mont) */
+
+void BN_set_params(int mult, int high, int low, int mont)
+ {
+ if (mult >= 0)
+ {
+ if ((unsigned int)mult > (sizeof(int)*8)-1)
+ mult=sizeof(int)*8-1;
+ bn_limit_bits=mult;
+ bn_limit_num=1<<mult;
+ }
+ if (high >= 0)
+ {
+ if ((unsigned int)high > (sizeof(int)*8)-1)
+ high=sizeof(int)*8-1;
+ bn_limit_bits_high=high;
+ bn_limit_num_high=1<<high;
+ }
+ if (low >= 0)
+ {
+ if ((unsigned int)low > (sizeof(int)*8)-1)
+ low=sizeof(int)*8-1;
+ bn_limit_bits_low=low;
+ bn_limit_num_low=1<<low;
+ }
+ if (mont >= 0)
+ {
+ if ((unsigned int)mont > (sizeof(int)*8)-1)
+ mont=sizeof(int)*8-1;
+ bn_limit_bits_mont=mont;
+ bn_limit_num_mont=1<<mont;
+ }
+ }
+
+int BN_get_params(int which)
+ {
+ if (which == 0) return(bn_limit_bits);
+ else if (which == 1) return(bn_limit_bits_high);
+ else if (which == 2) return(bn_limit_bits_low);
+ else if (which == 3) return(bn_limit_bits_mont);
+ else return(0);
+ }
+
+BIGNUM *BN_value_one(void)
+ {
+ static BN_ULONG data_one=1L;
+ static BIGNUM const_one={&data_one,1,1,0,0};
+
+ return(&const_one);
+ }
+
+char *BN_options(void)
+ {
+ static int init=0;
+ static char data[16];
+
+ if (!init)
+ {
+ init++;
+#ifdef BN_LLONG
+ sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULLONG)*8,
+ (int)sizeof(BN_ULONG)*8);
+#else
+ sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULONG)*8,
+ (int)sizeof(BN_ULONG)*8);
+#endif
+ }
+ return(data);
+ }
+
+int BN_num_bits_word(BN_ULONG l)
+ {
+ static const char bits[256]={
+ 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ };
+
+#if defined(SIXTY_FOUR_BIT_LONG)
+ if (l & 0xffffffff00000000L)
+ {
+ if (l & 0xffff000000000000L)
+ {
+ if (l & 0xff00000000000000L)
+ {
+ return(bits[(int)(l>>56)]+56);
+ }
+ else return(bits[(int)(l>>48)]+48);
+ }
+ else
+ {
+ if (l & 0x0000ff0000000000L)
+ {
+ return(bits[(int)(l>>40)]+40);
+ }
+ else return(bits[(int)(l>>32)]+32);
+ }
+ }
+ else
+#else
+#ifdef SIXTY_FOUR_BIT
+ if (l & 0xffffffff00000000LL)
+ {
+ if (l & 0xffff000000000000LL)
+ {
+ if (l & 0xff00000000000000LL)
+ {
+ return(bits[(int)(l>>56)]+56);
+ }
+ else return(bits[(int)(l>>48)]+48);
+ }
+ else
+ {
+ if (l & 0x0000ff0000000000LL)
+ {
+ return(bits[(int)(l>>40)]+40);
+ }
+ else return(bits[(int)(l>>32)]+32);
+ }
+ }
+ else
+#endif
+#endif
+ {
+#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
+ if (l & 0xffff0000L)
+ {
+ if (l & 0xff000000L)
+ return(bits[(int)(l>>24L)]+24);
+ else return(bits[(int)(l>>16L)]+16);
+ }
+ else
+#endif
+ {
+#if defined(SIXTEEN_BIT) || defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
+ if (l & 0xff00L)
+ return(bits[(int)(l>>8)]+8);
+ else
+#endif
+ return(bits[(int)(l )] );
+ }
+ }
+ }
+
+int BN_num_bits(const BIGNUM *a)
+ {
+ BN_ULONG l;
+ int i;
+
+ bn_check_top(a);
+
+ if (a->top == 0) return(0);
+ l=a->d[a->top-1];
+ i=(a->top-1)*BN_BITS2;
+ if (l == 0)
+ {
+#if !defined(NO_STDIO) && !defined(WIN16)
+ fprintf(stderr,"BAD TOP VALUE\n");
+#endif
+ abort();
+ }
+ return(i+BN_num_bits_word(l));
+ }
+
+void BN_clear_free(BIGNUM *a)
+ {
+ int i;
+
+ if (a == NULL) return;
+ if (a->d != NULL)
+ {
+ memset(a->d,0,a->max*sizeof(a->d[0]));
+ if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
+ Free(a->d);
+ }
+ i=BN_get_flags(a,BN_FLG_MALLOCED);
+ memset(a,0,sizeof(BIGNUM));
+ if (i)
+ Free(a);
+ }
+
+void BN_free(BIGNUM *a)
+ {
+ if (a == NULL) return;
+ if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA)))
+ Free(a->d);
+ a->flags|=BN_FLG_FREE; /* REMOVE? */
+ if (a->flags & BN_FLG_MALLOCED)
+ Free(a);
+ }
+
+void BN_init(BIGNUM *a)
+ {
+ memset(a,0,sizeof(BIGNUM));
+ }
+
+BIGNUM *BN_new(void)
+ {
+ BIGNUM *ret;
+
+ if ((ret=(BIGNUM *)Malloc(sizeof(BIGNUM))) == NULL)
+ {
+ BNerr(BN_F_BN_NEW,ERR_R_MALLOC_FAILURE);
+ return(NULL);
+ }
+ ret->flags=BN_FLG_MALLOCED;
+ ret->top=0;
+ ret->neg=0;
+ ret->max=0;
+ ret->d=NULL;
+ return(ret);
+ }
+
+
+BN_CTX *BN_CTX_new(void)
+ {
+ BN_CTX *ret;
+
+ ret=(BN_CTX *)Malloc(sizeof(BN_CTX));
+ if (ret == NULL)
+ {
+ BNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE);
+ return(NULL);
+ }
+
+ BN_CTX_init(ret);
+ ret->flags=BN_FLG_MALLOCED;
+ return(ret);
+ }
+
+void BN_CTX_init(BN_CTX *ctx)
+ {
+ memset(ctx,0,sizeof(BN_CTX));
+ ctx->tos=0;
+ ctx->flags=0;
+ }
+
+void BN_CTX_free(BN_CTX *c)
+ {
+ int i;
+
+ if(c == NULL)
+ return;
+
+ for (i=0; i<BN_CTX_NUM; i++)
+ BN_clear_free(&(c->bn[i]));
+ if (c->flags & BN_FLG_MALLOCED)
+ Free(c);
+ }
+
+BIGNUM *bn_expand2(BIGNUM *b, int words)
+ {
+ BN_ULONG *A,*a;
+ const BN_ULONG *B;
+ int i;
+
+ bn_check_top(b);
+
+ if (words > b->max)
+ {
+ bn_check_top(b);
+ if (BN_get_flags(b,BN_FLG_STATIC_DATA))
+ {
+ BNerr(BN_F_BN_EXPAND2,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
+ return(NULL);
+ }
+ a=A=(BN_ULONG *)Malloc(sizeof(BN_ULONG)*(words+1));
+ if (A == NULL)
+ {
+ BNerr(BN_F_BN_EXPAND2,ERR_R_MALLOC_FAILURE);
+ return(NULL);
+ }
+#if 1
+ B=b->d;
+ /* Check if the previous number needs to be copied */
+ if (B != NULL)
+ {
+#if 0
+ /* This lot is an unrolled loop to copy b->top
+ * BN_ULONGs from B to A
+ */
+/*
+ * I have nothing against unrolling but it's usually done for
+ * several reasons, namely:
+ * - minimize percentage of decision making code, i.e. branches;
+ * - avoid cache trashing;
+ * - make it possible to schedule loads earlier;
+ * Now let's examine the code below. The cornerstone of C is
+ * "programmer is always right" and that's what we love it for:-)
+ * For this very reason C compilers have to be paranoid when it
+ * comes to data aliasing and assume the worst. Yeah, but what
+ * does it mean in real life? This means that loop body below will
+ * be compiled to sequence of loads immediately followed by stores
+ * as compiler assumes the worst, something in A==B+1 style. As a
+ * result CPU pipeline is going to starve for incoming data. Secondly
+ * if A and B happen to share same cache line such code is going to
+ * cause severe cache trashing. Both factors have severe impact on
+ * performance of modern CPUs and this is the reason why this
+ * particulare piece of code is #ifdefed away and replaced by more
+ * "friendly" version found in #else section below. This comment
+ * also applies to BN_copy function.
+ *
+ * <appro@fy.chalmers.se>
+ */
+ for (i=b->top&(~7); i>0; i-=8)
+ {
+ A[0]=B[0]; A[1]=B[1]; A[2]=B[2]; A[3]=B[3];
+ A[4]=B[4]; A[5]=B[5]; A[6]=B[6]; A[7]=B[7];
+ A+=8;
+ B+=8;
+ }
+ switch (b->top&7)
+ {
+ case 7:
+ A[6]=B[6];
+ case 6:
+ A[5]=B[5];
+ case 5:
+ A[4]=B[4];
+ case 4:
+ A[3]=B[3];
+ case 3:
+ A[2]=B[2];
+ case 2:
+ A[1]=B[1];
+ case 1:
+ A[0]=B[0];
+ case 0:
+ /* I need the 'case 0' entry for utrix cc.
+ * If the optimiser is turned on, it does the
+ * switch table by doing
+ * a=top&7
+ * a--;
+ * goto jump_table[a];
+ * If top is 0, this makes us jump to 0xffffffc
+ * which is rather bad :-(.
+ * eric 23-Apr-1998
+ */
+ ;
+ }
+#else
+ for (i=b->top>>2; i>0; i--,A+=4,B+=4)
+ {
+ /*
+ * The fact that the loop is unrolled
+ * 4-wise is a tribute to Intel. It's
+ * the one that doesn't have enough
+ * registers to accomodate more data.
+ * I'd unroll it 8-wise otherwise:-)
+ *
+ * <appro@fy.chalmers.se>
+ */
+ BN_ULONG a0,a1,a2,a3;
+ a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
+ A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
+ }
+ switch (b->top&3)
+ {
+ case 3: A[2]=B[2];
+ case 2: A[1]=B[1];
+ case 1: A[0]=B[0];
+ case 0: ; /* ultrix cc workaround, see above */
+ }
+#endif
+ Free(b->d);
+ }
+
+ b->d=a;
+ b->max=words;
+
+ /* Now need to zero any data between b->top and b->max */
+
+ A= &(b->d[b->top]);
+ for (i=(b->max - b->top)>>3; i>0; i--,A+=8)
+ {
+ A[0]=0; A[1]=0; A[2]=0; A[3]=0;
+ A[4]=0; A[5]=0; A[6]=0; A[7]=0;
+ }
+ for (i=(b->max - b->top)&7; i>0; i--,A++)
+ A[0]=0;
+#else
+ memset(A,0,sizeof(BN_ULONG)*(words+1));
+ memcpy(A,b->d,sizeof(b->d[0])*b->top);
+ b->d=a;
+ b->max=words;
+#endif
+
+/* memset(&(p[b->max]),0,((words+1)-b->max)*sizeof(BN_ULONG)); */
+/* { int i; for (i=b->max; i<words+1; i++) p[i]=i;} */
+
+ }
+ return(b);
+ }
+
+BIGNUM *BN_dup(const BIGNUM *a)
+ {
+ BIGNUM *r;
+
+ if (a == NULL) return NULL;
+
+ bn_check_top(a);
+
+ r=BN_new();
+ if (r == NULL) return(NULL);
+ return((BIGNUM *)BN_copy(r,a));
+ }
+
+BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
+ {
+ int i;
+ BN_ULONG *A;
+ const BN_ULONG *B;
+
+ bn_check_top(b);
+
+ if (a == b) return(a);
+ if (bn_wexpand(a,b->top) == NULL) return(NULL);
+
+#if 1
+ A=a->d;
+ B=b->d;
+ for (i=b->top>>2; i>0; i--,A+=4,B+=4)
+ {
+ BN_ULONG a0,a1,a2,a3;
+ a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
+ A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
+ }
+ switch (b->top&3)
+ {
+ case 3: A[2]=B[2];
+ case 2: A[1]=B[1];
+ case 1: A[0]=B[0];
+ case 0: ; /* ultrix cc workaround, see comments in bn_expand2 */
+ }
+#else
+ memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
+#endif
+
+/* memset(&(a->d[b->top]),0,sizeof(a->d[0])*(a->max-b->top));*/
+ a->top=b->top;
+ if ((a->top == 0) && (a->d != NULL))
+ a->d[0]=0;
+ a->neg=b->neg;
+ return(a);
+ }
+
+void BN_clear(BIGNUM *a)
+ {
+ if (a->d != NULL)
+ memset(a->d,0,a->max*sizeof(a->d[0]));
+ a->top=0;
+ a->neg=0;
+ }
+
+BN_ULONG BN_get_word(BIGNUM *a)
+ {
+ int i,n;
+ BN_ULONG ret=0;
+
+ n=BN_num_bytes(a);
+ if ((unsigned int)n > sizeof(BN_ULONG))
+ return(BN_MASK2);
+ for (i=a->top-1; i>=0; i--)
+ {
+#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
+ ret<<=BN_BITS4; /* stops the compiler complaining */
+ ret<<=BN_BITS4;
+#else
+ ret=0;
+#endif
+ ret|=a->d[i];
+ }
+ return(ret);
+ }
+
+int BN_set_word(BIGNUM *a, BN_ULONG w)
+ {
+ int i,n;
+ if (bn_expand(a,(int)sizeof(BN_ULONG)*8) == NULL) return(0);
+
+ n=sizeof(BN_ULONG)/BN_BYTES;
+ a->neg=0;
+ a->top=0;
+ a->d[0]=(BN_ULONG)w&BN_MASK2;
+ if (a->d[0] != 0) a->top=1;
+ for (i=1; i<n; i++)
+ {
+ /* the following is done instead of
+ * w>>=BN_BITS2 so compilers don't complain
+ * on builds where sizeof(long) == BN_TYPES */
+#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
+ w>>=BN_BITS4;
+ w>>=BN_BITS4;
+#else
+ w=0;
+#endif
+ a->d[i]=(BN_ULONG)w&BN_MASK2;
+ if (a->d[i] != 0) a->top=i+1;
+ }
+ return(1);
+ }
+
+/* ignore negative */
+BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
+ {
+ unsigned int i,m;
+ unsigned int n;
+ BN_ULONG l;
+
+ if (ret == NULL) ret=BN_new();
+ if (ret == NULL) return(NULL);
+ l=0;
+ n=len;
+ if (n == 0)
+ {
+ ret->top=0;
+ return(ret);
+ }
+ if (bn_expand(ret,(int)(n+2)*8) == NULL)
+ return(NULL);
+ i=((n-1)/BN_BYTES)+1;
+ m=((n-1)%(BN_BYTES));
+ ret->top=i;
+ while (n-- > 0)
+ {
+ l=(l<<8L)| *(s++);
+ if (m-- == 0)
+ {
+ ret->d[--i]=l;
+ l=0;
+ m=BN_BYTES-1;
+ }
+ }
+ /* need to call this due to clear byte at top if avoiding
+ * having the top bit set (-ve number) */
+ bn_fix_top(ret);
+ return(ret);
+ }
+
+/* ignore negative */
+int BN_bn2bin(const BIGNUM *a, unsigned char *to)
+ {
+ int n,i;
+ BN_ULONG l;
+
+ n=i=BN_num_bytes(a);
+ while (i-- > 0)
+ {
+ l=a->d[i/BN_BYTES];
+ *(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
+ }
+ return(n);
+ }
+
+int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
+ {
+ int i;
+ BN_ULONG t1,t2,*ap,*bp;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ i=a->top-b->top;
+ if (i != 0) return(i);
+ ap=a->d;
+ bp=b->d;
+ for (i=a->top-1; i>=0; i--)
+ {
+ t1= ap[i];
+ t2= bp[i];
+ if (t1 != t2)
+ return(t1 > t2?1:-1);
+ }
+ return(0);
+ }
+
+int BN_cmp(const BIGNUM *a, const BIGNUM *b)
+ {
+ int i;
+ int gt,lt;
+ BN_ULONG t1,t2;
+
+ if ((a == NULL) || (b == NULL))
+ {
+ if (a != NULL)
+ return(-1);
+ else if (b != NULL)
+ return(1);
+ else
+ return(0);
+ }
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ if (a->neg != b->neg)
+ {
+ if (a->neg)
+ return(-1);
+ else return(1);
+ }
+ if (a->neg == 0)
+ { gt=1; lt= -1; }
+ else { gt= -1; lt=1; }
+
+ if (a->top > b->top) return(gt);
+ if (a->top < b->top) return(lt);
+ for (i=a->top-1; i>=0; i--)
+ {
+ t1=a->d[i];
+ t2=b->d[i];
+ if (t1 > t2) return(gt);
+ if (t1 < t2) return(lt);
+ }
+ return(0);
+ }
+
+int BN_set_bit(BIGNUM *a, int n)
+ {
+ int i,j,k;
+
+ i=n/BN_BITS2;
+ j=n%BN_BITS2;
+ if (a->top <= i)
+ {
+ if (bn_wexpand(a,i+1) == NULL) return(0);
+ for(k=a->top; k<i+1; k++)
+ a->d[k]=0;
+ a->top=i+1;
+ }
+
+ a->d[i]|=(((BN_ULONG)1)<<j);
+ return(1);
+ }
+
+int BN_clear_bit(BIGNUM *a, int n)
+ {
+ int i,j;
+
+ i=n/BN_BITS2;
+ j=n%BN_BITS2;
+ if (a->top <= i) return(0);
+
+ a->d[i]&=(~(((BN_ULONG)1)<<j));
+ bn_fix_top(a);
+ return(1);
+ }
+
+int BN_is_bit_set(const BIGNUM *a, int n)
+ {
+ int i,j;
+
+ if (n < 0) return(0);
+ i=n/BN_BITS2;
+ j=n%BN_BITS2;
+ if (a->top <= i) return(0);
+ return((a->d[i]&(((BN_ULONG)1)<<j))?1:0);
+ }
+
+int BN_mask_bits(BIGNUM *a, int n)
+ {
+ int b,w;
+
+ w=n/BN_BITS2;
+ b=n%BN_BITS2;
+ if (w >= a->top) return(0);
+ if (b == 0)
+ a->top=w;
+ else
+ {
+ a->top=w+1;
+ a->d[w]&= ~(BN_MASK2<<b);
+ }
+ bn_fix_top(a);
+ return(1);
+ }
+
+int bn_cmp_words(BN_ULONG *a, BN_ULONG *b, int n)
+ {
+ int i;
+ BN_ULONG aa,bb;
+
+ aa=a[n-1];
+ bb=b[n-1];
+ if (aa != bb) return((aa > bb)?1:-1);
+ for (i=n-2; i>=0; i--)
+ {
+ aa=a[i];
+ bb=b[i];
+ if (aa != bb) return((aa > bb)?1:-1);
+ }
+ return(0);
+ }
+
diff --git a/lib/dns/sec/openssl/bn_mont.c b/lib/dns/sec/openssl/bn_mont.c
new file mode 100644
index 00000000..ee0f410c
--- /dev/null
+++ b/lib/dns/sec/openssl/bn_mont.c
@@ -0,0 +1,407 @@
+/* crypto/bn/bn_mont.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/*
+ * Details about Montgomery multiplication algorithms can be found at:
+ * http://www.ece.orst.edu/ISL/Publications.html
+ * http://www.ece.orst.edu/ISL/Koc/papers/j37acmon.pdf
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+#define MONT_WORD
+
+int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b,
+ BN_MONT_CTX *mont, BN_CTX *ctx)
+ {
+ BIGNUM *tmp,*tmp2;
+
+ tmp= &(ctx->bn[ctx->tos]);
+ tmp2= &(ctx->bn[ctx->tos]);
+ ctx->tos+=2;
+
+ bn_check_top(tmp);
+ bn_check_top(tmp2);
+
+ if (a == b)
+ {
+#if 0
+ bn_wexpand(tmp,a->top*2);
+ bn_wexpand(tmp2,a->top*4);
+ bn_sqr_recursive(tmp->d,a->d,a->top,tmp2->d);
+ tmp->top=a->top*2;
+ if (tmp->d[tmp->top-1] == 0)
+ tmp->top--;
+#else
+ if (!BN_sqr(tmp,a,ctx)) goto err;
+#endif
+ }
+ else
+ {
+ if (!BN_mul(tmp,a,b,ctx)) goto err;
+ }
+ /* reduce from aRR to aR */
+ if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err;
+ ctx->tos-=2;
+ return(1);
+err:
+ return(0);
+ }
+
+int BN_from_montgomery(BIGNUM *ret, BIGNUM *a, BN_MONT_CTX *mont,
+ BN_CTX *ctx)
+ {
+#ifdef BN_RECURSION_MONT
+ if (mont->use_word)
+#endif
+ {
+ BIGNUM *n,*r;
+ BN_ULONG *ap,*np,*rp,n0,v,*nrp;
+ int al,nl,max,i,x,ri;
+ int retn=0;
+
+ r= &(ctx->bn[ctx->tos]);
+
+ if (!BN_copy(r,a)) goto err1;
+ n= &(mont->N);
+
+ ap=a->d;
+ /* mont->ri is the size of mont->N in bits/words */
+ al=ri=mont->ri/BN_BITS2;
+
+ nl=n->top;
+ if ((al == 0) || (nl == 0)) { r->top=0; return(1); }
+
+ max=(nl+al+1); /* allow for overflow (no?) XXX */
+ if (bn_wexpand(r,max) == NULL) goto err1;
+ if (bn_wexpand(ret,max) == NULL) goto err1;
+
+ r->neg=a->neg^n->neg;
+ np=n->d;
+ rp=r->d;
+ nrp= &(r->d[nl]);
+
+ /* clear the top words of T */
+#if 1
+ for (i=r->top; i<max; i++) /* memset? XXX */
+ r->d[i]=0;
+#else
+ memset(&(r->d[r->top]),0,(max-r->top)*sizeof(BN_ULONG));
+#endif
+
+ r->top=max;
+ n0=mont->n0;
+
+#ifdef BN_COUNT
+printf("word BN_from_montgomery %d * %d\n",nl,nl);
+#endif
+ for (i=0; i<nl; i++)
+ {
+ v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
+ nrp++;
+ rp++;
+ if (((nrp[-1]+=v)&BN_MASK2) >= v)
+ continue;
+ else
+ {
+ if (((++nrp[0])&BN_MASK2) != 0) continue;
+ if (((++nrp[1])&BN_MASK2) != 0) continue;
+ for (x=2; (((++nrp[x])&BN_MASK2) == 0); x++) ;
+ }
+ }
+ bn_fix_top(r);
+
+ /* mont->ri will be a multiple of the word size */
+#if 0
+ BN_rshift(ret,r,mont->ri);
+#else
+ x=ri;
+ rp=ret->d;
+ ap= &(r->d[x]);
+ if (r->top < x)
+ al=0;
+ else
+ al=r->top-x;
+ ret->top=al;
+ al-=4;
+ for (i=0; i<al; i+=4)
+ {
+ BN_ULONG t1,t2,t3,t4;
+
+ t1=ap[i+0];
+ t2=ap[i+1];
+ t3=ap[i+2];
+ t4=ap[i+3];
+ rp[i+0]=t1;
+ rp[i+1]=t2;
+ rp[i+2]=t3;
+ rp[i+3]=t4;
+ }
+ al+=4;
+ for (; i<al; i++)
+ rp[i]=ap[i];
+#endif
+
+ if (BN_ucmp(ret, &(mont->N)) >= 0)
+ {
+ BN_usub(ret,ret,&(mont->N)); /* XXX */
+ }
+ retn=1;
+err1:
+ return(retn);
+ }
+#ifdef BN_RECURSION_MONT
+ else /* bignum version */
+ {
+ BIGNUM *t1,*t2,*t3;
+ int j,i;
+
+#ifdef BN_COUNT
+printf("number BN_from_montgomery\n");
+#endif
+
+ t1= &(ctx->bn[ctx->tos]);
+ t2= &(ctx->bn[ctx->tos+1]);
+ t3= &(ctx->bn[ctx->tos+2]);
+
+ i=mont->Ni.top;
+ bn_wexpand(ret,i); /* perhaps only i*2 */
+ bn_wexpand(t1,i*4); /* perhaps only i*2 */
+ bn_wexpand(t2,i*2); /* perhaps only i */
+
+ bn_mul_low_recursive(t2->d,a->d,mont->Ni.d,i,t1->d);
+
+ BN_zero(t3);
+ BN_set_bit(t3,mont->N.top*BN_BITS2);
+ bn_sub_words(t3->d,t3->d,a->d,i);
+ bn_mul_high(ret->d,t2->d,mont->N.d,t3->d,i,t1->d);
+
+ /* hmm... if a is between i and 2*i, things are bad */
+ if (a->top > i)
+ {
+ j=(int)(bn_add_words(ret->d,ret->d,&(a->d[i]),i));
+ if (j) /* overflow */
+ bn_sub_words(ret->d,ret->d,mont->N.d,i);
+ }
+ ret->top=i;
+ bn_fix_top(ret);
+ if (a->d[0])
+ BN_add_word(ret,1); /* Always? */
+ else /* Very very rare */
+ {
+ for (i=1; i<mont->N.top-1; i++)
+ {
+ if (a->d[i])
+ {
+ BN_add_word(ret,1); /* Always? */
+ break;
+ }
+ }
+ }
+
+ if (BN_ucmp(ret,&(mont->N)) >= 0)
+ BN_usub(ret,ret,&(mont->N));
+
+ return(1);
+ }
+#endif
+ }
+
+BN_MONT_CTX *BN_MONT_CTX_new(void)
+ {
+ BN_MONT_CTX *ret;
+
+ if ((ret=(BN_MONT_CTX *)Malloc(sizeof(BN_MONT_CTX))) == NULL)
+ return(NULL);
+
+ BN_MONT_CTX_init(ret);
+ ret->flags=BN_FLG_MALLOCED;
+ return(ret);
+ }
+
+void BN_MONT_CTX_init(BN_MONT_CTX *ctx)
+ {
+ ctx->use_word=0;
+ ctx->ri=0;
+ BN_init(&(ctx->RR));
+ BN_init(&(ctx->N));
+ BN_init(&(ctx->Ni));
+ ctx->flags=0;
+ }
+
+void BN_MONT_CTX_free(BN_MONT_CTX *mont)
+ {
+ if(mont == NULL)
+ return;
+
+ BN_free(&(mont->RR));
+ BN_free(&(mont->N));
+ BN_free(&(mont->Ni));
+ if (mont->flags & BN_FLG_MALLOCED)
+ Free(mont);
+ }
+
+int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
+ {
+ BIGNUM Ri,*R;
+
+ BN_init(&Ri);
+ R= &(mont->RR); /* grab RR as a temp */
+ BN_copy(&(mont->N),mod); /* Set N */
+
+#ifdef BN_RECURSION_MONT
+ if (mont->N.top < BN_MONT_CTX_SET_SIZE_WORD)
+#endif
+ {
+ BIGNUM tmod;
+ BN_ULONG buf[2];
+
+ mont->use_word=1;
+
+ mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
+ BN_zero(R);
+ BN_set_bit(R,BN_BITS2);
+ /* I was bad, this modification of a passed variable was
+ * breaking the multithreaded stuff :-(
+ * z=mod->top;
+ * mod->top=1; */
+
+ buf[0]=mod->d[0];
+ buf[1]=0;
+ tmod.d=buf;
+ tmod.top=1;
+ tmod.max=mod->max;
+ tmod.neg=mod->neg;
+
+ if ((BN_mod_inverse(&Ri,R,&tmod,ctx)) == NULL)
+ goto err;
+ BN_lshift(&Ri,&Ri,BN_BITS2); /* R*Ri */
+ if (!BN_is_zero(&Ri))
+ {
+#if 1
+ BN_sub_word(&Ri,1);
+#else
+ BN_usub(&Ri,&Ri,BN_value_one()); /* R*Ri - 1 */
+#endif
+ }
+ else
+ {
+ /* This is not common..., 1 in BN_MASK2,
+ * It happens when buf[0] was == 1. So for 8 bit,
+ * this is 1/256, 16bit, 1 in 2^16 etc.
+ */
+ BN_set_word(&Ri,BN_MASK2);
+ }
+ BN_div(&Ri,NULL,&Ri,&tmod,ctx);
+ mont->n0=Ri.d[0];
+ BN_free(&Ri);
+ /* mod->top=z; */
+ }
+#ifdef BN_RECURSION_MONT
+ else
+ {
+ mont->use_word=0;
+ mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
+#if 1
+ BN_zero(R);
+ BN_set_bit(R,mont->ri);
+#else
+ BN_lshift(R,BN_value_one(),mont->ri); /* R */
+#endif
+ if ((BN_mod_inverse(&Ri,R,mod,ctx)) == NULL)
+ goto err;
+ BN_lshift(&Ri,&Ri,mont->ri); /* R*Ri */
+#if 1
+ BN_sub_word(&Ri,1);
+#else
+ BN_usub(&Ri,&Ri,BN_value_one()); /* R*Ri - 1 */
+#endif
+ BN_div(&(mont->Ni),NULL,&Ri,mod,ctx);
+ BN_free(&Ri);
+ }
+#endif
+
+ /* setup RR for conversions */
+#if 1
+ BN_zero(&(mont->RR));
+ BN_set_bit(&(mont->RR),mont->ri*2);
+#else
+ BN_lshift(mont->RR,BN_value_one(),mont->ri*2);
+#endif
+ BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx);
+
+ return(1);
+err:
+ return(0);
+ }
+
+BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from)
+ {
+ if (to == from) return(to);
+
+ BN_copy(&(to->RR),&(from->RR));
+ BN_copy(&(to->N),&(from->N));
+ BN_copy(&(to->Ni),&(from->Ni));
+ to->use_word=from->use_word;
+ to->ri=from->ri;
+ to->n0=from->n0;
+ return(to);
+ }
+
diff --git a/lib/dns/sec/openssl/bn_mul.c b/lib/dns/sec/openssl/bn_mul.c
new file mode 100644
index 00000000..38c47f3d
--- /dev/null
+++ b/lib/dns/sec/openssl/bn_mul.c
@@ -0,0 +1,756 @@
+/* crypto/bn/bn_mul.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+#ifdef BN_RECURSION
+/* r is 2*n2 words in size,
+ * a and b are both n2 words in size.
+ * n2 must be a power of 2.
+ * We multiply and return the result.
+ * t must be 2*n2 words in size
+ * We calulate
+ * a[0]*b[0]
+ * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
+ * a[1]*b[1]
+ */
+void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
+ BN_ULONG *t)
+ {
+ int n=n2/2,c1,c2;
+ unsigned int neg,zero;
+ BN_ULONG ln,lo,*p;
+
+#ifdef BN_COUNT
+printf(" bn_mul_recursive %d * %d\n",n2,n2);
+#endif
+#ifdef BN_MUL_COMBA
+/* if (n2 == 4)
+ {
+ bn_mul_comba4(r,a,b);
+ return;
+ }
+ else */ if (n2 == 8)
+ {
+ bn_mul_comba8(r,a,b);
+ return;
+ }
+#endif
+ if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL)
+ {
+ /* This should not happen */
+ bn_mul_normal(r,a,n2,b,n2);
+ return;
+ }
+ /* r=(a[0]-a[1])*(b[1]-b[0]) */
+ c1=bn_cmp_words(a,&(a[n]),n);
+ c2=bn_cmp_words(&(b[n]),b,n);
+ zero=neg=0;
+ switch (c1*3+c2)
+ {
+ case -4:
+ bn_sub_words(t, &(a[n]),a, n); /* - */
+ bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */
+ break;
+ case -3:
+ zero=1;
+ break;
+ case -2:
+ bn_sub_words(t, &(a[n]),a, n); /* - */
+ bn_sub_words(&(t[n]),&(b[n]),b, n); /* + */
+ neg=1;
+ break;
+ case -1:
+ case 0:
+ case 1:
+ zero=1;
+ break;
+ case 2:
+ bn_sub_words(t, a, &(a[n]),n); /* + */
+ bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */
+ neg=1;
+ break;
+ case 3:
+ zero=1;
+ break;
+ case 4:
+ bn_sub_words(t, a, &(a[n]),n);
+ bn_sub_words(&(t[n]),&(b[n]),b, n);
+ break;
+ }
+
+#ifdef BN_MUL_COMBA
+ if (n == 4)
+ {
+ if (!zero)
+ bn_mul_comba4(&(t[n2]),t,&(t[n]));
+ else
+ memset(&(t[n2]),0,8*sizeof(BN_ULONG));
+
+ bn_mul_comba4(r,a,b);
+ bn_mul_comba4(&(r[n2]),&(a[n]),&(b[n]));
+ }
+ else if (n == 8)
+ {
+ if (!zero)
+ bn_mul_comba8(&(t[n2]),t,&(t[n]));
+ else
+ memset(&(t[n2]),0,16*sizeof(BN_ULONG));
+
+ bn_mul_comba8(r,a,b);
+ bn_mul_comba8(&(r[n2]),&(a[n]),&(b[n]));
+ }
+ else
+#endif
+ {
+ p= &(t[n2*2]);
+ if (!zero)
+ bn_mul_recursive(&(t[n2]),t,&(t[n]),n,p);
+ else
+ memset(&(t[n2]),0,n2*sizeof(BN_ULONG));
+ bn_mul_recursive(r,a,b,n,p);
+ bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),n,p);
+ }
+
+ /* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
+ * r[10] holds (a[0]*b[0])
+ * r[32] holds (b[1]*b[1])
+ */
+
+ c1=(int)(bn_add_words(t,r,&(r[n2]),n2));
+
+ if (neg) /* if t[32] is negative */
+ {
+ c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2));
+ }
+ else
+ {
+ /* Might have a carry */
+ c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),t,n2));
+ }
+
+ /* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
+ * r[10] holds (a[0]*b[0])
+ * r[32] holds (b[1]*b[1])
+ * c1 holds the carry bits
+ */
+ c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2));
+ if (c1)
+ {
+ p= &(r[n+n2]);
+ lo= *p;
+ ln=(lo+c1)&BN_MASK2;
+ *p=ln;
+
+ /* The overflow will stop before we over write
+ * words we should not overwrite */
+ if (ln < (BN_ULONG)c1)
+ {
+ do {
+ p++;
+ lo= *p;
+ ln=(lo+1)&BN_MASK2;
+ *p=ln;
+ } while (ln == 0);
+ }
+ }
+ }
+
+/* n+tn is the word length
+ * t needs to be n*4 is size, as does r */
+void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int tn,
+ int n, BN_ULONG *t)
+ {
+ int i,j,n2=n*2;
+ unsigned int c1;
+ BN_ULONG ln,lo,*p;
+
+#ifdef BN_COUNT
+printf(" bn_mul_part_recursive %d * %d\n",tn+n,tn+n);
+#endif
+ if (n < 8)
+ {
+ i=tn+n;
+ bn_mul_normal(r,a,i,b,i);
+ return;
+ }
+
+ /* r=(a[0]-a[1])*(b[1]-b[0]) */
+ bn_sub_words(t, a, &(a[n]),n); /* + */
+ bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */
+
+/* if (n == 4)
+ {
+ bn_mul_comba4(&(t[n2]),t,&(t[n]));
+ bn_mul_comba4(r,a,b);
+ bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn);
+ memset(&(r[n2+tn*2]),0,sizeof(BN_ULONG)*(n2-tn*2));
+ }
+ else */ if (n == 8)
+ {
+ bn_mul_comba8(&(t[n2]),t,&(t[n]));
+ bn_mul_comba8(r,a,b);
+ bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn);
+ memset(&(r[n2+tn*2]),0,sizeof(BN_ULONG)*(n2-tn*2));
+ }
+ else
+ {
+ p= &(t[n2*2]);
+ bn_mul_recursive(&(t[n2]),t,&(t[n]),n,p);
+ bn_mul_recursive(r,a,b,n,p);
+ i=n/2;
+ /* If there is only a bottom half to the number,
+ * just do it */
+ j=tn-i;
+ if (j == 0)
+ {
+ bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),i,p);
+ memset(&(r[n2+i*2]),0,sizeof(BN_ULONG)*(n2-i*2));
+ }
+ else if (j > 0) /* eg, n == 16, i == 8 and tn == 11 */
+ {
+ bn_mul_part_recursive(&(r[n2]),&(a[n]),&(b[n]),
+ j,i,p);
+ memset(&(r[n2+tn*2]),0,
+ sizeof(BN_ULONG)*(n2-tn*2));
+ }
+ else /* (j < 0) eg, n == 16, i == 8 and tn == 5 */
+ {
+ memset(&(r[n2]),0,sizeof(BN_ULONG)*n2);
+ if (tn < BN_MUL_RECURSIVE_SIZE_NORMAL)
+ {
+ bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn);
+ }
+ else
+ {
+ for (;;)
+ {
+ i/=2;
+ if (i < tn)
+ {
+ bn_mul_part_recursive(&(r[n2]),
+ &(a[n]),&(b[n]),
+ tn-i,i,p);
+ break;
+ }
+ else if (i == tn)
+ {
+ bn_mul_recursive(&(r[n2]),
+ &(a[n]),&(b[n]),
+ i,p);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
+ * r[10] holds (a[0]*b[0])
+ * r[32] holds (b[1]*b[1])
+ */
+
+ c1=(int)(bn_add_words(t,r,&(r[n2]),n2));
+ c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2));
+
+ /* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
+ * r[10] holds (a[0]*b[0])
+ * r[32] holds (b[1]*b[1])
+ * c1 holds the carry bits
+ */
+ c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2));
+ if (c1)
+ {
+ p= &(r[n+n2]);
+ lo= *p;
+ ln=(lo+c1)&BN_MASK2;
+ *p=ln;
+
+ /* The overflow will stop before we over write
+ * words we should not overwrite */
+ if (ln < c1)
+ {
+ do {
+ p++;
+ lo= *p;
+ ln=(lo+1)&BN_MASK2;
+ *p=ln;
+ } while (ln == 0);
+ }
+ }
+ }
+
+/* a and b must be the same size, which is n2.
+ * r needs to be n2 words and t needs to be n2*2
+ */
+void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
+ BN_ULONG *t)
+ {
+ int n=n2/2;
+
+#ifdef BN_COUNT
+printf(" bn_mul_low_recursive %d * %d\n",n2,n2);
+#endif
+
+ bn_mul_recursive(r,a,b,n,&(t[0]));
+ if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL)
+ {
+ bn_mul_low_recursive(&(t[0]),&(a[0]),&(b[n]),n,&(t[n2]));
+ bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
+ bn_mul_low_recursive(&(t[0]),&(a[n]),&(b[0]),n,&(t[n2]));
+ bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
+ }
+ else
+ {
+ bn_mul_low_normal(&(t[0]),&(a[0]),&(b[n]),n);
+ bn_mul_low_normal(&(t[n]),&(a[n]),&(b[0]),n);
+ bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
+ bn_add_words(&(r[n]),&(r[n]),&(t[n]),n);
+ }
+ }
+
+/* a and b must be the same size, which is n2.
+ * r needs to be n2 words and t needs to be n2*2
+ * l is the low words of the output.
+ * t needs to be n2*3
+ */
+void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
+ BN_ULONG *t)
+ {
+ int i,n;
+ int c1,c2;
+ int neg,oneg,zero;
+ BN_ULONG ll,lc,*lp,*mp;
+
+#ifdef BN_COUNT
+printf(" bn_mul_high %d * %d\n",n2,n2);
+#endif
+ n=n2/2;
+
+ /* Calculate (al-ah)*(bh-bl) */
+ neg=zero=0;
+ c1=bn_cmp_words(&(a[0]),&(a[n]),n);
+ c2=bn_cmp_words(&(b[n]),&(b[0]),n);
+ switch (c1*3+c2)
+ {
+ case -4:
+ bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n);
+ bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n);
+ break;
+ case -3:
+ zero=1;
+ break;
+ case -2:
+ bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n);
+ bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n);
+ neg=1;
+ break;
+ case -1:
+ case 0:
+ case 1:
+ zero=1;
+ break;
+ case 2:
+ bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n);
+ bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n);
+ neg=1;
+ break;
+ case 3:
+ zero=1;
+ break;
+ case 4:
+ bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n);
+ bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n);
+ break;
+ }
+
+ oneg=neg;
+ /* t[10] = (a[0]-a[1])*(b[1]-b[0]) */
+ /* r[10] = (a[1]*b[1]) */
+#ifdef BN_MUL_COMBA
+ if (n == 8)
+ {
+ bn_mul_comba8(&(t[0]),&(r[0]),&(r[n]));
+ bn_mul_comba8(r,&(a[n]),&(b[n]));
+ }
+ else
+#endif
+ {
+ bn_mul_recursive(&(t[0]),&(r[0]),&(r[n]),n,&(t[n2]));
+ bn_mul_recursive(r,&(a[n]),&(b[n]),n,&(t[n2]));
+ }
+
+ /* s0 == low(al*bl)
+ * s1 == low(ah*bh)+low((al-ah)*(bh-bl))+low(al*bl)+high(al*bl)
+ * We know s0 and s1 so the only unknown is high(al*bl)
+ * high(al*bl) == s1 - low(ah*bh+s0+(al-ah)*(bh-bl))
+ * high(al*bl) == s1 - (r[0]+l[0]+t[0])
+ */
+ if (l != NULL)
+ {
+ lp= &(t[n2+n]);
+ c1=(int)(bn_add_words(lp,&(r[0]),&(l[0]),n));
+ }
+ else
+ {
+ c1=0;
+ lp= &(r[0]);
+ }
+
+ if (neg)
+ neg=(int)(bn_sub_words(&(t[n2]),lp,&(t[0]),n));
+ else
+ {
+ bn_add_words(&(t[n2]),lp,&(t[0]),n);
+ neg=0;
+ }
+
+ if (l != NULL)
+ {
+ bn_sub_words(&(t[n2+n]),&(l[n]),&(t[n2]),n);
+ }
+ else
+ {
+ lp= &(t[n2+n]);
+ mp= &(t[n2]);
+ for (i=0; i<n; i++)
+ lp[i]=((~mp[i])+1)&BN_MASK2;
+ }
+
+ /* s[0] = low(al*bl)
+ * t[3] = high(al*bl)
+ * t[10] = (a[0]-a[1])*(b[1]-b[0]) neg is the sign
+ * r[10] = (a[1]*b[1])
+ */
+ /* R[10] = al*bl
+ * R[21] = al*bl + ah*bh + (a[0]-a[1])*(b[1]-b[0])
+ * R[32] = ah*bh
+ */
+ /* R[1]=t[3]+l[0]+r[0](+-)t[0] (have carry/borrow)
+ * R[2]=r[0]+t[3]+r[1](+-)t[1] (have carry/borrow)
+ * R[3]=r[1]+(carry/borrow)
+ */
+ if (l != NULL)
+ {
+ lp= &(t[n2]);
+ c1= (int)(bn_add_words(lp,&(t[n2+n]),&(l[0]),n));
+ }
+ else
+ {
+ lp= &(t[n2+n]);
+ c1=0;
+ }
+ c1+=(int)(bn_add_words(&(t[n2]),lp, &(r[0]),n));
+ if (oneg)
+ c1-=(int)(bn_sub_words(&(t[n2]),&(t[n2]),&(t[0]),n));
+ else
+ c1+=(int)(bn_add_words(&(t[n2]),&(t[n2]),&(t[0]),n));
+
+ c2 =(int)(bn_add_words(&(r[0]),&(r[0]),&(t[n2+n]),n));
+ c2+=(int)(bn_add_words(&(r[0]),&(r[0]),&(r[n]),n));
+ if (oneg)
+ c2-=(int)(bn_sub_words(&(r[0]),&(r[0]),&(t[n]),n));
+ else
+ c2+=(int)(bn_add_words(&(r[0]),&(r[0]),&(t[n]),n));
+
+ if (c1 != 0) /* Add starting at r[0], could be +ve or -ve */
+ {
+ i=0;
+ if (c1 > 0)
+ {
+ lc=c1;
+ do {
+ ll=(r[i]+lc)&BN_MASK2;
+ r[i++]=ll;
+ lc=(lc > ll);
+ } while (lc);
+ }
+ else
+ {
+ lc= -c1;
+ do {
+ ll=r[i];
+ r[i++]=(ll-lc)&BN_MASK2;
+ lc=(lc > ll);
+ } while (lc);
+ }
+ }
+ if (c2 != 0) /* Add starting at r[1] */
+ {
+ i=n;
+ if (c2 > 0)
+ {
+ lc=c2;
+ do {
+ ll=(r[i]+lc)&BN_MASK2;
+ r[i++]=ll;
+ lc=(lc > ll);
+ } while (lc);
+ }
+ else
+ {
+ lc= -c2;
+ do {
+ ll=r[i];
+ r[i++]=(ll-lc)&BN_MASK2;
+ lc=(lc > ll);
+ } while (lc);
+ }
+ }
+ }
+#endif
+
+int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
+ {
+ int top,al,bl;
+ BIGNUM *rr;
+#ifdef BN_RECURSION
+ BIGNUM *t;
+ int i,j,k;
+#endif
+
+#ifdef BN_COUNT
+printf("BN_mul %d * %d\n",a->top,b->top);
+#endif
+
+ bn_check_top(a);
+ bn_check_top(b);
+ bn_check_top(r);
+
+ al=a->top;
+ bl=b->top;
+ r->neg=a->neg^b->neg;
+
+ if ((al == 0) || (bl == 0))
+ {
+ BN_zero(r);
+ return(1);
+ }
+ top=al+bl;
+
+ if ((r == a) || (r == b))
+ rr= &(ctx->bn[ctx->tos+1]);
+ else
+ rr=r;
+
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+ if (al == bl)
+ {
+# ifdef BN_MUL_COMBA
+/* if (al == 4)
+ {
+ if (bn_wexpand(rr,8) == NULL) return(0);
+ rr->top=8;
+ bn_mul_comba4(rr->d,a->d,b->d);
+ goto end;
+ }
+ else */ if (al == 8)
+ {
+ if (bn_wexpand(rr,16) == NULL) return(0);
+ rr->top=16;
+ bn_mul_comba8(rr->d,a->d,b->d);
+ goto end;
+ }
+ else
+# endif
+#ifdef BN_RECURSION
+ if (al < BN_MULL_SIZE_NORMAL)
+#endif
+ {
+ if (bn_wexpand(rr,top) == NULL) return(0);
+ rr->top=top;
+ bn_mul_normal(rr->d,a->d,al,b->d,bl);
+ goto end;
+ }
+# ifdef BN_RECURSION
+ goto symetric;
+# endif
+ }
+#endif
+#ifdef BN_RECURSION
+ else if ((al < BN_MULL_SIZE_NORMAL) || (bl < BN_MULL_SIZE_NORMAL))
+ {
+ if (bn_wexpand(rr,top) == NULL) return(0);
+ rr->top=top;
+ bn_mul_normal(rr->d,a->d,al,b->d,bl);
+ goto end;
+ }
+ else
+ {
+ i=(al-bl);
+ if ((i == 1) && !BN_get_flags(b,BN_FLG_STATIC_DATA))
+ {
+ bn_wexpand(b,al);
+ b->d[bl]=0;
+ bl++;
+ goto symetric;
+ }
+ else if ((i == -1) && !BN_get_flags(a,BN_FLG_STATIC_DATA))
+ {
+ bn_wexpand(a,bl);
+ a->d[al]=0;
+ al++;
+ goto symetric;
+ }
+ }
+#endif
+
+ /* asymetric and >= 4 */
+ if (bn_wexpand(rr,top) == NULL) return(0);
+ rr->top=top;
+ bn_mul_normal(rr->d,a->d,al,b->d,bl);
+
+#ifdef BN_RECURSION
+ if (0)
+ {
+symetric:
+ /* symetric and > 4 */
+ /* 16 or larger */
+ j=BN_num_bits_word((BN_ULONG)al);
+ j=1<<(j-1);
+ k=j+j;
+ t= &(ctx->bn[ctx->tos]);
+ if (al == j) /* exact multiple */
+ {
+ bn_wexpand(t,k*2);
+ bn_wexpand(rr,k*2);
+ bn_mul_recursive(rr->d,a->d,b->d,al,t->d);
+ }
+ else
+ {
+ bn_wexpand(a,k);
+ bn_wexpand(b,k);
+ bn_wexpand(t,k*4);
+ bn_wexpand(rr,k*4);
+ for (i=a->top; i<k; i++)
+ a->d[i]=0;
+ for (i=b->top; i<k; i++)
+ b->d[i]=0;
+ bn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d);
+ }
+ rr->top=top;
+ }
+#endif
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+end:
+#endif
+ bn_fix_top(rr);
+ if (r != rr) BN_copy(r,rr);
+ return(1);
+ }
+
+void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
+ {
+ BN_ULONG *rr;
+
+#ifdef BN_COUNT
+printf(" bn_mul_normal %d * %d\n",na,nb);
+#endif
+
+ if (na < nb)
+ {
+ int itmp;
+ BN_ULONG *ltmp;
+
+ itmp=na; na=nb; nb=itmp;
+ ltmp=a; a=b; b=ltmp;
+
+ }
+ rr= &(r[na]);
+ rr[0]=bn_mul_words(r,a,na,b[0]);
+
+ for (;;)
+ {
+ if (--nb <= 0) return;
+ rr[1]=bn_mul_add_words(&(r[1]),a,na,b[1]);
+ if (--nb <= 0) return;
+ rr[2]=bn_mul_add_words(&(r[2]),a,na,b[2]);
+ if (--nb <= 0) return;
+ rr[3]=bn_mul_add_words(&(r[3]),a,na,b[3]);
+ if (--nb <= 0) return;
+ rr[4]=bn_mul_add_words(&(r[4]),a,na,b[4]);
+ rr+=4;
+ r+=4;
+ b+=4;
+ }
+ }
+
+void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+ {
+#ifdef BN_COUNT
+printf(" bn_mul_low_normal %d * %d\n",n,n);
+#endif
+ bn_mul_words(r,a,n,b[0]);
+
+ for (;;)
+ {
+ if (--n <= 0) return;
+ bn_mul_add_words(&(r[1]),a,n,b[1]);
+ if (--n <= 0) return;
+ bn_mul_add_words(&(r[2]),a,n,b[2]);
+ if (--n <= 0) return;
+ bn_mul_add_words(&(r[3]),a,n,b[3]);
+ if (--n <= 0) return;
+ bn_mul_add_words(&(r[4]),a,n,b[4]);
+ r+=4;
+ b+=4;
+ }
+ }
+
diff --git a/lib/dns/sec/openssl/bn_prime.c b/lib/dns/sec/openssl/bn_prime.c
new file mode 100644
index 00000000..6fa0f9be
--- /dev/null
+++ b/lib/dns/sec/openssl/bn_prime.c
@@ -0,0 +1,447 @@
+/* crypto/bn/bn_prime.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+#include <openssl/rand.h>
+
+/* The quick seive algorithm approach to weeding out primes is
+ * Philip Zimmermann's, as implemented in PGP. I have had a read of
+ * his comments and implemented my own version.
+ */
+#include "bn_prime.h"
+
+static int witness(BIGNUM *a, BIGNUM *n, BN_CTX *ctx,BN_CTX *ctx2,
+ BN_MONT_CTX *mont);
+static int probable_prime(BIGNUM *rnd, int bits);
+static int probable_prime_dh(BIGNUM *rnd, int bits,
+ BIGNUM *add, BIGNUM *rem, BN_CTX *ctx);
+static int probable_prime_dh_strong(BIGNUM *rnd, int bits,
+ BIGNUM *add, BIGNUM *rem, BN_CTX *ctx);
+BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int strong, BIGNUM *add,
+ BIGNUM *rem, void (*callback)(int,int,void *), void *cb_arg)
+ {
+ BIGNUM *rnd=NULL;
+ BIGNUM t;
+ int i,j,c1=0;
+ BN_CTX *ctx;
+
+ ctx=BN_CTX_new();
+ if (ctx == NULL) goto err;
+ if (ret == NULL)
+ {
+ if ((rnd=BN_new()) == NULL) goto err;
+ }
+ else
+ rnd=ret;
+ BN_init(&t);
+loop:
+ /* make a random number and set the top and bottom bits */
+ if (add == NULL)
+ {
+ if (!probable_prime(rnd,bits)) goto err;
+ }
+ else
+ {
+ if (strong)
+ {
+ if (!probable_prime_dh_strong(rnd,bits,add,rem,ctx))
+ goto err;
+ }
+ else
+ {
+ if (!probable_prime_dh(rnd,bits,add,rem,ctx))
+ goto err;
+ }
+ }
+ /* if (BN_mod_word(rnd,(BN_ULONG)3) == 1) goto loop; */
+ if (callback != NULL) callback(0,c1++,cb_arg);
+
+ if (!strong)
+ {
+ i=BN_is_prime(rnd,BN_prime_checks,callback,ctx,cb_arg);
+ if (i == -1) goto err;
+ if (i == 0) goto loop;
+ }
+ else
+ {
+ /* for a strong prime generation,
+ * check that (p-1)/2 is prime.
+ * Since a prime is odd, We just
+ * need to divide by 2 */
+ if (!BN_rshift1(&t,rnd)) goto err;
+
+ for (i=0; i<BN_prime_checks; i++)
+ {
+ j=BN_is_prime(rnd,1,callback,ctx,cb_arg);
+ if (j == -1) goto err;
+ if (j == 0) goto loop;
+
+ j=BN_is_prime(&t,1,callback,ctx,cb_arg);
+ if (j == -1) goto err;
+ if (j == 0) goto loop;
+
+ if (callback != NULL) callback(2,c1-1,cb_arg);
+ /* We have a strong prime test pass */
+ }
+ }
+ /* we have a prime :-) */
+ ret=rnd;
+err:
+ if ((ret == NULL) && (rnd != NULL)) BN_free(rnd);
+ BN_free(&t);
+ if (ctx != NULL) BN_CTX_free(ctx);
+ return(ret);
+ }
+
+int BN_is_prime(BIGNUM *a, int checks, void (*callback)(int,int,void *),
+ BN_CTX *ctx_passed, void *cb_arg)
+ {
+ int i,j,c2=0,ret= -1;
+ BIGNUM *check;
+ BN_CTX *ctx=NULL,*ctx2=NULL;
+ BN_MONT_CTX *mont=NULL;
+
+ if (!BN_is_odd(a))
+ return(0);
+ if (ctx_passed != NULL)
+ ctx=ctx_passed;
+ else
+ if ((ctx=BN_CTX_new()) == NULL) goto err;
+
+ if ((ctx2=BN_CTX_new()) == NULL) goto err;
+ if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
+
+ check= &(ctx->bn[ctx->tos++]);
+
+ /* Setup the montgomery structure */
+ if (!BN_MONT_CTX_set(mont,a,ctx2)) goto err;
+
+ for (i=0; i<checks; i++)
+ {
+ if (!BN_rand(check,BN_num_bits(a)-1,0,0)) goto err;
+ j=witness(check,a,ctx,ctx2,mont);
+ if (j == -1) goto err;
+ if (j)
+ {
+ ret=0;
+ goto err;
+ }
+ if (callback != NULL) callback(1,c2++,cb_arg);
+ }
+ ret=1;
+err:
+ ctx->tos--;
+ if ((ctx_passed == NULL) && (ctx != NULL))
+ BN_CTX_free(ctx);
+ if (ctx2 != NULL)
+ BN_CTX_free(ctx2);
+ if (mont != NULL) BN_MONT_CTX_free(mont);
+
+ return(ret);
+ }
+
+#define RECP_MUL_MOD
+
+static int witness(BIGNUM *a, BIGNUM *n, BN_CTX *ctx, BN_CTX *ctx2,
+ BN_MONT_CTX *mont)
+ {
+ int k,i,ret= -1,good;
+ BIGNUM *d,*dd,*tmp,*d1,*d2,*n1;
+ BIGNUM *mont_one,*mont_n1,*mont_a;
+
+ d1= &(ctx->bn[ctx->tos]);
+ d2= &(ctx->bn[ctx->tos+1]);
+ n1= &(ctx->bn[ctx->tos+2]);
+ ctx->tos+=3;
+
+ mont_one= &(ctx2->bn[ctx2->tos]);
+ mont_n1= &(ctx2->bn[ctx2->tos+1]);
+ mont_a= &(ctx2->bn[ctx2->tos+2]);
+ ctx2->tos+=3;
+
+ d=d1;
+ dd=d2;
+ if (!BN_one(d)) goto err;
+ if (!BN_sub(n1,n,d)) goto err; /* n1=n-1; */
+ k=BN_num_bits(n1);
+
+ if (!BN_to_montgomery(mont_one,BN_value_one(),mont,ctx2)) goto err;
+ if (!BN_to_montgomery(mont_n1,n1,mont,ctx2)) goto err;
+ if (!BN_to_montgomery(mont_a,a,mont,ctx2)) goto err;
+
+ BN_copy(d,mont_one);
+ for (i=k-1; i>=0; i--)
+ {
+ if ( (BN_cmp(d,mont_one) != 0) &&
+ (BN_cmp(d,mont_n1) != 0))
+ good=1;
+ else
+ good=0;
+
+ BN_mod_mul_montgomery(dd,d,d,mont,ctx2);
+
+ if (good && (BN_cmp(dd,mont_one) == 0))
+ {
+ ret=1;
+ goto err;
+ }
+ if (BN_is_bit_set(n1,i))
+ {
+ BN_mod_mul_montgomery(d,dd,mont_a,mont,ctx2);
+ }
+ else
+ {
+ tmp=d;
+ d=dd;
+ dd=tmp;
+ }
+ }
+ if (BN_cmp(d,mont_one) == 0)
+ i=0;
+ else i=1;
+ ret=i;
+err:
+ ctx->tos-=3;
+ ctx2->tos-=3;
+ return(ret);
+ }
+
+static int probable_prime(BIGNUM *rnd, int bits)
+ {
+ int i;
+ MS_STATIC BN_ULONG mods[NUMPRIMES];
+ BN_ULONG delta,d;
+
+again:
+ if (!BN_rand(rnd,bits,1,1)) return(0);
+ /* we now have a random number 'rand' to test. */
+ for (i=1; i<NUMPRIMES; i++)
+ mods[i]=BN_mod_word(rnd,(BN_ULONG)primes[i]);
+ delta=0;
+ loop: for (i=1; i<NUMPRIMES; i++)
+ {
+ /* check that rnd is not a prime and also
+ * that gcd(rnd-1,primes) == 1 (except for 2) */
+ if (((mods[i]+delta)%primes[i]) <= 1)
+ {
+ d=delta;
+ delta+=2;
+ /* perhaps need to check for overflow of
+ * delta (but delta can be upto 2^32)
+ * 21-May-98 eay - added overflow check */
+ if (delta < d) goto again;
+ goto loop;
+ }
+ }
+ if (!BN_add_word(rnd,delta)) return(0);
+ return(1);
+ }
+
+static int probable_prime_dh(BIGNUM *rnd, int bits, BIGNUM *add, BIGNUM *rem,
+ BN_CTX *ctx)
+ {
+ int i,ret=0;
+ BIGNUM *t1;
+
+ t1= &(ctx->bn[ctx->tos++]);
+
+ if (!BN_rand(rnd,bits,0,1)) goto err;
+
+ /* we need ((rnd-rem) % add) == 0 */
+
+ if (!BN_mod(t1,rnd,add,ctx)) goto err;
+ if (!BN_sub(rnd,rnd,t1)) goto err;
+ if (rem == NULL)
+ { if (!BN_add_word(rnd,1)) goto err; }
+ else
+ { if (!BN_add(rnd,rnd,rem)) goto err; }
+
+ /* we now have a random number 'rand' to test. */
+
+ loop: for (i=1; i<NUMPRIMES; i++)
+ {
+ /* check that rnd is a prime */
+ if (BN_mod_word(rnd,(BN_ULONG)primes[i]) <= 1)
+ {
+ if (!BN_add(rnd,rnd,add)) goto err;
+ goto loop;
+ }
+ }
+ ret=1;
+err:
+ ctx->tos--;
+ return(ret);
+ }
+
+static int probable_prime_dh_strong(BIGNUM *p, int bits, BIGNUM *padd,
+ BIGNUM *rem, BN_CTX *ctx)
+ {
+ int i,ret=0;
+ BIGNUM *t1,*qadd=NULL,*q=NULL;
+
+ bits--;
+ t1= &(ctx->bn[ctx->tos++]);
+ q= &(ctx->bn[ctx->tos++]);
+ qadd= &(ctx->bn[ctx->tos++]);
+
+ if (!BN_rshift1(qadd,padd)) goto err;
+
+ if (!BN_rand(q,bits,0,1)) goto err;
+
+ /* we need ((rnd-rem) % add) == 0 */
+ if (!BN_mod(t1,q,qadd,ctx)) goto err;
+ if (!BN_sub(q,q,t1)) goto err;
+ if (rem == NULL)
+ { if (!BN_add_word(q,1)) goto err; }
+ else
+ {
+ if (!BN_rshift1(t1,rem)) goto err;
+ if (!BN_add(q,q,t1)) goto err;
+ }
+
+ /* we now have a random number 'rand' to test. */
+ if (!BN_lshift1(p,q)) goto err;
+ if (!BN_add_word(p,1)) goto err;
+
+ loop: for (i=1; i<NUMPRIMES; i++)
+ {
+ /* check that p and q are prime */
+ /* check that for p and q
+ * gcd(p-1,primes) == 1 (except for 2) */
+ if ( (BN_mod_word(p,(BN_ULONG)primes[i]) == 0) ||
+ (BN_mod_word(q,(BN_ULONG)primes[i]) == 0))
+ {
+ if (!BN_add(p,p,padd)) goto err;
+ if (!BN_add(q,q,qadd)) goto err;
+ goto loop;
+ }
+ }
+ ret=1;
+err:
+ ctx->tos-=3;
+ return(ret);
+ }
+
+#if 0
+static int witness(BIGNUM *a, BIGNUM *n, BN_CTX *ctx)
+ {
+ int k,i,nb,ret= -1;
+ BIGNUM *d,*dd,*tmp;
+ BIGNUM *d1,*d2,*x,*n1,*inv;
+
+ d1= &(ctx->bn[ctx->tos]);
+ d2= &(ctx->bn[ctx->tos+1]);
+ x= &(ctx->bn[ctx->tos+2]);
+ n1= &(ctx->bn[ctx->tos+3]);
+ inv=&(ctx->bn[ctx->tos+4]);
+ ctx->tos+=5;
+
+ d=d1;
+ dd=d2;
+ if (!BN_one(d)) goto err;
+ if (!BN_sub(n1,n,d)) goto err; /* n1=n-1; */
+ k=BN_num_bits(n1);
+
+ /* i=BN_num_bits(n); */
+#ifdef RECP_MUL_MOD
+ nb=BN_reciprocal(inv,n,ctx); /**/
+ if (nb == -1) goto err;
+#endif
+
+ for (i=k-1; i>=0; i--)
+ {
+ if (BN_copy(x,d) == NULL) goto err;
+#ifndef RECP_MUL_MOD
+ if (!BN_mod_mul(dd,d,d,n,ctx)) goto err;
+#else
+ if (!BN_mod_mul_reciprocal(dd,d,d,n,inv,nb,ctx)) goto err;
+#endif
+ if ( BN_is_one(dd) &&
+ !BN_is_one(x) &&
+ (BN_cmp(x,n1) != 0))
+ {
+ ret=1;
+ goto err;
+ }
+ if (BN_is_bit_set(n1,i))
+ {
+#ifndef RECP_MUL_MOD
+ if (!BN_mod_mul(d,dd,a,n,ctx)) goto err;
+#else
+ if (!BN_mod_mul_reciprocal(d,dd,a,n,inv,nb,ctx)) goto err;
+#endif
+ }
+ else
+ {
+ tmp=d;
+ d=dd;
+ dd=tmp;
+ }
+ }
+ if (BN_is_one(d))
+ i=0;
+ else i=1;
+ ret=i;
+err:
+ ctx->tos-=5;
+ return(ret);
+ }
+#endif
diff --git a/lib/dns/sec/openssl/bn_prime.h b/lib/dns/sec/openssl/bn_prime.h
new file mode 100644
index 00000000..6fce0210
--- /dev/null
+++ b/lib/dns/sec/openssl/bn_prime.h
@@ -0,0 +1,325 @@
+/* crypto/bn/bn_prime.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef EIGHT_BIT
+#define NUMPRIMES 2048
+#else
+#define NUMPRIMES 54
+#endif
+static unsigned int primes[NUMPRIMES]=
+ {
+ 2, 3, 5, 7, 11, 13, 17, 19,
+ 23, 29, 31, 37, 41, 43, 47, 53,
+ 59, 61, 67, 71, 73, 79, 83, 89,
+ 97, 101, 103, 107, 109, 113, 127, 131,
+ 137, 139, 149, 151, 157, 163, 167, 173,
+ 179, 181, 191, 193, 197, 199, 211, 223,
+ 227, 229, 233, 239, 241, 251,
+#ifndef EIGHT_BIT
+ 257, 263,
+ 269, 271, 277, 281, 283, 293, 307, 311,
+ 313, 317, 331, 337, 347, 349, 353, 359,
+ 367, 373, 379, 383, 389, 397, 401, 409,
+ 419, 421, 431, 433, 439, 443, 449, 457,
+ 461, 463, 467, 479, 487, 491, 499, 503,
+ 509, 521, 523, 541, 547, 557, 563, 569,
+ 571, 577, 587, 593, 599, 601, 607, 613,
+ 617, 619, 631, 641, 643, 647, 653, 659,
+ 661, 673, 677, 683, 691, 701, 709, 719,
+ 727, 733, 739, 743, 751, 757, 761, 769,
+ 773, 787, 797, 809, 811, 821, 823, 827,
+ 829, 839, 853, 857, 859, 863, 877, 881,
+ 883, 887, 907, 911, 919, 929, 937, 941,
+ 947, 953, 967, 971, 977, 983, 991, 997,
+ 1009,1013,1019,1021,1031,1033,1039,1049,
+ 1051,1061,1063,1069,1087,1091,1093,1097,
+ 1103,1109,1117,1123,1129,1151,1153,1163,
+ 1171,1181,1187,1193,1201,1213,1217,1223,
+ 1229,1231,1237,1249,1259,1277,1279,1283,
+ 1289,1291,1297,1301,1303,1307,1319,1321,
+ 1327,1361,1367,1373,1381,1399,1409,1423,
+ 1427,1429,1433,1439,1447,1451,1453,1459,
+ 1471,1481,1483,1487,1489,1493,1499,1511,
+ 1523,1531,1543,1549,1553,1559,1567,1571,
+ 1579,1583,1597,1601,1607,1609,1613,1619,
+ 1621,1627,1637,1657,1663,1667,1669,1693,
+ 1697,1699,1709,1721,1723,1733,1741,1747,
+ 1753,1759,1777,1783,1787,1789,1801,1811,
+ 1823,1831,1847,1861,1867,1871,1873,1877,
+ 1879,1889,1901,1907,1913,1931,1933,1949,
+ 1951,1973,1979,1987,1993,1997,1999,2003,
+ 2011,2017,2027,2029,2039,2053,2063,2069,
+ 2081,2083,2087,2089,2099,2111,2113,2129,
+ 2131,2137,2141,2143,2153,2161,2179,2203,
+ 2207,2213,2221,2237,2239,2243,2251,2267,
+ 2269,2273,2281,2287,2293,2297,2309,2311,
+ 2333,2339,2341,2347,2351,2357,2371,2377,
+ 2381,2383,2389,2393,2399,2411,2417,2423,
+ 2437,2441,2447,2459,2467,2473,2477,2503,
+ 2521,2531,2539,2543,2549,2551,2557,2579,
+ 2591,2593,2609,2617,2621,2633,2647,2657,
+ 2659,2663,2671,2677,2683,2687,2689,2693,
+ 2699,2707,2711,2713,2719,2729,2731,2741,
+ 2749,2753,2767,2777,2789,2791,2797,2801,
+ 2803,2819,2833,2837,2843,2851,2857,2861,
+ 2879,2887,2897,2903,2909,2917,2927,2939,
+ 2953,2957,2963,2969,2971,2999,3001,3011,
+ 3019,3023,3037,3041,3049,3061,3067,3079,
+ 3083,3089,3109,3119,3121,3137,3163,3167,
+ 3169,3181,3187,3191,3203,3209,3217,3221,
+ 3229,3251,3253,3257,3259,3271,3299,3301,
+ 3307,3313,3319,3323,3329,3331,3343,3347,
+ 3359,3361,3371,3373,3389,3391,3407,3413,
+ 3433,3449,3457,3461,3463,3467,3469,3491,
+ 3499,3511,3517,3527,3529,3533,3539,3541,
+ 3547,3557,3559,3571,3581,3583,3593,3607,
+ 3613,3617,3623,3631,3637,3643,3659,3671,
+ 3673,3677,3691,3697,3701,3709,3719,3727,
+ 3733,3739,3761,3767,3769,3779,3793,3797,
+ 3803,3821,3823,3833,3847,3851,3853,3863,
+ 3877,3881,3889,3907,3911,3917,3919,3923,
+ 3929,3931,3943,3947,3967,3989,4001,4003,
+ 4007,4013,4019,4021,4027,4049,4051,4057,
+ 4073,4079,4091,4093,4099,4111,4127,4129,
+ 4133,4139,4153,4157,4159,4177,4201,4211,
+ 4217,4219,4229,4231,4241,4243,4253,4259,
+ 4261,4271,4273,4283,4289,4297,4327,4337,
+ 4339,4349,4357,4363,4373,4391,4397,4409,
+ 4421,4423,4441,4447,4451,4457,4463,4481,
+ 4483,4493,4507,4513,4517,4519,4523,4547,
+ 4549,4561,4567,4583,4591,4597,4603,4621,
+ 4637,4639,4643,4649,4651,4657,4663,4673,
+ 4679,4691,4703,4721,4723,4729,4733,4751,
+ 4759,4783,4787,4789,4793,4799,4801,4813,
+ 4817,4831,4861,4871,4877,4889,4903,4909,
+ 4919,4931,4933,4937,4943,4951,4957,4967,
+ 4969,4973,4987,4993,4999,5003,5009,5011,
+ 5021,5023,5039,5051,5059,5077,5081,5087,
+ 5099,5101,5107,5113,5119,5147,5153,5167,
+ 5171,5179,5189,5197,5209,5227,5231,5233,
+ 5237,5261,5273,5279,5281,5297,5303,5309,
+ 5323,5333,5347,5351,5381,5387,5393,5399,
+ 5407,5413,5417,5419,5431,5437,5441,5443,
+ 5449,5471,5477,5479,5483,5501,5503,5507,
+ 5519,5521,5527,5531,5557,5563,5569,5573,
+ 5581,5591,5623,5639,5641,5647,5651,5653,
+ 5657,5659,5669,5683,5689,5693,5701,5711,
+ 5717,5737,5741,5743,5749,5779,5783,5791,
+ 5801,5807,5813,5821,5827,5839,5843,5849,
+ 5851,5857,5861,5867,5869,5879,5881,5897,
+ 5903,5923,5927,5939,5953,5981,5987,6007,
+ 6011,6029,6037,6043,6047,6053,6067,6073,
+ 6079,6089,6091,6101,6113,6121,6131,6133,
+ 6143,6151,6163,6173,6197,6199,6203,6211,
+ 6217,6221,6229,6247,6257,6263,6269,6271,
+ 6277,6287,6299,6301,6311,6317,6323,6329,
+ 6337,6343,6353,6359,6361,6367,6373,6379,
+ 6389,6397,6421,6427,6449,6451,6469,6473,
+ 6481,6491,6521,6529,6547,6551,6553,6563,
+ 6569,6571,6577,6581,6599,6607,6619,6637,
+ 6653,6659,6661,6673,6679,6689,6691,6701,
+ 6703,6709,6719,6733,6737,6761,6763,6779,
+ 6781,6791,6793,6803,6823,6827,6829,6833,
+ 6841,6857,6863,6869,6871,6883,6899,6907,
+ 6911,6917,6947,6949,6959,6961,6967,6971,
+ 6977,6983,6991,6997,7001,7013,7019,7027,
+ 7039,7043,7057,7069,7079,7103,7109,7121,
+ 7127,7129,7151,7159,7177,7187,7193,7207,
+ 7211,7213,7219,7229,7237,7243,7247,7253,
+ 7283,7297,7307,7309,7321,7331,7333,7349,
+ 7351,7369,7393,7411,7417,7433,7451,7457,
+ 7459,7477,7481,7487,7489,7499,7507,7517,
+ 7523,7529,7537,7541,7547,7549,7559,7561,
+ 7573,7577,7583,7589,7591,7603,7607,7621,
+ 7639,7643,7649,7669,7673,7681,7687,7691,
+ 7699,7703,7717,7723,7727,7741,7753,7757,
+ 7759,7789,7793,7817,7823,7829,7841,7853,
+ 7867,7873,7877,7879,7883,7901,7907,7919,
+ 7927,7933,7937,7949,7951,7963,7993,8009,
+ 8011,8017,8039,8053,8059,8069,8081,8087,
+ 8089,8093,8101,8111,8117,8123,8147,8161,
+ 8167,8171,8179,8191,8209,8219,8221,8231,
+ 8233,8237,8243,8263,8269,8273,8287,8291,
+ 8293,8297,8311,8317,8329,8353,8363,8369,
+ 8377,8387,8389,8419,8423,8429,8431,8443,
+ 8447,8461,8467,8501,8513,8521,8527,8537,
+ 8539,8543,8563,8573,8581,8597,8599,8609,
+ 8623,8627,8629,8641,8647,8663,8669,8677,
+ 8681,8689,8693,8699,8707,8713,8719,8731,
+ 8737,8741,8747,8753,8761,8779,8783,8803,
+ 8807,8819,8821,8831,8837,8839,8849,8861,
+ 8863,8867,8887,8893,8923,8929,8933,8941,
+ 8951,8963,8969,8971,8999,9001,9007,9011,
+ 9013,9029,9041,9043,9049,9059,9067,9091,
+ 9103,9109,9127,9133,9137,9151,9157,9161,
+ 9173,9181,9187,9199,9203,9209,9221,9227,
+ 9239,9241,9257,9277,9281,9283,9293,9311,
+ 9319,9323,9337,9341,9343,9349,9371,9377,
+ 9391,9397,9403,9413,9419,9421,9431,9433,
+ 9437,9439,9461,9463,9467,9473,9479,9491,
+ 9497,9511,9521,9533,9539,9547,9551,9587,
+ 9601,9613,9619,9623,9629,9631,9643,9649,
+ 9661,9677,9679,9689,9697,9719,9721,9733,
+ 9739,9743,9749,9767,9769,9781,9787,9791,
+ 9803,9811,9817,9829,9833,9839,9851,9857,
+ 9859,9871,9883,9887,9901,9907,9923,9929,
+ 9931,9941,9949,9967,9973,10007,10009,10037,
+ 10039,10061,10067,10069,10079,10091,10093,10099,
+ 10103,10111,10133,10139,10141,10151,10159,10163,
+ 10169,10177,10181,10193,10211,10223,10243,10247,
+ 10253,10259,10267,10271,10273,10289,10301,10303,
+ 10313,10321,10331,10333,10337,10343,10357,10369,
+ 10391,10399,10427,10429,10433,10453,10457,10459,
+ 10463,10477,10487,10499,10501,10513,10529,10531,
+ 10559,10567,10589,10597,10601,10607,10613,10627,
+ 10631,10639,10651,10657,10663,10667,10687,10691,
+ 10709,10711,10723,10729,10733,10739,10753,10771,
+ 10781,10789,10799,10831,10837,10847,10853,10859,
+ 10861,10867,10883,10889,10891,10903,10909,10937,
+ 10939,10949,10957,10973,10979,10987,10993,11003,
+ 11027,11047,11057,11059,11069,11071,11083,11087,
+ 11093,11113,11117,11119,11131,11149,11159,11161,
+ 11171,11173,11177,11197,11213,11239,11243,11251,
+ 11257,11261,11273,11279,11287,11299,11311,11317,
+ 11321,11329,11351,11353,11369,11383,11393,11399,
+ 11411,11423,11437,11443,11447,11467,11471,11483,
+ 11489,11491,11497,11503,11519,11527,11549,11551,
+ 11579,11587,11593,11597,11617,11621,11633,11657,
+ 11677,11681,11689,11699,11701,11717,11719,11731,
+ 11743,11777,11779,11783,11789,11801,11807,11813,
+ 11821,11827,11831,11833,11839,11863,11867,11887,
+ 11897,11903,11909,11923,11927,11933,11939,11941,
+ 11953,11959,11969,11971,11981,11987,12007,12011,
+ 12037,12041,12043,12049,12071,12073,12097,12101,
+ 12107,12109,12113,12119,12143,12149,12157,12161,
+ 12163,12197,12203,12211,12227,12239,12241,12251,
+ 12253,12263,12269,12277,12281,12289,12301,12323,
+ 12329,12343,12347,12373,12377,12379,12391,12401,
+ 12409,12413,12421,12433,12437,12451,12457,12473,
+ 12479,12487,12491,12497,12503,12511,12517,12527,
+ 12539,12541,12547,12553,12569,12577,12583,12589,
+ 12601,12611,12613,12619,12637,12641,12647,12653,
+ 12659,12671,12689,12697,12703,12713,12721,12739,
+ 12743,12757,12763,12781,12791,12799,12809,12821,
+ 12823,12829,12841,12853,12889,12893,12899,12907,
+ 12911,12917,12919,12923,12941,12953,12959,12967,
+ 12973,12979,12983,13001,13003,13007,13009,13033,
+ 13037,13043,13049,13063,13093,13099,13103,13109,
+ 13121,13127,13147,13151,13159,13163,13171,13177,
+ 13183,13187,13217,13219,13229,13241,13249,13259,
+ 13267,13291,13297,13309,13313,13327,13331,13337,
+ 13339,13367,13381,13397,13399,13411,13417,13421,
+ 13441,13451,13457,13463,13469,13477,13487,13499,
+ 13513,13523,13537,13553,13567,13577,13591,13597,
+ 13613,13619,13627,13633,13649,13669,13679,13681,
+ 13687,13691,13693,13697,13709,13711,13721,13723,
+ 13729,13751,13757,13759,13763,13781,13789,13799,
+ 13807,13829,13831,13841,13859,13873,13877,13879,
+ 13883,13901,13903,13907,13913,13921,13931,13933,
+ 13963,13967,13997,13999,14009,14011,14029,14033,
+ 14051,14057,14071,14081,14083,14087,14107,14143,
+ 14149,14153,14159,14173,14177,14197,14207,14221,
+ 14243,14249,14251,14281,14293,14303,14321,14323,
+ 14327,14341,14347,14369,14387,14389,14401,14407,
+ 14411,14419,14423,14431,14437,14447,14449,14461,
+ 14479,14489,14503,14519,14533,14537,14543,14549,
+ 14551,14557,14561,14563,14591,14593,14621,14627,
+ 14629,14633,14639,14653,14657,14669,14683,14699,
+ 14713,14717,14723,14731,14737,14741,14747,14753,
+ 14759,14767,14771,14779,14783,14797,14813,14821,
+ 14827,14831,14843,14851,14867,14869,14879,14887,
+ 14891,14897,14923,14929,14939,14947,14951,14957,
+ 14969,14983,15013,15017,15031,15053,15061,15073,
+ 15077,15083,15091,15101,15107,15121,15131,15137,
+ 15139,15149,15161,15173,15187,15193,15199,15217,
+ 15227,15233,15241,15259,15263,15269,15271,15277,
+ 15287,15289,15299,15307,15313,15319,15329,15331,
+ 15349,15359,15361,15373,15377,15383,15391,15401,
+ 15413,15427,15439,15443,15451,15461,15467,15473,
+ 15493,15497,15511,15527,15541,15551,15559,15569,
+ 15581,15583,15601,15607,15619,15629,15641,15643,
+ 15647,15649,15661,15667,15671,15679,15683,15727,
+ 15731,15733,15737,15739,15749,15761,15767,15773,
+ 15787,15791,15797,15803,15809,15817,15823,15859,
+ 15877,15881,15887,15889,15901,15907,15913,15919,
+ 15923,15937,15959,15971,15973,15991,16001,16007,
+ 16033,16057,16061,16063,16067,16069,16073,16087,
+ 16091,16097,16103,16111,16127,16139,16141,16183,
+ 16187,16189,16193,16217,16223,16229,16231,16249,
+ 16253,16267,16273,16301,16319,16333,16339,16349,
+ 16361,16363,16369,16381,16411,16417,16421,16427,
+ 16433,16447,16451,16453,16477,16481,16487,16493,
+ 16519,16529,16547,16553,16561,16567,16573,16603,
+ 16607,16619,16631,16633,16649,16651,16657,16661,
+ 16673,16691,16693,16699,16703,16729,16741,16747,
+ 16759,16763,16787,16811,16823,16829,16831,16843,
+ 16871,16879,16883,16889,16901,16903,16921,16927,
+ 16931,16937,16943,16963,16979,16981,16987,16993,
+ 17011,17021,17027,17029,17033,17041,17047,17053,
+ 17077,17093,17099,17107,17117,17123,17137,17159,
+ 17167,17183,17189,17191,17203,17207,17209,17231,
+ 17239,17257,17291,17293,17299,17317,17321,17327,
+ 17333,17341,17351,17359,17377,17383,17387,17389,
+ 17393,17401,17417,17419,17431,17443,17449,17467,
+ 17471,17477,17483,17489,17491,17497,17509,17519,
+ 17539,17551,17569,17573,17579,17581,17597,17599,
+ 17609,17623,17627,17657,17659,17669,17681,17683,
+ 17707,17713,17729,17737,17747,17749,17761,17783,
+ 17789,17791,17807,17827,17837,17839,17851,17863,
+#endif
+ };
diff --git a/lib/dns/sec/openssl/bn_print.c b/lib/dns/sec/openssl/bn_print.c
new file mode 100644
index 00000000..c5469f9e
--- /dev/null
+++ b/lib/dns/sec/openssl/bn_print.c
@@ -0,0 +1,327 @@
+/* crypto/bn/bn_print.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include "bn_lcl.h"
+
+static const char *Hex="0123456789ABCDEF";
+
+/* Must 'Free' the returned data */
+char *BN_bn2hex(const BIGNUM *a)
+ {
+ int i,j,v,z=0;
+ char *buf;
+ char *p;
+
+ buf=(char *)Malloc(a->top*BN_BYTES*2+2);
+ if (buf == NULL)
+ {
+ BNerr(BN_F_BN_BN2HEX,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ p=buf;
+ if (a->neg) *(p++)='-';
+ if (a->top == 0) *(p++)='0';
+ for (i=a->top-1; i >=0; i--)
+ {
+ for (j=BN_BITS2-8; j >= 0; j-=8)
+ {
+ /* strip leading zeros */
+ v=((int)(a->d[i]>>(long)j))&0xff;
+ if (z || (v != 0))
+ {
+ *(p++)=Hex[v>>4];
+ *(p++)=Hex[v&0x0f];
+ z=1;
+ }
+ }
+ }
+ *p='\0';
+err:
+ return(buf);
+ }
+
+#if 0
+/* Must 'Free' the returned data */
+char *BN_bn2dec(const BIGNUM *a)
+ {
+ int i=0,num;
+ char *buf=NULL;
+ char *p;
+ BIGNUM *t=NULL;
+ BN_ULONG *bn_data=NULL,*lp;
+
+ i=BN_num_bits(a)*3;
+ num=(i/10+i/1000+3)+1;
+ bn_data=(BN_ULONG *)Malloc((num/BN_DEC_NUM+1)*sizeof(BN_ULONG));
+ buf=(char *)Malloc(num+3);
+ if ((buf == NULL) || (bn_data == NULL))
+ {
+ BNerr(BN_F_BN_BN2DEC,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if ((t=BN_dup(a)) == NULL) goto err;
+
+ p=buf;
+ lp=bn_data;
+ if (t->neg) *(p++)='-';
+ if (t->top == 0)
+ {
+ *(p++)='0';
+ *(p++)='\0';
+ }
+ else
+ {
+ i=0;
+ while (!BN_is_zero(t))
+ {
+ *lp=BN_div_word(t,BN_DEC_CONV);
+ lp++;
+ }
+ lp--;
+ /* We now have a series of blocks, BN_DEC_NUM chars
+ * in length, where the last one needs trucation.
+ * The blocks need to be reversed in order. */
+ sprintf(p,BN_DEC_FMT1,*lp);
+ while (*p) p++;
+ while (lp != bn_data)
+ {
+ lp--;
+ sprintf(p,BN_DEC_FMT2,*lp);
+ while (*p) p++;
+ }
+ }
+err:
+ if (bn_data != NULL) Free(bn_data);
+ if (t != NULL) BN_free(t);
+ return(buf);
+ }
+#endif
+
+int BN_hex2bn(BIGNUM **bn, const char *a)
+ {
+ BIGNUM *ret=NULL;
+ BN_ULONG l=0;
+ int neg=0,h,m,i,j,k,c;
+ int num;
+
+ if ((a == NULL) || (*a == '\0')) return(0);
+
+ if (*a == '-') { neg=1; a++; }
+
+ for (i=0; isxdigit((unsigned char) a[i]); i++)
+ ;
+
+ num=i+neg;
+ if (bn == NULL) return(num);
+
+ /* a is the start of the hex digets, and it is 'i' long */
+ if (*bn == NULL)
+ {
+ if ((ret=BN_new()) == NULL) return(0);
+ }
+ else
+ {
+ ret= *bn;
+ BN_zero(ret);
+ }
+
+ /* i is the number of hex digests; */
+ if (bn_expand(ret,i*4) == NULL) goto err;
+
+ j=i; /* least significate 'hex' */
+ m=0;
+ h=0;
+ while (j > 0)
+ {
+ m=((BN_BYTES*2) <= j)?(BN_BYTES*2):j;
+ l=0;
+ for (;;)
+ {
+ c=a[j-m];
+ if ((c >= '0') && (c <= '9')) k=c-'0';
+ else if ((c >= 'a') && (c <= 'f')) k=c-'a'+10;
+ else if ((c >= 'A') && (c <= 'F')) k=c-'A'+10;
+ else k=0; /* paranoia */
+ l=(l<<4)|k;
+
+ if (--m <= 0)
+ {
+ ret->d[h++]=l;
+ break;
+ }
+ }
+ j-=(BN_BYTES*2);
+ }
+ ret->top=h;
+ bn_fix_top(ret);
+ ret->neg=neg;
+
+ *bn=ret;
+ return(num);
+err:
+ if (*bn == NULL) BN_free(ret);
+ return(0);
+ }
+
+#if 0
+int BN_dec2bn(BIGNUM **bn, const char *a)
+ {
+ BIGNUM *ret=NULL;
+ BN_ULONG l=0;
+ int neg=0,i,j;
+ int num;
+
+ if ((a == NULL) || (*a == '\0')) return(0);
+ if (*a == '-') { neg=1; a++; }
+
+ for (i=0; isdigit((unsigned char) a[i]); i++)
+ ;
+
+ num=i+neg;
+ if (bn == NULL) return(num);
+
+ /* a is the start of the digets, and it is 'i' long.
+ * We chop it into BN_DEC_NUM digets at a time */
+ if (*bn == NULL)
+ {
+ if ((ret=BN_new()) == NULL) return(0);
+ }
+ else
+ {
+ ret= *bn;
+ BN_zero(ret);
+ }
+
+ /* i is the number of digests, a bit of an over expand; */
+ if (bn_expand(ret,i*4) == NULL) goto err;
+
+ j=BN_DEC_NUM-(i%BN_DEC_NUM);
+ if (j == BN_DEC_NUM) j=0;
+ l=0;
+ while (*a)
+ {
+ l*=10;
+ l+= *a-'0';
+ a++;
+ if (++j == BN_DEC_NUM)
+ {
+ BN_mul_word(ret,BN_DEC_CONV);
+ BN_add_word(ret,l);
+ l=0;
+ j=0;
+ }
+ }
+ ret->neg=neg;
+
+ bn_fix_top(ret);
+ *bn=ret;
+ return(num);
+err:
+ if (*bn == NULL) BN_free(ret);
+ return(0);
+ }
+#endif
+
+#ifndef NO_BIO
+
+#ifndef NO_FP_API
+int BN_print_fp(FILE *fp, BIGNUM *a)
+ {
+ BIO *b;
+ int ret;
+
+ if ((b=BIO_new(BIO_s_file())) == NULL)
+ return(0);
+ BIO_set_fp(b,fp,BIO_NOCLOSE);
+ ret=BN_print(b,a);
+ BIO_free(b);
+ return(ret);
+ }
+#endif
+
+int BN_print(BIO *bp, const BIGNUM *a)
+ {
+ int i,j,v,z=0;
+ int ret=0;
+
+ if ((a->neg) && (BIO_write(bp,"-",1) != 1)) goto end;
+ if ((a->top == 0) && (BIO_write(bp,"0",1) != 1)) goto end;
+ for (i=a->top-1; i >=0; i--)
+ {
+ for (j=BN_BITS2-4; j >= 0; j-=4)
+ {
+ /* strip leading zeros */
+ v=((int)(a->d[i]>>(long)j))&0x0f;
+ if (z || (v != 0))
+ {
+ if (BIO_write(bp,&(Hex[v]),1) != 1)
+ goto end;
+ z=1;
+ }
+ }
+ }
+ ret=1;
+end:
+ return(ret);
+ }
+
+#endif
diff --git a/lib/dns/sec/openssl/bn_rand.c b/lib/dns/sec/openssl/bn_rand.c
new file mode 100644
index 00000000..91b8e34a
--- /dev/null
+++ b/lib/dns/sec/openssl/bn_rand.c
@@ -0,0 +1,117 @@
+/* crypto/bn/bn_rand.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+#include <openssl/rand.h>
+
+int BN_rand(BIGNUM *rnd, int bits, int top, int bottom)
+ {
+ unsigned char *buf=NULL;
+ int ret=0,bit,bytes,mask;
+ time_t tim;
+
+ bytes=(bits+7)/8;
+ bit=(bits-1)%8;
+ mask=0xff<<bit;
+
+ buf=(unsigned char *)Malloc(bytes);
+ if (buf == NULL)
+ {
+ BNerr(BN_F_BN_RAND,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /* make a random number and set the top and bottom bits */
+ time(&tim);
+ RAND_seed(&tim,sizeof(tim));
+
+ RAND_bytes(buf,(int)bytes);
+ if (top)
+ {
+ if (bit == 0)
+ {
+ buf[0]=1;
+ buf[1]|=0x80;
+ }
+ else
+ {
+ buf[0]|=(3<<(bit-1));
+ buf[0]&= ~(mask<<1);
+ }
+ }
+ else
+ {
+ buf[0]|=(1<<bit);
+ buf[0]&= ~(mask<<1);
+ }
+ if (bottom) /* set bottom bits to whatever odd is */
+ buf[bytes-1]|=1;
+ if (!BN_bin2bn(buf,bytes,rnd)) goto err;
+ ret=1;
+err:
+ if (buf != NULL)
+ {
+ memset(buf,0,bytes);
+ Free(buf);
+ }
+ return(ret);
+ }
+
diff --git a/lib/dns/sec/openssl/bn_recp.c b/lib/dns/sec/openssl/bn_recp.c
new file mode 100644
index 00000000..9419ce02
--- /dev/null
+++ b/lib/dns/sec/openssl/bn_recp.c
@@ -0,0 +1,228 @@
+/* crypto/bn/bn_recp.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+void BN_RECP_CTX_init(BN_RECP_CTX *recp)
+ {
+ BN_init(&(recp->N));
+ BN_init(&(recp->Nr));
+ recp->num_bits=0;
+ recp->flags=0;
+ }
+
+BN_RECP_CTX *BN_RECP_CTX_new(void)
+ {
+ BN_RECP_CTX *ret;
+
+ if ((ret=(BN_RECP_CTX *)Malloc(sizeof(BN_RECP_CTX))) == NULL)
+ return(NULL);
+
+ BN_RECP_CTX_init(ret);
+ ret->flags=BN_FLG_MALLOCED;
+ return(ret);
+ }
+
+void BN_RECP_CTX_free(BN_RECP_CTX *recp)
+ {
+ if(recp == NULL)
+ return;
+
+ BN_free(&(recp->N));
+ BN_free(&(recp->Nr));
+ if (recp->flags & BN_FLG_MALLOCED)
+ Free(recp);
+ }
+
+int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx)
+ {
+ ctx = ctx; /* BEW - quiet the compiler */
+ BN_copy(&(recp->N),d);
+ BN_zero(&(recp->Nr));
+ recp->num_bits=BN_num_bits(d);
+ recp->shift=0;
+ return(1);
+ }
+
+int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y, BN_RECP_CTX *recp,
+ BN_CTX *ctx)
+ {
+ int ret=0;
+ BIGNUM *a;
+
+ a= &(ctx->bn[ctx->tos++]);
+ if (y != NULL)
+ {
+ if (x == y)
+ { if (!BN_sqr(a,x,ctx)) goto err; }
+ else
+ { if (!BN_mul(a,x,y,ctx)) goto err; }
+ }
+ else
+ a=x; /* Just do the mod */
+
+ BN_div_recp(NULL,r,a,recp,ctx);
+ ret=1;
+err:
+ ctx->tos--;
+ return(ret);
+ }
+
+int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, BN_RECP_CTX *recp,
+ BN_CTX *ctx)
+ {
+ int i,j,tos,ret=0,ex;
+ BIGNUM *a,*b,*d,*r;
+
+ tos=ctx->tos;
+ a= &(ctx->bn[ctx->tos++]);
+ b= &(ctx->bn[ctx->tos++]);
+ if (dv != NULL)
+ d=dv;
+ else
+ d= &(ctx->bn[ctx->tos++]);
+ if (rem != NULL)
+ r=rem;
+ else
+ r= &(ctx->bn[ctx->tos++]);
+
+ if (BN_ucmp(m,&(recp->N)) < 0)
+ {
+ BN_zero(d);
+ BN_copy(r,m);
+ ctx->tos=tos;
+ return(1);
+ }
+
+ /* We want the remainder
+ * Given input of ABCDEF / ab
+ * we need multiply ABCDEF by 3 digests of the reciprocal of ab
+ *
+ */
+ i=BN_num_bits(m);
+
+ j=recp->num_bits*2;
+ if (j > i)
+ {
+ i=j;
+ ex=0;
+ }
+ else
+ {
+ ex=(i-j)/2;
+ }
+
+ j=i/2;
+
+ if (i != recp->shift)
+ recp->shift=BN_reciprocal(&(recp->Nr),&(recp->N),
+ i,ctx);
+
+ if (!BN_rshift(a,m,j-ex)) goto err;
+ if (!BN_mul(b,a,&(recp->Nr),ctx)) goto err;
+ if (!BN_rshift(d,b,j+ex)) goto err;
+ d->neg=0;
+ if (!BN_mul(b,&(recp->N),d,ctx)) goto err;
+ if (!BN_usub(r,m,b)) goto err;
+ r->neg=0;
+
+ j=0;
+#if 1
+ while (BN_ucmp(r,&(recp->N)) >= 0)
+ {
+ if (j++ > 2)
+ {
+ BNerr(BN_F_BN_MOD_MUL_RECIPROCAL,BN_R_BAD_RECIPROCAL);
+ goto err;
+ }
+ if (!BN_usub(r,r,&(recp->N))) goto err;
+ if (!BN_add_word(d,1)) goto err;
+ }
+#endif
+
+ r->neg=BN_is_zero(r)?0:m->neg;
+ d->neg=m->neg^recp->N.neg;
+ ret=1;
+err:
+ ctx->tos=tos;
+ return(ret);
+ }
+
+/* len is the expected size of the result
+ * We actually calculate with an extra word of precision, so
+ * we can do faster division if the remainder is not required.
+ */
+int BN_reciprocal(BIGNUM *r, BIGNUM *m, int len, BN_CTX *ctx)
+ {
+ int ret= -1;
+ BIGNUM t;
+
+ BN_init(&t);
+
+ BN_zero(&t);
+ if (!BN_set_bit(&t,len)) goto err;
+
+ if (!BN_div(r,NULL,&t,m,ctx)) goto err;
+ ret=len;
+err:
+ BN_free(&t);
+ return(ret);
+ }
+
diff --git a/lib/dns/sec/openssl/bn_shift.c b/lib/dns/sec/openssl/bn_shift.c
new file mode 100644
index 00000000..61aae65a
--- /dev/null
+++ b/lib/dns/sec/openssl/bn_shift.c
@@ -0,0 +1,200 @@
+/* crypto/bn/bn_shift.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+int BN_lshift1(BIGNUM *r, BIGNUM *a)
+ {
+ register BN_ULONG *ap,*rp,t,c;
+ int i;
+
+ if (r != a)
+ {
+ r->neg=a->neg;
+ if (bn_wexpand(r,a->top+1) == NULL) return(0);
+ r->top=a->top;
+ }
+ else
+ {
+ if (bn_wexpand(r,a->top+1) == NULL) return(0);
+ }
+ ap=a->d;
+ rp=r->d;
+ c=0;
+ for (i=0; i<a->top; i++)
+ {
+ t= *(ap++);
+ *(rp++)=((t<<1)|c)&BN_MASK2;
+ c=(t & BN_TBIT)?1:0;
+ }
+ if (c)
+ {
+ *rp=1;
+ r->top++;
+ }
+ return(1);
+ }
+
+int BN_rshift1(BIGNUM *r, BIGNUM *a)
+ {
+ BN_ULONG *ap,*rp,t,c;
+ int i;
+
+ if (BN_is_zero(a))
+ {
+ BN_zero(r);
+ return(1);
+ }
+ if (a != r)
+ {
+ if (bn_wexpand(r,a->top) == NULL) return(0);
+ r->top=a->top;
+ r->neg=a->neg;
+ }
+ ap=a->d;
+ rp=r->d;
+ c=0;
+ for (i=a->top-1; i>=0; i--)
+ {
+ t=ap[i];
+ rp[i]=((t>>1)&BN_MASK2)|c;
+ c=(t&1)?BN_TBIT:0;
+ }
+ bn_fix_top(r);
+ return(1);
+ }
+
+int BN_lshift(BIGNUM *r, const BIGNUM *a, int n)
+ {
+ int i,nw,lb,rb;
+ BN_ULONG *t,*f;
+ BN_ULONG l;
+
+ r->neg=a->neg;
+ if (bn_wexpand(r,a->top+(n/BN_BITS2)+1) == NULL) return(0);
+ nw=n/BN_BITS2;
+ lb=n%BN_BITS2;
+ rb=BN_BITS2-lb;
+ f=a->d;
+ t=r->d;
+ t[a->top+nw]=0;
+ if (lb == 0)
+ for (i=a->top-1; i>=0; i--)
+ t[nw+i]=f[i];
+ else
+ for (i=a->top-1; i>=0; i--)
+ {
+ l=f[i];
+ t[nw+i+1]|=(l>>rb)&BN_MASK2;
+ t[nw+i]=(l<<lb)&BN_MASK2;
+ }
+ memset(t,0,nw*sizeof(t[0]));
+/* for (i=0; i<nw; i++)
+ t[i]=0;*/
+ r->top=a->top+nw+1;
+ bn_fix_top(r);
+ return(1);
+ }
+
+int BN_rshift(BIGNUM *r, BIGNUM *a, int n)
+ {
+ int i,j,nw,lb,rb;
+ BN_ULONG *t,*f;
+ BN_ULONG l,tmp;
+
+ nw=n/BN_BITS2;
+ rb=n%BN_BITS2;
+ lb=BN_BITS2-rb;
+ if (nw > a->top)
+ {
+ BN_zero(r);
+ return(1);
+ }
+ if (r != a)
+ {
+ r->neg=a->neg;
+ if (bn_wexpand(r,a->top-nw+1) == NULL) return(0);
+ }
+
+ f= &(a->d[nw]);
+ t=r->d;
+ j=a->top-nw;
+ r->top=j;
+
+ if (rb == 0)
+ {
+ for (i=j+1; i > 0; i--)
+ *(t++)= *(f++);
+ }
+ else
+ {
+ l= *(f++);
+ for (i=1; i<j; i++)
+ {
+ tmp =(l>>rb)&BN_MASK2;
+ l= *(f++);
+ *(t++) =(tmp|(l<<lb))&BN_MASK2;
+ }
+ *(t++) =(l>>rb)&BN_MASK2;
+ }
+ *t=0;
+ bn_fix_top(r);
+ return(1);
+ }
diff --git a/lib/dns/sec/openssl/bn_sqr.c b/lib/dns/sec/openssl/bn_sqr.c
new file mode 100644
index 00000000..12cce4d7
--- /dev/null
+++ b/lib/dns/sec/openssl/bn_sqr.c
@@ -0,0 +1,281 @@
+/* crypto/bn/bn_sqr.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/* r must not be a */
+/* I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96 */
+int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx)
+ {
+ int max,al;
+ BIGNUM *tmp,*rr;
+
+#ifdef BN_COUNT
+printf("BN_sqr %d * %d\n",a->top,a->top);
+#endif
+ bn_check_top(a);
+ tmp= &(ctx->bn[ctx->tos]);
+ rr=(a != r)?r: (&ctx->bn[ctx->tos+1]);
+
+ al=a->top;
+ if (al <= 0)
+ {
+ r->top=0;
+ return(1);
+ }
+
+ max=(al+al);
+ if (bn_wexpand(rr,max+1) == NULL) return(0);
+
+ r->neg=0;
+ if (al == 4)
+ {
+#ifndef BN_SQR_COMBA
+ BN_ULONG t[8];
+ bn_sqr_normal(rr->d,a->d,4,t);
+#else
+ bn_sqr_comba4(rr->d,a->d);
+#endif
+ }
+ else if (al == 8)
+ {
+#ifndef BN_SQR_COMBA
+ BN_ULONG t[16];
+ bn_sqr_normal(rr->d,a->d,8,t);
+#else
+ bn_sqr_comba8(rr->d,a->d);
+#endif
+ }
+ else
+ {
+#if defined(BN_RECURSION)
+ if (al < BN_SQR_RECURSIVE_SIZE_NORMAL)
+ {
+ BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL*2];
+ bn_sqr_normal(rr->d,a->d,al,t);
+ }
+ else
+ {
+ int j,k;
+
+ j=BN_num_bits_word((BN_ULONG)al);
+ j=1<<(j-1);
+ k=j+j;
+ if (al == j)
+ {
+ if (bn_wexpand(a,k*2) == NULL) return(0);
+ if (bn_wexpand(tmp,k*2) == NULL) return(0);
+ bn_sqr_recursive(rr->d,a->d,al,tmp->d);
+ }
+ else
+ {
+ if (bn_wexpand(tmp,max) == NULL) return(0);
+ bn_sqr_normal(rr->d,a->d,al,tmp->d);
+ }
+ }
+#else
+ if (bn_wexpand(tmp,max) == NULL) return(0);
+ bn_sqr_normal(rr->d,a->d,al,tmp->d);
+#endif
+ }
+
+ rr->top=max;
+ if ((max > 0) && (rr->d[max-1] == 0)) rr->top--;
+ if (rr != r) BN_copy(r,rr);
+ return(1);
+ }
+
+/* tmp must have 2*n words */
+void bn_sqr_normal(BN_ULONG *r, BN_ULONG *a, int n, BN_ULONG *tmp)
+ {
+ int i,j,max;
+ BN_ULONG *ap,*rp;
+
+ max=n*2;
+ ap=a;
+ rp=r;
+ rp[0]=rp[max-1]=0;
+ rp++;
+ j=n;
+
+ if (--j > 0)
+ {
+ ap++;
+ rp[j]=bn_mul_words(rp,ap,j,ap[-1]);
+ rp+=2;
+ }
+
+ for (i=n-2; i>0; i--)
+ {
+ j--;
+ ap++;
+ rp[j]=bn_mul_add_words(rp,ap,j,ap[-1]);
+ rp+=2;
+ }
+
+ bn_add_words(r,r,r,max);
+
+ /* There will not be a carry */
+
+ bn_sqr_words(tmp,a,n);
+
+ bn_add_words(r,r,tmp,max);
+ }
+
+#ifdef BN_RECURSION
+/* r is 2*n words in size,
+ * a and b are both n words in size.
+ * n must be a power of 2.
+ * We multiply and return the result.
+ * t must be 2*n words in size
+ * We calulate
+ * a[0]*b[0]
+ * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
+ * a[1]*b[1]
+ */
+void bn_sqr_recursive(BN_ULONG *r, BN_ULONG *a, int n2, BN_ULONG *t)
+ {
+ int n=n2/2;
+ int zero,c1;
+ BN_ULONG ln,lo,*p;
+
+#ifdef BN_COUNT
+printf(" bn_sqr_recursive %d * %d\n",n2,n2);
+#endif
+ if (n2 == 4)
+ {
+#ifndef BN_SQR_COMBA
+ bn_sqr_normal(r,a,4,t);
+#else
+ bn_sqr_comba4(r,a);
+#endif
+ return;
+ }
+ else if (n2 == 8)
+ {
+#ifndef BN_SQR_COMBA
+ bn_sqr_normal(r,a,8,t);
+#else
+ bn_sqr_comba8(r,a);
+#endif
+ return;
+ }
+ if (n2 < BN_SQR_RECURSIVE_SIZE_NORMAL)
+ {
+ bn_sqr_normal(r,a,n2,t);
+ return;
+ }
+ /* r=(a[0]-a[1])*(a[1]-a[0]) */
+ c1=bn_cmp_words(a,&(a[n]),n);
+ zero=0;
+ if (c1 > 0)
+ bn_sub_words(t,a,&(a[n]),n);
+ else if (c1 < 0)
+ bn_sub_words(t,&(a[n]),a,n);
+ else
+ zero=1;
+
+ /* The result will always be negative unless it is zero */
+ p= &(t[n2*2]);
+
+ if (!zero)
+ bn_sqr_recursive(&(t[n2]),t,n,p);
+ else
+ memset(&(t[n2]),0,n*sizeof(BN_ULONG));
+ bn_sqr_recursive(r,a,n,p);
+ bn_sqr_recursive(&(r[n2]),&(a[n]),n,p);
+
+ /* t[32] holds (a[0]-a[1])*(a[1]-a[0]), it is negative or zero
+ * r[10] holds (a[0]*b[0])
+ * r[32] holds (b[1]*b[1])
+ */
+
+ c1=(int)(bn_add_words(t,r,&(r[n2]),n2));
+
+ /* t[32] is negative */
+ c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2));
+
+ /* t[32] holds (a[0]-a[1])*(a[1]-a[0])+(a[0]*a[0])+(a[1]*a[1])
+ * r[10] holds (a[0]*a[0])
+ * r[32] holds (a[1]*a[1])
+ * c1 holds the carry bits
+ */
+ c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2));
+ if (c1)
+ {
+ p= &(r[n+n2]);
+ lo= *p;
+ ln=(lo+c1)&BN_MASK2;
+ *p=ln;
+
+ /* The overflow will stop before we over write
+ * words we should not overwrite */
+ if (ln < (BN_ULONG)c1)
+ {
+ do {
+ p++;
+ lo= *p;
+ ln=(lo+1)&BN_MASK2;
+ *p=ln;
+ } while (ln == 0);
+ }
+ }
+ }
+#endif
diff --git a/lib/dns/sec/openssl/bn_word.c b/lib/dns/sec/openssl/bn_word.c
new file mode 100644
index 00000000..c0cfbc67
--- /dev/null
+++ b/lib/dns/sec/openssl/bn_word.c
@@ -0,0 +1,194 @@
+/* crypto/bn/bn_word.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+BN_ULONG BN_mod_word(BIGNUM *a, BN_ULONG w)
+ {
+#ifndef BN_LLONG
+ BN_ULONG ret=0;
+#else
+ BN_ULLONG ret=0;
+#endif
+ int i;
+
+ w&=BN_MASK2;
+ for (i=a->top-1; i>=0; i--)
+ {
+#ifndef BN_LLONG
+ ret=((ret<<BN_BITS4)|((a->d[i]>>BN_BITS4)&BN_MASK2l))%w;
+ ret=((ret<<BN_BITS4)|(a->d[i]&BN_MASK2l))%w;
+#else
+ ret=(BN_ULLONG)(((ret<<(BN_ULLONG)BN_BITS2)|a->d[i])%
+ (BN_ULLONG)w);
+#endif
+ }
+ return((BN_ULONG)ret);
+ }
+
+BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w)
+ {
+ BN_ULONG ret;
+ int i;
+
+ if (a->top == 0) return(0);
+ ret=0;
+ w&=BN_MASK2;
+ for (i=a->top-1; i>=0; i--)
+ {
+ BN_ULONG l,d;
+
+ l=a->d[i];
+ d=bn_div_words(ret,l,w);
+ ret=(l-((d*w)&BN_MASK2))&BN_MASK2;
+ a->d[i]=d;
+ }
+ if ((a->top > 0) && (a->d[a->top-1] == 0))
+ a->top--;
+ return(ret);
+ }
+
+int BN_add_word(BIGNUM *a, BN_ULONG w)
+ {
+ BN_ULONG l;
+ int i;
+
+ if (a->neg)
+ {
+ a->neg=0;
+ i=BN_sub_word(a,w);
+ if (!BN_is_zero(a))
+ a->neg=1;
+ return(i);
+ }
+ w&=BN_MASK2;
+ if (bn_wexpand(a,a->top+1) == NULL) return(0);
+ i=0;
+ for (;;)
+ {
+ l=(a->d[i]+(BN_ULONG)w)&BN_MASK2;
+ a->d[i]=l;
+ if (w > l)
+ w=1;
+ else
+ break;
+ i++;
+ }
+ if (i >= a->top)
+ a->top++;
+ return(1);
+ }
+
+int BN_sub_word(BIGNUM *a, BN_ULONG w)
+ {
+ int i;
+
+ if (a->neg)
+ {
+ a->neg=0;
+ i=BN_add_word(a,w);
+ a->neg=1;
+ return(i);
+ }
+
+ w&=BN_MASK2;
+ if ((a->top == 1) && (a->d[0] < w))
+ {
+ a->d[0]=w-a->d[0];
+ a->neg=1;
+ return(1);
+ }
+ i=0;
+ for (;;)
+ {
+ if (a->d[i] >= w)
+ {
+ a->d[i]-=w;
+ break;
+ }
+ else
+ {
+ a->d[i]=(a->d[i]-w)&BN_MASK2;
+ i++;
+ w=1;
+ }
+ }
+ if ((a->d[i] == 0) && (i == (a->top-1)))
+ a->top--;
+ return(1);
+ }
+
+int BN_mul_word(BIGNUM *a, BN_ULONG w)
+ {
+ BN_ULONG ll;
+
+ w&=BN_MASK2;
+ if (a->top)
+ {
+ ll=bn_mul_words(a->d,a->d,a->top,w);
+ if (ll)
+ {
+ if (bn_wexpand(a,a->top+1) == NULL) return(0);
+ a->d[a->top++]=ll;
+ }
+ }
+ return(1);
+ }
+
diff --git a/lib/dns/sec/openssl/buffer.c b/lib/dns/sec/openssl/buffer.c
new file mode 100644
index 00000000..c3a108ea
--- /dev/null
+++ b/lib/dns/sec/openssl/buffer.c
@@ -0,0 +1,144 @@
+/* crypto/buffer/buffer.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+
+BUF_MEM *BUF_MEM_new(void)
+ {
+ BUF_MEM *ret;
+
+ ret=Malloc(sizeof(BUF_MEM));
+ if (ret == NULL)
+ {
+ BUFerr(BUF_F_BUF_MEM_NEW,ERR_R_MALLOC_FAILURE);
+ return(NULL);
+ }
+ ret->length=0;
+ ret->max=0;
+ ret->data=NULL;
+ return(ret);
+ }
+
+void BUF_MEM_free(BUF_MEM *a)
+ {
+ if(a == NULL)
+ return;
+
+ if (a->data != NULL)
+ {
+ memset(a->data,0,(unsigned int)a->max);
+ Free(a->data);
+ }
+ Free(a);
+ }
+
+int BUF_MEM_grow(BUF_MEM *str, int len)
+ {
+ char *ret;
+ unsigned int n;
+
+ if (str->length >= len)
+ {
+ str->length=len;
+ return(len);
+ }
+ if (str->max >= len)
+ {
+ memset(&str->data[str->length],0,len-str->length);
+ str->length=len;
+ return(len);
+ }
+ n=(len+3)/3*4;
+ if (str->data == NULL)
+ ret=Malloc(n);
+ else
+ ret=Realloc(str->data,n);
+ if (ret == NULL)
+ {
+ BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE);
+ len=0;
+ }
+ else
+ {
+ str->data=ret;
+ str->length=len;
+ str->max=n;
+ }
+ return(len);
+ }
+
+char *BUF_strdup(const char *str)
+ {
+ char *ret;
+ int n;
+
+ if (str == NULL) return(NULL);
+
+ n=strlen(str);
+ ret=Malloc(n+1);
+ if (ret == NULL)
+ {
+ BUFerr(BUF_F_BUF_STRDUP,ERR_R_MALLOC_FAILURE);
+ return(NULL);
+ }
+ memcpy(ret,str,n+1);
+ return(ret);
+ }
+
diff --git a/lib/dns/sec/openssl/cryptlib.c b/lib/dns/sec/openssl/cryptlib.c
new file mode 100644
index 00000000..be5e68eb
--- /dev/null
+++ b/lib/dns/sec/openssl/cryptlib.c
@@ -0,0 +1,296 @@
+/* crypto/cryptlib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/crypto.h>
+/*#include "date.h"*/
+
+#if defined(WIN32) || defined(WIN16)
+static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */
+#endif
+
+/* real #defines in crypto.h, keep these upto date */
+static const char* lock_names[CRYPTO_NUM_LOCKS] =
+ {
+ "<<ERROR>>",
+ "err",
+ "err_hash",
+ "x509",
+ "x509_info",
+ "x509_pkey",
+ "x509_crl",
+ "x509_req",
+ "dsa",
+ "rsa",
+ "evp_pkey",
+ "x509_store",
+ "ssl_ctx",
+ "ssl_cert",
+ "ssl_session",
+ "ssl_sess_cert",
+ "ssl",
+ "rand",
+ "debug_malloc",
+ "BIO",
+ "gethostbyname",
+ "getservbyname",
+ "readdir",
+ "RSA_blinding",
+#if CRYPTO_NUM_LOCKS != 24
+# error "Inconsistency between crypto.h and cryptlib.c"
+#endif
+ };
+
+static STACK *app_locks=NULL;
+
+static void (MS_FAR *locking_callback)(int mode,int type,
+ const char *file,int line)=NULL;
+static int (MS_FAR *add_lock_callback)(int *pointer,int amount,
+ int type,const char *file,int line)=NULL;
+static unsigned long (MS_FAR *id_callback)(void)=NULL;
+int CRYPTO_get_new_lockid(char *name)
+ {
+ char *str;
+ int i;
+
+ /* A hack to make Visual C++ 5.0 work correctly when linking as
+ * a DLL using /MT. Without this, the application cannot use
+ * and floating point printf's.
+ * It also seems to be needed for Visual C 1.5 (win16) */
+#if defined(WIN32) || defined(WIN16)
+ SSLeay_MSVC5_hack=(double)name[0]*(double)name[1];
+#endif
+
+ if ((app_locks == NULL) && ((app_locks=sk_new_null()) == NULL))
+ {
+ CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
+ return(0);
+ }
+ if ((str=BUF_strdup(name)) == NULL)
+ return(0);
+ i=sk_push(app_locks,str);
+ if (!i)
+ Free(str);
+ else
+ i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */
+ return(i);
+ }
+
+void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file,
+ int line)
+ {
+ return(locking_callback);
+ }
+
+int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
+ const char *file,int line)
+ {
+ return(add_lock_callback);
+ }
+
+void CRYPTO_set_locking_callback(void (*func)(int mode,int type,
+ const char *file,int line))
+ {
+ locking_callback=func;
+ }
+
+void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type,
+ const char *file,int line))
+ {
+ add_lock_callback=func;
+ }
+
+unsigned long (*CRYPTO_get_id_callback(void))(void)
+ {
+ return(id_callback);
+ }
+
+void CRYPTO_set_id_callback(unsigned long (*func)(void))
+ {
+ id_callback=func;
+ }
+
+unsigned long CRYPTO_thread_id(void)
+ {
+ unsigned long ret=0;
+
+ if (id_callback == NULL)
+ {
+#ifdef WIN16
+ ret=(unsigned long)GetCurrentTask();
+#elif defined(WIN32)
+ ret=(unsigned long)GetCurrentThreadId();
+#elif defined(MSDOS)
+ ret=1L;
+#else
+ ret=(unsigned long)getpid();
+#endif
+ }
+ else
+ ret=id_callback();
+ return(ret);
+ }
+
+void CRYPTO_lock(int mode, int type, const char *file, int line)
+ {
+#ifdef LOCK_DEBUG
+ {
+ char *rw_text,*operation_text;
+
+ if (mode & CRYPTO_LOCK)
+ operation_text="lock ";
+ else if (mode & CRYPTO_UNLOCK)
+ operation_text="unlock";
+ else
+ operation_text="ERROR ";
+
+ if (mode & CRYPTO_READ)
+ rw_text="r";
+ else if (mode & CRYPTO_WRITE)
+ rw_text="w";
+ else
+ rw_text="ERROR";
+
+ fprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%d\n",
+ CRYPTO_thread_id(), rw_text, operation_text,
+ CRYPTO_get_lock_name(type), file, line);
+ }
+#endif
+ if (locking_callback != NULL)
+ locking_callback(mode,type,file,line);
+ }
+
+int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
+ int line)
+ {
+ int ret;
+
+ if (add_lock_callback != NULL)
+ {
+#ifdef LOCK_DEBUG
+ int before= *pointer;
+#endif
+
+ ret=add_lock_callback(pointer,amount,type,file,line);
+#ifdef LOCK_DEBUG
+ fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
+ CRYPTO_thread_id(),
+ before,amount,ret,
+ CRYPTO_get_lock_name(type),
+ file,line);
+#endif
+ *pointer=ret;
+ }
+ else
+ {
+ CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,file,line);
+
+ ret= *pointer+amount;
+#ifdef LOCK_DEBUG
+ fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
+ CRYPTO_thread_id(),
+ *pointer,amount,ret,
+ CRYPTO_get_lock_name(type),
+ file,line);
+#endif
+ *pointer=ret;
+ CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line);
+ }
+ return(ret);
+ }
+
+const char *CRYPTO_get_lock_name(int type)
+ {
+ if (type < 0)
+ return("ERROR");
+ else if (type < CRYPTO_NUM_LOCKS)
+ return(lock_names[type]);
+ else if (type-CRYPTO_NUM_LOCKS >= sk_num(app_locks))
+ return("ERROR");
+ else
+ return(sk_value(app_locks,type-CRYPTO_NUM_LOCKS));
+ }
+
+#ifdef _DLL
+#ifdef WIN32
+
+/* All we really need to do is remove the 'error' state when a thread
+ * detaches */
+
+BOOL WINAPI DLLEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason,
+ LPVOID lpvReserved)
+ {
+ switch(fdwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ break;
+ case DLL_THREAD_ATTACH:
+ break;
+ case DLL_THREAD_DETACH:
+ ERR_remove_state(0);
+ break;
+ case DLL_PROCESS_DETACH:
+ break;
+ }
+ return(TRUE);
+ }
+#endif
+
+#endif
diff --git a/lib/dns/sec/openssl/cryptlib.h b/lib/dns/sec/openssl/cryptlib.h
new file mode 100644
index 00000000..e3d38524
--- /dev/null
+++ b/lib/dns/sec/openssl/cryptlib.h
@@ -0,0 +1,96 @@
+/* crypto/cryptlib.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_CRYPTLIB_H
+#define HEADER_CRYPTLIB_H
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "openssl/e_os.h"
+
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/opensslconf.h>
+
+#ifndef VMS
+#define X509_CERT_AREA OPENSSLDIR
+#define X509_CERT_DIR OPENSSLDIR "/certs"
+#define X509_CERT_FILE OPENSSLDIR "/cert.pem"
+#define X509_PRIVATE_DIR OPENSSLDIR "/private"
+#else
+#define X509_CERT_AREA "SSLROOT:[000000]"
+#define X509_CERT_DIR "SSLCERTS:"
+#define X509_CERT_FILE "SSLCERTS:cert.pem"
+#define X509_PRIVATE_DIR "SSLPRIVATE:"
+#endif
+
+#define X509_CERT_DIR_EVP "SSL_CERT_DIR"
+#define X509_CERT_FILE_EVP "SSL_CERT_FILE"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/dns/sec/openssl/dh_err.c b/lib/dns/sec/openssl/dh_err.c
new file mode 100644
index 00000000..0348bd24
--- /dev/null
+++ b/lib/dns/sec/openssl/dh_err.c
@@ -0,0 +1,98 @@
+/* crypto/dh/dh_err.c */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/dh.h>
+
+/* BEGIN ERROR CODES */
+#ifndef NO_ERR
+static ERR_STRING_DATA DH_str_functs[]=
+ {
+{ERR_PACK(0,DH_F_DHPARAMS_PRINT,0), "DHparams_print"},
+{ERR_PACK(0,DH_F_DHPARAMS_PRINT_FP,0), "DHparams_print_fp"},
+{ERR_PACK(0,DH_F_DH_COMPUTE_KEY,0), "DH_compute_key"},
+{ERR_PACK(0,DH_F_DH_GENERATE_KEY,0), "DH_generate_key"},
+{ERR_PACK(0,DH_F_DH_GENERATE_PARAMETERS,0), "DH_generate_parameters"},
+{ERR_PACK(0,DH_F_DH_NEW,0), "DH_new"},
+{0,NULL}
+ };
+
+static ERR_STRING_DATA DH_str_reasons[]=
+ {
+{DH_R_NO_PRIVATE_VALUE ,"no private value"},
+{0,NULL}
+ };
+
+#endif
+
+void ERR_load_DH_strings(void)
+ {
+ static int init=1;
+
+ if (init)
+ {
+ init=0;
+#ifndef NO_ERR
+ ERR_load_strings(ERR_LIB_DH,DH_str_functs);
+ ERR_load_strings(ERR_LIB_DH,DH_str_reasons);
+#endif
+
+ }
+ }
diff --git a/lib/dns/sec/openssl/dh_gen.c b/lib/dns/sec/openssl/dh_gen.c
new file mode 100644
index 00000000..b7bcd2c7
--- /dev/null
+++ b/lib/dns/sec/openssl/dh_gen.c
@@ -0,0 +1,148 @@
+/* crypto/dh/dh_gen.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+
+/* We generate DH parameters as follows
+ * find a prime q which is prime_len/2 bits long.
+ * p=(2*q)+1 or (p-1)/2 = q
+ * For this case, g is a generator if
+ * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1.
+ * Since the factors of p-1 are q and 2, we just need to check
+ * g^2 mod p != 1 and g^q mod p != 1.
+ *
+ * Having said all that,
+ * there is another special case method for the generators 2, 3 and 5.
+ * for 2, p mod 24 == 11
+ * for 3, p mod 12 == 5 <<<<< does not work for strong primes.
+ * for 5, p mod 10 == 3 or 7
+ *
+ * Thanks to Phil Karn <karn@qualcomm.com> for the pointers about the
+ * special generators and for answering some of my questions.
+ *
+ * I've implemented the second simple method :-).
+ * Since DH should be using a strong prime (both p and q are prime),
+ * this generator function can take a very very long time to run.
+ */
+
+DH *DH_generate_parameters(int prime_len, int generator,
+ void (*callback)(int,int,void *), void *cb_arg)
+ {
+ BIGNUM *p=NULL,*t1,*t2;
+ DH *ret=NULL;
+ int g,ok= -1;
+ BN_CTX *ctx=NULL;
+
+ ret=DH_new();
+ if (ret == NULL) goto err;
+ ctx=BN_CTX_new();
+ if (ctx == NULL) goto err;
+ t1= &(ctx->bn[0]);
+ t2= &(ctx->bn[1]);
+ ctx->tos=2;
+
+ if (generator == DH_GENERATOR_2)
+ {
+ BN_set_word(t1,24);
+ BN_set_word(t2,11);
+ g=2;
+ }
+#ifdef undef /* does not work for strong primes */
+ else if (generator == DH_GENERATOR_3)
+ {
+ BN_set_word(t1,12);
+ BN_set_word(t2,5);
+ g=3;
+ }
+#endif
+ else if (generator == DH_GENERATOR_5)
+ {
+ BN_set_word(t1,10);
+ BN_set_word(t2,3);
+ /* BN_set_word(t3,7); just have to miss
+ * out on these ones :-( */
+ g=5;
+ }
+ else
+ g=generator;
+
+ p=BN_generate_prime(NULL,prime_len,1,t1,t2,callback,cb_arg);
+ if (p == NULL) goto err;
+ if (callback != NULL) callback(3,0,cb_arg);
+ ret->p=p;
+ ret->g=BN_new();
+ if (!BN_set_word(ret->g,g)) goto err;
+ ok=1;
+err:
+ if (ok == -1)
+ {
+ DHerr(DH_F_DH_GENERATE_PARAMETERS,ERR_R_BN_LIB);
+ ok=0;
+ }
+
+ if (ctx != NULL) BN_CTX_free(ctx);
+ if (!ok && (ret != NULL))
+ {
+ DH_free(ret);
+ ret=NULL;
+ }
+ return(ret);
+ }
diff --git a/lib/dns/sec/openssl/dh_key.c b/lib/dns/sec/openssl/dh_key.c
new file mode 100644
index 00000000..cede53bf
--- /dev/null
+++ b/lib/dns/sec/openssl/dh_key.c
@@ -0,0 +1,154 @@
+/* crypto/dh/dh_key.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#include <openssl/dh.h>
+
+int DH_generate_key(DH *dh)
+ {
+ int ok=0;
+ unsigned int i;
+ BN_CTX ctx;
+ BN_MONT_CTX *mont;
+ BIGNUM *pub_key=NULL,*priv_key=NULL;
+
+ BN_CTX_init(&ctx);
+
+ if (dh->priv_key == NULL)
+ {
+ i=dh->length;
+ if (i == 0)
+ {
+ /* Make the number p-1 bits long */
+ i=BN_num_bits(dh->p)-1;
+ }
+ priv_key=BN_new();
+ if (priv_key == NULL) goto err;
+ if (!BN_rand(priv_key,i,0,0)) goto err;
+ }
+ else
+ priv_key=dh->priv_key;
+
+ if (dh->pub_key == NULL)
+ {
+ pub_key=BN_new();
+ if (pub_key == NULL) goto err;
+ }
+ else
+ pub_key=dh->pub_key;
+
+ if ((dh->method_mont_p == NULL) && (dh->flags & DH_FLAG_CACHE_MONT_P))
+ {
+ if ((dh->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
+ if (!BN_MONT_CTX_set((BN_MONT_CTX *)dh->method_mont_p,
+ dh->p,&ctx)) goto err;
+ }
+ mont=(BN_MONT_CTX *)dh->method_mont_p;
+
+ if (!BN_mod_exp_mont(pub_key,dh->g,priv_key,dh->p,&ctx,mont)) goto err;
+
+ dh->pub_key=pub_key;
+ dh->priv_key=priv_key;
+ ok=1;
+err:
+ if (ok != 1)
+ DHerr(DH_F_DH_GENERATE_KEY,ERR_R_BN_LIB);
+
+ if ((pub_key != NULL) && (dh->pub_key == NULL)) BN_free(pub_key);
+ if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key);
+ BN_CTX_free(&ctx);
+ return(ok);
+ }
+
+int DH_compute_key(unsigned char *key, BIGNUM *pub_key, DH *dh)
+ {
+ BN_CTX ctx;
+ BN_MONT_CTX *mont;
+ BIGNUM *tmp;
+ int ret= -1;
+
+ BN_CTX_init(&ctx);
+ tmp= &(ctx.bn[ctx.tos++]);
+
+ if (dh->priv_key == NULL)
+ {
+ DHerr(DH_F_DH_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE);
+ goto err;
+ }
+ if ((dh->method_mont_p == NULL) && (dh->flags & DH_FLAG_CACHE_MONT_P))
+ {
+ if ((dh->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
+ if (!BN_MONT_CTX_set((BN_MONT_CTX *)dh->method_mont_p,
+ dh->p,&ctx)) goto err;
+ }
+
+ mont=(BN_MONT_CTX *)dh->method_mont_p;
+ if (!BN_mod_exp_mont(tmp,pub_key,dh->priv_key,dh->p,&ctx,mont))
+ {
+ DHerr(DH_F_DH_COMPUTE_KEY,ERR_R_BN_LIB);
+ goto err;
+ }
+
+ ret=BN_bn2bin(tmp,key);
+err:
+ BN_CTX_free(&ctx);
+ return(ret);
+ }
diff --git a/lib/dns/sec/openssl/dh_lib.c b/lib/dns/sec/openssl/dh_lib.c
new file mode 100644
index 00000000..61e0720e
--- /dev/null
+++ b/lib/dns/sec/openssl/dh_lib.c
@@ -0,0 +1,103 @@
+/* crypto/dh/dh_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+
+const char *DH_version="Diffie-Hellman" OPENSSL_VERSION_PTEXT;
+
+DH *DH_new(void)
+ {
+ DH *ret;
+
+ ret=(DH *)Malloc(sizeof(DH));
+ if (ret == NULL)
+ {
+ DHerr(DH_F_DH_NEW,ERR_R_MALLOC_FAILURE);
+ return(NULL);
+ }
+ ret->pad=0;
+ ret->version=0;
+ ret->p=NULL;
+ ret->g=NULL;
+ ret->length=0;
+ ret->pub_key=NULL;
+ ret->priv_key=NULL;
+ ret->flags=DH_FLAG_CACHE_MONT_P;
+ ret->method_mont_p=NULL;
+ return(ret);
+ }
+
+void DH_free(DH *r)
+ {
+ if(r == NULL) return;
+ if (r->p != NULL) BN_clear_free(r->p);
+ if (r->g != NULL) BN_clear_free(r->g);
+ if (r->pub_key != NULL) BN_clear_free(r->pub_key);
+ if (r->priv_key != NULL) BN_clear_free(r->priv_key);
+ if (r->method_mont_p != NULL)
+ BN_MONT_CTX_free((BN_MONT_CTX *)r->method_mont_p);
+ Free(r);
+ }
+
+int DH_size(DH *dh)
+ {
+ return(BN_num_bytes(dh->p));
+ }
diff --git a/lib/dns/sec/openssl/dsa_asn1.c b/lib/dns/sec/openssl/dsa_asn1.c
new file mode 100644
index 00000000..3bc02163
--- /dev/null
+++ b/lib/dns/sec/openssl/dsa_asn1.c
@@ -0,0 +1,99 @@
+/* crypto/dsa/dsa_asn1.c */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/dsa.h>
+/*#include <openssl/asn1.h>*/
+/*#include <openssl/asn1_mac.h>*/
+
+DSA_SIG *DSA_SIG_new(void)
+{
+ DSA_SIG *ret;
+
+ ret = Malloc(sizeof(DSA_SIG));
+ if (ret == NULL)
+ {
+ DSAerr(DSA_F_DSA_SIG_NEW,ERR_R_MALLOC_FAILURE);
+ return(NULL);
+ }
+ ret->r = NULL;
+ ret->s = NULL;
+ return(ret);
+}
+
+void DSA_SIG_free(DSA_SIG *r)
+{
+ if (r == NULL) return;
+ if (r->r) BN_clear_free(r->r);
+ if (r->s) BN_clear_free(r->s);
+ Free(r);
+}
+
+#if 0
+/* BEW */
+int i2d_DSA_SIG(DSA_SIG *v, unsigned char **pp)
+{
+ int t=0,len;
+ ASN1_INTEGER rbs,sbs;
+ unsigned char *p;
+
+ rbs.data=Malloc(BN_num_bits(v->r)/8+1);
+ if (rbs.data == NULL)
+ {
+ DSAerr(DSA_F_I2D_DSA_SIG, ERR_R_MALLOC_FAILURE);
+ return(0);
+ }
+ rbs.type=V_ASN1_INTEGER;
+ rbs.length=BN_bn2bin(v->r,rbs.data);
+ sbs.data=Malloc(BN_num_bits(v->s)/8+1);
+ if (sbs.data == NULL)
+ {
+ Free(rbs.data);
+ DSAerr(DSA_F_I2D_DSA_SIG, ERR_R_MALLOC_FAILURE);
+ return(0);
+ }
+ sbs.type=V_ASN1_INTEGER;
+ sbs.length=BN_bn2bin(v->s,sbs.data);
+
+ len=i2d_ASN1_INTEGER(&rbs,NULL);
+ len+=i2d_ASN1_INTEGER(&sbs,NULL);
+
+ if (pp)
+ {
+ p=*pp;
+ ASN1_put_object(&p,1,len,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
+ i2d_ASN1_INTEGER(&rbs,&p);
+ i2d_ASN1_INTEGER(&sbs,&p);
+ }
+ t=ASN1_object_size(1,len,V_ASN1_SEQUENCE);
+ Free(rbs.data);
+ Free(sbs.data);
+ return(t);
+}
+
+DSA_SIG *d2i_DSA_SIG(DSA_SIG **a, unsigned char **pp, long length)
+{
+ int i=ERR_R_NESTED_ASN1_ERROR;
+ ASN1_INTEGER *bs=NULL;
+ M_ASN1_D2I_vars(a,DSA_SIG *,DSA_SIG_new);
+
+ M_ASN1_D2I_Init();
+ M_ASN1_D2I_start_sequence();
+ M_ASN1_D2I_get(bs,d2i_ASN1_INTEGER);
+ if ((ret->r=BN_bin2bn(bs->data,bs->length,ret->r)) == NULL)
+ goto err_bn;
+ M_ASN1_D2I_get(bs,d2i_ASN1_INTEGER);
+ if ((ret->s=BN_bin2bn(bs->data,bs->length,ret->s)) == NULL)
+ goto err_bn;
+ ASN1_BIT_STRING_free(bs);
+ M_ASN1_D2I_Finish_2(a);
+
+err_bn:
+ i=ERR_R_BN_LIB;
+err:
+ DSAerr(DSA_F_D2I_DSA_SIG,i);
+ if ((ret != NULL) && ((a == NULL) || (*a != ret))) DSA_SIG_free(ret);
+ if (bs != NULL) ASN1_BIT_STRING_free(bs);
+ return(NULL);
+}
+#endif
diff --git a/lib/dns/sec/openssl/dsa_err.c b/lib/dns/sec/openssl/dsa_err.c
new file mode 100644
index 00000000..33a8270a
--- /dev/null
+++ b/lib/dns/sec/openssl/dsa_err.c
@@ -0,0 +1,106 @@
+/* crypto/dsa/dsa_err.c */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/dsa.h>
+
+/* BEGIN ERROR CODES */
+#ifndef NO_ERR
+static ERR_STRING_DATA DSA_str_functs[]=
+ {
+{ERR_PACK(0,DSA_F_D2I_DSA_SIG,0), "d2i_DSA_SIG"},
+{ERR_PACK(0,DSA_F_DSAPARAMS_PRINT,0), "DSAparams_print"},
+{ERR_PACK(0,DSA_F_DSAPARAMS_PRINT_FP,0), "DSAparams_print_fp"},
+{ERR_PACK(0,DSA_F_DSA_DO_SIGN,0), "DSA_do_sign"},
+{ERR_PACK(0,DSA_F_DSA_DO_VERIFY,0), "DSA_do_verify"},
+{ERR_PACK(0,DSA_F_DSA_IS_PRIME,0), "DSA_is_prime"},
+{ERR_PACK(0,DSA_F_DSA_NEW,0), "DSA_new"},
+{ERR_PACK(0,DSA_F_DSA_PRINT,0), "DSA_print"},
+{ERR_PACK(0,DSA_F_DSA_PRINT_FP,0), "DSA_print_fp"},
+{ERR_PACK(0,DSA_F_DSA_SIGN,0), "DSA_sign"},
+{ERR_PACK(0,DSA_F_DSA_SIGN_SETUP,0), "DSA_sign_setup"},
+{ERR_PACK(0,DSA_F_DSA_SIG_NEW,0), "DSA_SIG_new"},
+{ERR_PACK(0,DSA_F_DSA_VERIFY,0), "DSA_verify"},
+{ERR_PACK(0,DSA_F_I2D_DSA_SIG,0), "i2d_DSA_SIG"},
+{0,NULL}
+ };
+
+static ERR_STRING_DATA DSA_str_reasons[]=
+ {
+{DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE ,"data too large for key size"},
+{0,NULL}
+ };
+
+#endif
+
+void ERR_load_DSA_strings(void)
+ {
+ static int init=1;
+
+ if (init)
+ {
+ init=0;
+#ifndef NO_ERR
+ ERR_load_strings(ERR_LIB_DSA,DSA_str_functs);
+ ERR_load_strings(ERR_LIB_DSA,DSA_str_reasons);
+#endif
+
+ }
+ }
diff --git a/lib/dns/sec/openssl/dsa_gen.c b/lib/dns/sec/openssl/dsa_gen.c
new file mode 100644
index 00000000..b5e5ec06
--- /dev/null
+++ b/lib/dns/sec/openssl/dsa_gen.c
@@ -0,0 +1,333 @@
+/* crypto/dsa/dsa_gen.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#undef GENUINE_DSA
+
+#ifdef GENUINE_DSA
+#define HASH SHA
+#else
+#define HASH SHA1
+#endif
+
+#ifndef NO_SHA
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include <openssl/sha.h>
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/rand.h>
+
+DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len,
+ int *counter_ret, unsigned long *h_ret, void (*callback)(),
+ char *cb_arg)
+ {
+ int ok=0;
+ unsigned char seed[SHA_DIGEST_LENGTH];
+ unsigned char md[SHA_DIGEST_LENGTH];
+ unsigned char buf[SHA_DIGEST_LENGTH],buf2[SHA_DIGEST_LENGTH];
+ BIGNUM *r0,*W,*X,*c,*test;
+ BIGNUM *g=NULL,*q=NULL,*p=NULL;
+ BN_MONT_CTX *mont=NULL;
+ int k,n=0,i,b,m=0;
+ int counter=0;
+ BN_CTX *ctx=NULL,*ctx2=NULL;
+ unsigned int h=2;
+ DSA *ret=NULL;
+
+ if (bits < 512) bits=512;
+ bits=(bits+63)/64*64;
+
+ if ((seed_in != NULL) && (seed_len == 20))
+ memcpy(seed,seed_in,seed_len);
+
+ if ((ctx=BN_CTX_new()) == NULL) goto err;
+ if ((ctx2=BN_CTX_new()) == NULL) goto err;
+ if ((ret=DSA_new()) == NULL) goto err;
+
+ if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
+
+ r0= &(ctx2->bn[0]);
+ g= &(ctx2->bn[1]);
+ W= &(ctx2->bn[2]);
+ q= &(ctx2->bn[3]);
+ X= &(ctx2->bn[4]);
+ c= &(ctx2->bn[5]);
+ p= &(ctx2->bn[6]);
+ test= &(ctx2->bn[7]);
+
+ BN_lshift(test,BN_value_one(),bits-1);
+
+ for (;;)
+ {
+ for (;;)
+ {
+ /* step 1 */
+ if (callback != NULL) callback(0,m++,cb_arg);
+
+ if (!seed_len)
+ RAND_bytes(seed,SHA_DIGEST_LENGTH);
+ else
+ seed_len=0;
+
+ memcpy(buf,seed,SHA_DIGEST_LENGTH);
+ memcpy(buf2,seed,SHA_DIGEST_LENGTH);
+ for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--)
+ {
+ buf[i]++;
+ if (buf[i] != 0) break;
+ }
+
+ /* step 2 */
+ HASH(seed,SHA_DIGEST_LENGTH,md);
+ HASH(buf,SHA_DIGEST_LENGTH,buf2);
+ for (i=0; i<SHA_DIGEST_LENGTH; i++)
+ md[i]^=buf2[i];
+
+ /* step 3 */
+ md[0]|=0x80;
+ md[SHA_DIGEST_LENGTH-1]|=0x01;
+ if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,q)) abort();
+
+ /* step 4 */
+ if (DSA_is_prime(q,callback,cb_arg) > 0) break;
+ /* do a callback call */
+ /* step 5 */
+ }
+
+ if (callback != NULL) callback(2,0,cb_arg);
+ if (callback != NULL) callback(3,0,cb_arg);
+
+ /* step 6 */
+ counter=0;
+
+ n=(bits-1)/160;
+ b=(bits-1)-n*160;
+
+ for (;;)
+ {
+ /* step 7 */
+ BN_zero(W);
+ for (k=0; k<=n; k++)
+ {
+ for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--)
+ {
+ buf[i]++;
+ if (buf[i] != 0) break;
+ }
+
+ HASH(buf,SHA_DIGEST_LENGTH,md);
+
+ /* step 8 */
+ if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,r0)) abort();
+ BN_lshift(r0,r0,160*k);
+ BN_add(W,W,r0);
+ }
+
+ /* more of step 8 */
+ BN_mask_bits(W,bits-1);
+ BN_copy(X,W); /* this should be ok */
+ BN_add(X,X,test); /* this should be ok */
+
+ /* step 9 */
+ BN_lshift1(r0,q);
+ BN_mod(c,X,r0,ctx);
+ BN_sub(r0,c,BN_value_one());
+ BN_sub(p,X,r0);
+
+ /* step 10 */
+ if (BN_cmp(p,test) >= 0)
+ {
+ /* step 11 */
+ if (DSA_is_prime(p,callback,cb_arg) > 0)
+ goto end;
+ }
+
+ /* step 13 */
+ counter++;
+
+ /* step 14 */
+ if (counter >= 4096) break;
+
+ if (callback != NULL) callback(0,counter,cb_arg);
+ }
+ }
+end:
+ if (callback != NULL) callback(2,1,cb_arg);
+
+ /* We now need to gernerate g */
+ /* Set r0=(p-1)/q */
+ BN_sub(test,p,BN_value_one());
+ BN_div(r0,NULL,test,q,ctx);
+
+ BN_set_word(test,h);
+ BN_MONT_CTX_set(mont,p,ctx);
+
+ for (;;)
+ {
+ /* g=test^r0%p */
+ BN_mod_exp_mont(g,test,r0,p,ctx,mont);
+ if (!BN_is_one(g)) break;
+ BN_add(test,test,BN_value_one());
+ h++;
+ }
+
+ if (callback != NULL) callback(3,1,cb_arg);
+
+ ok=1;
+err:
+ if (!ok)
+ {
+ if (ret != NULL) DSA_free(ret);
+ }
+ else
+ {
+ ret->p=BN_dup(p);
+ ret->q=BN_dup(q);
+ ret->g=BN_dup(g);
+ if ((m > 1) && (seed_in != NULL)) memcpy(seed_in,seed,20);
+ if (counter_ret != NULL) *counter_ret=counter;
+ if (h_ret != NULL) *h_ret=h;
+ }
+ if (ctx != NULL) BN_CTX_free(ctx);
+ if (ctx != NULL) BN_CTX_free(ctx2);
+ if (mont != NULL) BN_MONT_CTX_free(mont);
+ return(ok?ret:NULL);
+ }
+
+int DSA_is_prime(BIGNUM *w, void (*callback)(), char *cb_arg)
+ {
+ int ok= -1,j,i,n;
+ BN_CTX *ctx=NULL,*ctx2=NULL;
+ BIGNUM *w_1,*b,*m,*z,*tmp,*mont_1;
+ int a;
+ BN_MONT_CTX *mont=NULL;
+
+ if (!BN_is_bit_set(w,0)) return(0);
+
+ if ((ctx=BN_CTX_new()) == NULL) goto err;
+ if ((ctx2=BN_CTX_new()) == NULL) goto err;
+ if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
+
+ m= &(ctx2->bn[2]);
+ b= &(ctx2->bn[3]);
+ z= &(ctx2->bn[4]);
+ w_1= &(ctx2->bn[5]);
+ tmp= &(ctx2->bn[6]);
+ mont_1= &(ctx2->bn[7]);
+
+ /* step 1 */
+ n=50;
+
+ /* step 2 */
+ if (!BN_sub(w_1,w,BN_value_one())) goto err;
+ for (a=1; !BN_is_bit_set(w_1,a); a++)
+ ;
+ if (!BN_rshift(m,w_1,a)) goto err;
+
+ BN_MONT_CTX_set(mont,w,ctx);
+ BN_to_montgomery(mont_1,BN_value_one(),mont,ctx);
+ BN_to_montgomery(w_1,w_1,mont,ctx);
+ for (i=1; i < n; i++)
+ {
+ /* step 3 */
+ BN_rand(b,BN_num_bits(w)-2/*-1*/,0,0);
+ /* BN_set_word(b,0x10001L); */
+
+ /* step 4 */
+ j=0;
+ if (!BN_mod_exp_mont(z,b,m,w,ctx,mont)) goto err;
+
+ if (!BN_to_montgomery(z,z,mont,ctx)) goto err;
+
+ /* step 5 */
+ for (;;)
+ {
+ if (((j == 0) && (BN_cmp(z,mont_1) == 0)) ||
+ (BN_cmp(z,w_1) == 0))
+ break;
+
+ /* step 6 */
+ if ((j > 0) && (BN_cmp(z,mont_1) == 0))
+ {
+ ok=0;
+ goto err;
+ }
+
+ j++;
+ if (j >= a)
+ {
+ ok=0;
+ goto err;
+ }
+
+ if (!BN_mod_mul_montgomery(z,z,z,mont,ctx)) goto err;
+ if (callback != NULL) callback(1,j,cb_arg);
+ }
+ }
+
+ ok=1;
+err:
+ if (ok == -1) DSAerr(DSA_F_DSA_IS_PRIME,ERR_R_BN_LIB);
+ BN_CTX_free(ctx);
+ BN_CTX_free(ctx2);
+ BN_MONT_CTX_free(mont);
+
+ return(ok);
+ }
+#endif
diff --git a/lib/dns/sec/openssl/dsa_key.c b/lib/dns/sec/openssl/dsa_key.c
new file mode 100644
index 00000000..ab7f38fc
--- /dev/null
+++ b/lib/dns/sec/openssl/dsa_key.c
@@ -0,0 +1,112 @@
+/* crypto/dsa/dsa_key.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef NO_SHA
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include <openssl/sha.h>
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/rand.h>
+
+int DSA_generate_key(DSA *dsa)
+ {
+ int ok=0;
+ unsigned int i;
+ BN_CTX *ctx=NULL;
+ BIGNUM *pub_key=NULL,*priv_key=NULL;
+
+ if ((ctx=BN_CTX_new()) == NULL) goto err;
+
+ if (dsa->priv_key == NULL)
+ {
+ if ((priv_key=BN_new()) == NULL) goto err;
+ }
+ else
+ priv_key=dsa->priv_key;
+
+ i=BN_num_bits(dsa->q);
+ for (;;)
+ {
+ BN_rand(priv_key,i,1,0);
+ if (BN_cmp(priv_key,dsa->q) >= 0)
+ BN_sub(priv_key,priv_key,dsa->q);
+ if (!BN_is_zero(priv_key)) break;
+ }
+
+ if (dsa->pub_key == NULL)
+ {
+ if ((pub_key=BN_new()) == NULL) goto err;
+ }
+ else
+ pub_key=dsa->pub_key;
+
+ if (!BN_mod_exp(pub_key,dsa->g,priv_key,dsa->p,ctx)) goto err;
+
+ dsa->priv_key=priv_key;
+ dsa->pub_key=pub_key;
+ ok=1;
+
+err:
+ if ((pub_key != NULL) && (dsa->pub_key == NULL)) BN_free(pub_key);
+ if ((priv_key != NULL) && (dsa->priv_key == NULL)) BN_free(priv_key);
+ if (ctx != NULL) BN_CTX_free(ctx);
+ return(ok);
+ }
+#endif
diff --git a/lib/dns/sec/openssl/dsa_lib.c b/lib/dns/sec/openssl/dsa_lib.c
new file mode 100644
index 00000000..6208b2a8
--- /dev/null
+++ b/lib/dns/sec/openssl/dsa_lib.c
@@ -0,0 +1,150 @@
+/* crypto/dsa/dsa_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+/*#include <openssl/asn1.h>*/
+
+const char *DSA_version="DSA" OPENSSL_VERSION_PTEXT;
+
+DSA *DSA_new(void)
+ {
+ DSA *ret;
+
+ ret=(DSA *)Malloc(sizeof(DSA));
+ if (ret == NULL)
+ {
+ DSAerr(DSA_F_DSA_NEW,ERR_R_MALLOC_FAILURE);
+ return(NULL);
+ }
+ ret->pad=0;
+ ret->version=0;
+ ret->write_params=1;
+ ret->p=NULL;
+ ret->q=NULL;
+ ret->g=NULL;
+ ret->flags=DSA_FLAG_CACHE_MONT_P;
+
+ ret->pub_key=NULL;
+ ret->priv_key=NULL;
+
+ ret->kinv=NULL;
+ ret->r=NULL;
+ ret->method_mont_p=NULL;
+
+ ret->references=1;
+ return(ret);
+ }
+
+void DSA_free(DSA *r)
+ {
+ int i;
+
+ if (r == NULL) return;
+
+ i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_DSA);
+#ifdef REF_PRINT
+ REF_PRINT("DSA",r);
+#endif
+ if (i > 0) return;
+#ifdef REF_CHECK
+ if (i < 0)
+ {
+ fprintf(stderr,"DSA_free, bad reference count\n");
+ abort();
+ }
+#endif
+
+ if (r->p != NULL) BN_clear_free(r->p);
+ if (r->q != NULL) BN_clear_free(r->q);
+ if (r->g != NULL) BN_clear_free(r->g);
+ if (r->pub_key != NULL) BN_clear_free(r->pub_key);
+ if (r->priv_key != NULL) BN_clear_free(r->priv_key);
+ if (r->kinv != NULL) BN_clear_free(r->kinv);
+ if (r->r != NULL) BN_clear_free(r->r);
+ if (r->method_mont_p != NULL)
+ BN_MONT_CTX_free((BN_MONT_CTX *)r->method_mont_p);
+ Free(r);
+ }
+
+#if 0
+/* BEW */
+int DSA_size(DSA *r)
+ {
+ int ret,i;
+ ASN1_INTEGER bs;
+ unsigned char buf[4];
+
+ i=BN_num_bits(r->q);
+ bs.length=(i+7)/8;
+ bs.data=buf;
+ bs.type=V_ASN1_INTEGER;
+ /* If the top bit is set the asn1 encoding is 1 larger. */
+ buf[0]=0xff;
+
+ i=i2d_ASN1_INTEGER(&bs,NULL);
+ i+=i; /* r and s */
+ ret=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
+ return(ret);
+ }
+#endif
+
diff --git a/lib/dns/sec/openssl/dsa_sign.c b/lib/dns/sec/openssl/dsa_sign.c
new file mode 100644
index 00000000..6d8a21d7
--- /dev/null
+++ b/lib/dns/sec/openssl/dsa_sign.c
@@ -0,0 +1,214 @@
+/* crypto/dsa/dsa_sign.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/rand.h>
+/*#include <openssl/asn1.h>*/
+
+DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
+ {
+ BIGNUM *kinv=NULL,*r=NULL,*s=NULL;
+ BIGNUM m;
+ BIGNUM xr;
+ BN_CTX *ctx=NULL;
+ int i,reason=ERR_R_BN_LIB;
+ DSA_SIG *ret=NULL;
+
+ BN_init(&m);
+ BN_init(&xr);
+ s=BN_new();
+ if (s == NULL) goto err;
+
+ i=BN_num_bytes(dsa->q); /* should be 20 */
+ if ((dlen > i) || (dlen > 50))
+ {
+ reason=DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE;
+ goto err;
+ }
+
+ ctx=BN_CTX_new();
+ if (ctx == NULL) goto err;
+
+ if ((dsa->kinv == NULL) || (dsa->r == NULL))
+ {
+ if (!DSA_sign_setup(dsa,ctx,&kinv,&r)) goto err;
+ }
+ else
+ {
+ kinv=dsa->kinv;
+ dsa->kinv=NULL;
+ r=dsa->r;
+ dsa->r=NULL;
+ }
+
+ if (BN_bin2bn(dgst,dlen,&m) == NULL) goto err;
+
+ /* Compute s = inv(k) (m + xr) mod q */
+ if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */
+ if (!BN_add(s, &xr, &m)) goto err; /* s = m + xr */
+ if (BN_cmp(s,dsa->q) > 0)
+ BN_sub(s,s,dsa->q);
+ if (!BN_mod_mul(s,s,kinv,dsa->q,ctx)) goto err;
+
+ ret=DSA_SIG_new();
+ if (ret == NULL) goto err;
+ ret->r = r;
+ ret->s = s;
+
+err:
+ if (!ret)
+ {
+ DSAerr(DSA_F_DSA_DO_SIGN,reason);
+ BN_free(r);
+ BN_free(s);
+ }
+ if (ctx != NULL) BN_CTX_free(ctx);
+ BN_clear_free(&m);
+ BN_clear_free(&xr);
+ if (kinv != NULL) /* dsa->kinv is NULL now if we used it */
+ BN_clear_free(kinv);
+ return(ret);
+ }
+
+/* data has already been hashed (probably with SHA or SHA-1). */
+
+/* BEW */
+#if 0
+/* unsigned char *sig: out */
+/* unsigned int *siglen: out */
+int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig,
+ unsigned int *siglen, DSA *dsa)
+ {
+ DSA_SIG *s;
+ s=DSA_do_sign(dgst,dlen,dsa);
+ if (s == NULL)
+ {
+ *siglen=0;
+ return(0);
+ }
+ *siglen=i2d_DSA_SIG(s,&sig);
+ DSA_SIG_free(s);
+ return(1);
+ }
+#endif
+
+int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
+ {
+ BN_CTX *ctx;
+ BIGNUM k,*kinv=NULL,*r=NULL;
+ int ret=0;
+
+ if (ctx_in == NULL)
+ {
+ if ((ctx=BN_CTX_new()) == NULL) goto err;
+ }
+ else
+ ctx=ctx_in;
+
+ BN_init(&k);
+ if ((r=BN_new()) == NULL) goto err;
+ kinv=NULL;
+
+ /* Get random k */
+ for (;;)
+ {
+ if (!BN_rand(&k, BN_num_bits(dsa->q), 1, 0)) goto err;
+ if (BN_cmp(&k,dsa->q) >= 0)
+ BN_sub(&k,&k,dsa->q);
+ if (!BN_is_zero(&k)) break;
+ }
+
+ if ((dsa->method_mont_p == NULL) && (dsa->flags & DSA_FLAG_CACHE_MONT_P))
+ {
+ if ((dsa->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
+ if (!BN_MONT_CTX_set((BN_MONT_CTX *)dsa->method_mont_p,
+ dsa->p,ctx)) goto err;
+ }
+
+ /* Compute r = (g^k mod p) mod q */
+ if (!BN_mod_exp_mont(r,dsa->g,&k,dsa->p,ctx,
+ (BN_MONT_CTX *)dsa->method_mont_p)) goto err;
+ if (!BN_mod(r,r,dsa->q,ctx)) goto err;
+
+ /* Compute part of 's = inv(k) (m + xr) mod q' */
+ if ((kinv=BN_mod_inverse(NULL,&k,dsa->q,ctx)) == NULL) goto err;
+
+ if (*kinvp != NULL) BN_clear_free(*kinvp);
+ *kinvp=kinv;
+ kinv=NULL;
+ if (*rp != NULL) BN_clear_free(*rp);
+ *rp=r;
+ ret=1;
+err:
+ if (!ret)
+ {
+ DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB);
+ if (kinv != NULL) BN_clear_free(kinv);
+ if (r != NULL) BN_clear_free(r);
+ }
+ if (ctx_in == NULL) BN_CTX_free(ctx);
+ if (kinv != NULL) BN_clear_free(kinv);
+ BN_clear_free(&k);
+ return(ret);
+ }
+
diff --git a/lib/dns/sec/openssl/dsa_vrf.c b/lib/dns/sec/openssl/dsa_vrf.c
new file mode 100644
index 00000000..9e0ab3f6
--- /dev/null
+++ b/lib/dns/sec/openssl/dsa_vrf.c
@@ -0,0 +1,163 @@
+/* crypto/dsa/dsa_vrf.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/rand.h>
+/*#include <openssl/asn1.h>*/
+/*#include <openssl/asn1_mac.h>*/
+
+int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
+ DSA *dsa)
+ {
+ BN_CTX *ctx;
+ BIGNUM u1,u2,t1;
+ BN_MONT_CTX *mont=NULL;
+ int ret = -1;
+
+ if ((ctx=BN_CTX_new()) == NULL) goto err;
+ BN_init(&u1);
+ BN_init(&u2);
+ BN_init(&t1);
+
+ /* Calculate W = inv(S) mod Q
+ * save W in u2 */
+ if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err;
+
+ /* save M in u1 */
+ if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err;
+
+ /* u1 = M * w mod q */
+ if (!BN_mod_mul(&u1,&u1,&u2,dsa->q,ctx)) goto err;
+
+ /* u2 = r * w mod q */
+ if (!BN_mod_mul(&u2,sig->r,&u2,dsa->q,ctx)) goto err;
+
+ if ((dsa->method_mont_p == NULL) && (dsa->flags & DSA_FLAG_CACHE_MONT_P))
+ {
+ if ((dsa->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
+ if (!BN_MONT_CTX_set((BN_MONT_CTX *)dsa->method_mont_p,
+ dsa->p,ctx)) goto err;
+ }
+ mont=(BN_MONT_CTX *)dsa->method_mont_p;
+
+#if 0
+ {
+ BIGNUM t2;
+
+ BN_init(&t2);
+ /* v = ( g^u1 * y^u2 mod p ) mod q */
+ /* let t1 = g ^ u1 mod p */
+ if (!BN_mod_exp_mont(&t1,dsa->g,&u1,dsa->p,ctx,mont)) goto err;
+ /* let t2 = y ^ u2 mod p */
+ if (!BN_mod_exp_mont(&t2,dsa->pub_key,&u2,dsa->p,ctx,mont)) goto err;
+ /* let u1 = t1 * t2 mod p */
+ if (!BN_mod_mul(&u1,&t1,&t2,dsa->p,ctx)) goto err_bn;
+ BN_free(&t2);
+ }
+ /* let u1 = u1 mod q */
+ if (!BN_mod(&u1,&u1,dsa->q,ctx)) goto err;
+#else
+ {
+ if (!BN_mod_exp2_mont(&t1,dsa->g,&u1,dsa->pub_key,&u2,dsa->p,ctx,mont))
+ goto err;
+ /* BN_copy(&u1,&t1); */
+ /* let u1 = u1 mod q */
+ if (!BN_mod(&u1,&t1,dsa->q,ctx)) goto err;
+ }
+#endif
+ /* V is now in u1. If the signature is correct, it will be
+ * equal to R. */
+ ret=(BN_ucmp(&u1, sig->r) == 0);
+
+ err:
+ if (ret != 1) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB);
+ if (ctx != NULL) BN_CTX_free(ctx);
+ BN_free(&u1);
+ BN_free(&u2);
+ BN_free(&t1);
+ return(ret);
+ }
+
+#if 0
+/* BEW */
+/* data has already been hashed (probably with SHA or SHA-1). */
+/* returns
+ * 1: correct signature
+ * 0: incorrect signature
+ * -1: error
+ */
+int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
+ unsigned char *sigbuf, int siglen, DSA *dsa)
+ {
+ DSA_SIG *s;
+ int ret=-1;
+
+ s = DSA_SIG_new();
+ if (s == NULL) return(ret);
+ if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err;
+ ret=DSA_do_verify(dgst,dgst_len,s,dsa);
+err:
+ DSA_SIG_free(s);
+ return(ret);
+ }
+#endif
diff --git a/lib/dns/sec/openssl/err.c b/lib/dns/sec/openssl/err.c
new file mode 100644
index 00000000..d62680da
--- /dev/null
+++ b/lib/dns/sec/openssl/err.c
@@ -0,0 +1,642 @@
+/* crypto/err/err.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <openssl/lhash.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+#include <openssl/crypto.h>
+
+
+static LHASH *error_hash=NULL;
+static LHASH *thread_hash=NULL;
+
+static unsigned long err_hash(ERR_STRING_DATA *a);
+static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b);
+static unsigned long pid_hash(ERR_STATE *pid);
+static int pid_cmp(ERR_STATE *a,ERR_STATE *pid);
+static unsigned long get_error_values(int inc,const char **file,int *line,
+ const char **data,int *flags);
+static void ERR_STATE_free(ERR_STATE *s);
+#ifndef NO_ERR
+static ERR_STRING_DATA ERR_str_libraries[]=
+ {
+{ERR_PACK(ERR_LIB_NONE,0,0) ,"unknown library"},
+{ERR_PACK(ERR_LIB_SYS,0,0) ,"system library"},
+{ERR_PACK(ERR_LIB_BN,0,0) ,"bignum routines"},
+{ERR_PACK(ERR_LIB_RSA,0,0) ,"rsa routines"},
+{ERR_PACK(ERR_LIB_DH,0,0) ,"Diffie-Hellman routines"},
+{ERR_PACK(ERR_LIB_EVP,0,0) ,"digital envelope routines"},
+{ERR_PACK(ERR_LIB_BUF,0,0) ,"memory buffer routines"},
+{ERR_PACK(ERR_LIB_BIO,0,0) ,"BIO routines"},
+{ERR_PACK(ERR_LIB_OBJ,0,0) ,"object identifier routines"},
+{ERR_PACK(ERR_LIB_PEM,0,0) ,"PEM routines"},
+{ERR_PACK(ERR_LIB_ASN1,0,0) ,"asn1 encoding routines"},
+{ERR_PACK(ERR_LIB_X509,0,0) ,"x509 certificate routines"},
+{ERR_PACK(ERR_LIB_CONF,0,0) ,"configuation file routines"},
+{ERR_PACK(ERR_LIB_METH,0,0) ,"X509 lookup 'method' routines"},
+{ERR_PACK(ERR_LIB_SSL,0,0) ,"SSL routines"},
+{ERR_PACK(ERR_LIB_RSAREF,0,0) ,"RSAref routines"},
+{ERR_PACK(ERR_LIB_PROXY,0,0) ,"Proxy routines"},
+{ERR_PACK(ERR_LIB_BIO,0,0) ,"BIO routines"},
+{ERR_PACK(ERR_LIB_PKCS7,0,0) ,"PKCS7 routines"},
+{ERR_PACK(ERR_LIB_X509V3,0,0) ,"X509 V3 routines"},
+{ERR_PACK(ERR_LIB_PKCS12,0,0) ,"PKCS12 routines"},
+{0,NULL},
+ };
+
+static ERR_STRING_DATA ERR_str_functs[]=
+ {
+ {ERR_PACK(0,SYS_F_FOPEN,0), "fopen"},
+ {ERR_PACK(0,SYS_F_CONNECT,0), "connect"},
+ {ERR_PACK(0,SYS_F_GETSERVBYNAME,0), "getservbyname"},
+ {ERR_PACK(0,SYS_F_SOCKET,0), "socket"},
+ {ERR_PACK(0,SYS_F_IOCTLSOCKET,0), "ioctlsocket"},
+ {ERR_PACK(0,SYS_F_BIND,0), "bind"},
+ {ERR_PACK(0,SYS_F_LISTEN,0), "listen"},
+ {ERR_PACK(0,SYS_F_ACCEPT,0), "accept"},
+#ifdef WINDOWS
+ {ERR_PACK(0,SYS_F_WSASTARTUP,0), "WSAstartup"},
+#endif
+ {0,NULL},
+ };
+
+static ERR_STRING_DATA ERR_str_reasons[]=
+ {
+{ERR_R_FATAL ,"fatal"},
+{ERR_R_SYS_LIB ,"system lib"},
+{ERR_R_BN_LIB ,"BN lib"},
+{ERR_R_RSA_LIB ,"RSA lib"},
+{ERR_R_DH_LIB ,"DH lib"},
+{ERR_R_EVP_LIB ,"EVP lib"},
+{ERR_R_BUF_LIB ,"BUF lib"},
+{ERR_R_BIO_LIB ,"BIO lib"},
+{ERR_R_OBJ_LIB ,"OBJ lib"},
+{ERR_R_PEM_LIB ,"PEM lib"},
+{ERR_R_X509_LIB ,"X509 lib"},
+{ERR_R_METH_LIB ,"METH lib"},
+{ERR_R_ASN1_LIB ,"ASN1 lib"},
+{ERR_R_CONF_LIB ,"CONF lib"},
+{ERR_R_SSL_LIB ,"SSL lib"},
+{ERR_R_PROXY_LIB ,"PROXY lib"},
+{ERR_R_BIO_LIB ,"BIO lib"},
+{ERR_R_PKCS7_LIB ,"PKCS7 lib"},
+{ERR_R_PKCS12_LIB ,"PKCS12 lib"},
+{ERR_R_MALLOC_FAILURE ,"Malloc failure"},
+{ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED ,"called a fuction you should not call"},
+{ERR_R_PASSED_NULL_PARAMETER ,"passed a null parameter"},
+{ERR_R_NESTED_ASN1_ERROR ,"nested asn1 error"},
+{ERR_R_BAD_ASN1_OBJECT_HEADER ,"bad asn1 object header"},
+{ERR_R_BAD_GET_ASN1_OBJECT_CALL ,"bad get asn1 object call"},
+{ERR_R_EXPECTING_AN_ASN1_SEQUENCE ,"expecting an asn1 sequence"},
+{ERR_R_ASN1_LENGTH_MISMATCH ,"asn1 length mismatch"},
+{ERR_R_MISSING_ASN1_EOS ,"missing asn1 eos"},
+
+{0,NULL},
+ };
+#endif
+
+#define err_clear_data(p,i) \
+ if (((p)->err_data[i] != NULL) && \
+ (p)->err_data_flags[i] & ERR_TXT_MALLOCED) \
+ { \
+ Free((p)->err_data[i]); \
+ (p)->err_data[i]=NULL; \
+ } \
+ (p)->err_data_flags[i]=0;
+
+static void ERR_STATE_free(ERR_STATE *s)
+ {
+ int i;
+
+ if(s == NULL)
+ return;
+
+ for (i=0; i<ERR_NUM_ERRORS; i++)
+ {
+ err_clear_data(s,i);
+ }
+ Free(s);
+ }
+
+void ERR_load_ERR_strings(void)
+ {
+ static int init=1;
+
+ if (init)
+ {
+ CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+ if (init == 0)
+ {
+ CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+ return;
+ }
+ init=0;
+ CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+
+#ifndef NO_ERR
+ ERR_load_strings(0,ERR_str_libraries);
+ ERR_load_strings(0,ERR_str_reasons);
+ ERR_load_strings(ERR_LIB_SYS,ERR_str_functs);
+#endif
+ }
+ }
+
+void ERR_load_strings(int lib, ERR_STRING_DATA *str)
+ {
+ if (error_hash == NULL)
+ {
+ CRYPTO_w_lock(CRYPTO_LOCK_ERR_HASH);
+ error_hash=lh_new(err_hash,err_cmp);
+ if (error_hash == NULL)
+ {
+ CRYPTO_w_unlock(CRYPTO_LOCK_ERR_HASH);
+ return;
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_ERR_HASH);
+
+ ERR_load_ERR_strings();
+ }
+
+ CRYPTO_w_lock(CRYPTO_LOCK_ERR_HASH);
+ while (str->error)
+ {
+ str->error|=ERR_PACK(lib,0,0);
+ lh_insert(error_hash,(char *)str);
+ str++;
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_ERR_HASH);
+ }
+
+void ERR_free_strings(void)
+ {
+ CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+
+ if (error_hash != NULL)
+ {
+ lh_free(error_hash);
+ error_hash=NULL;
+ }
+
+ CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+ }
+
+/********************************************************/
+
+void ERR_put_error(int lib, int func, int reason, const char *file,
+ int line)
+ {
+ ERR_STATE *es;
+
+#ifdef _OSD_POSIX
+ /* In the BS2000-OSD POSIX subsystem, the compiler generates
+ * path names in the form "*POSIX(/etc/passwd)".
+ * This dirty hack strips them to something sensible.
+ * @@@ We shouldn't modify a const string, though.
+ */
+ if (strncmp(file,"*POSIX(", sizeof("*POSIX(")-1) == 0) {
+ char *end;
+
+ /* Skip the "*POSIX(" prefix */
+ file += sizeof("*POSIX(")-1;
+ end = &file[strlen(file)-1];
+ if (*end == ')')
+ *end = '\0';
+ /* Optional: use the basename of the path only. */
+ if ((end = strrchr(file, '/')) != NULL)
+ file = &end[1];
+ }
+#endif
+ es=ERR_get_state();
+
+ es->top=(es->top+1)%ERR_NUM_ERRORS;
+ if (es->top == es->bottom)
+ es->bottom=(es->bottom+1)%ERR_NUM_ERRORS;
+ es->err_buffer[es->top]=ERR_PACK(lib,func,reason);
+ es->err_file[es->top]=file;
+ es->err_line[es->top]=line;
+ err_clear_data(es,es->top);
+ }
+
+void ERR_clear_error(void)
+ {
+ ERR_STATE *es;
+
+ es=ERR_get_state();
+
+#if 0
+ /* hmm... is this needed */
+ for (i=0; i<ERR_NUM_ERRORS; i++)
+ {
+ es->err_buffer[i]=0;
+ es->err_file[i]=NULL;
+ es->err_line[i]= -1;
+ err_clear_data(es,i);
+ }
+#endif
+ es->top=es->bottom=0;
+ }
+
+
+unsigned long ERR_get_error(void)
+ { return(get_error_values(1,NULL,NULL,NULL,NULL)); }
+
+unsigned long ERR_get_error_line(const char **file,
+ int *line)
+ { return(get_error_values(1,file,line,NULL,NULL)); }
+
+unsigned long ERR_get_error_line_data(const char **file, int *line,
+ const char **data, int *flags)
+ { return(get_error_values(1,file,line,
+ data,flags)); }
+
+unsigned long ERR_peek_error(void)
+ { return(get_error_values(0,NULL,NULL,NULL,NULL)); }
+
+unsigned long ERR_peek_error_line(const char **file,
+ int *line)
+ { return(get_error_values(0,file,line,NULL,NULL)); }
+
+unsigned long ERR_peek_error_line_data(const char **file, int *line,
+ const char **data, int *flags)
+ { return(get_error_values(0,file,line,
+ data,flags)); }
+
+static unsigned long get_error_values(int inc, const char **file, int *line,
+ const char **data, int *flags)
+ {
+ int i=0;
+ ERR_STATE *es;
+ unsigned long ret;
+
+ es=ERR_get_state();
+
+ if (es->bottom == es->top) return(0);
+ i=(es->bottom+1)%ERR_NUM_ERRORS;
+
+ ret=es->err_buffer[i];
+ if (inc)
+ {
+ es->bottom=i;
+ es->err_buffer[i]=0;
+ }
+
+ if ((file != NULL) && (line != NULL))
+ {
+ if (es->err_file[i] == NULL)
+ {
+ *file="NA";
+ if (line != NULL) *line=0;
+ }
+ else
+ {
+ *file=es->err_file[i];
+ if (line != NULL) *line=es->err_line[i];
+ }
+ }
+
+ if (data != NULL)
+ {
+ if (es->err_data[i] == NULL)
+ {
+ *data="";
+ if (flags != NULL) *flags=0;
+ }
+ else
+ {
+ *data=es->err_data[i];
+ if (flags != NULL) *flags=es->err_data_flags[i];
+ }
+ }
+ return(ret);
+ }
+
+/* BAD for multi-threaded, uses a local buffer if ret == NULL */
+char *ERR_error_string(unsigned long e, char *ret)
+ {
+ static char buf[256];
+ const char *ls,*fs,*rs;
+ unsigned long l,f,r;
+ int i;
+
+ l=ERR_GET_LIB(e);
+ f=ERR_GET_FUNC(e);
+ r=ERR_GET_REASON(e);
+
+ ls=ERR_lib_error_string(e);
+ fs=ERR_func_error_string(e);
+ rs=ERR_reason_error_string(e);
+
+ if (ret == NULL) ret=buf;
+
+ sprintf(&(ret[0]),"error:%08lX:",e);
+ i=strlen(ret);
+ if (ls == NULL)
+ sprintf(&(ret[i]),":lib(%lu) ",l);
+ else sprintf(&(ret[i]),"%s",ls);
+ i=strlen(ret);
+ if (fs == NULL)
+ sprintf(&(ret[i]),":func(%lu) ",f);
+ else sprintf(&(ret[i]),":%s",fs);
+ i=strlen(ret);
+ if (rs == NULL)
+ sprintf(&(ret[i]),":reason(%lu)",r);
+ else sprintf(&(ret[i]),":%s",rs);
+
+ return(ret);
+ }
+
+LHASH *ERR_get_string_table(void)
+ {
+ return(error_hash);
+ }
+
+LHASH *ERR_get_err_state_table(void)
+ {
+ return(thread_hash);
+ }
+
+const char *ERR_lib_error_string(unsigned long e)
+ {
+ ERR_STRING_DATA d,*p=NULL;
+ unsigned long l;
+
+ l=ERR_GET_LIB(e);
+
+ CRYPTO_r_lock(CRYPTO_LOCK_ERR_HASH);
+
+ if (error_hash != NULL)
+ {
+ d.error=ERR_PACK(l,0,0);
+ p=(ERR_STRING_DATA *)lh_retrieve(error_hash,(char *)&d);
+ }
+
+ CRYPTO_r_unlock(CRYPTO_LOCK_ERR_HASH);
+
+ return((p == NULL)?NULL:p->string);
+ }
+
+const char *ERR_func_error_string(unsigned long e)
+ {
+ ERR_STRING_DATA d,*p=NULL;
+ unsigned long l,f;
+
+ l=ERR_GET_LIB(e);
+ f=ERR_GET_FUNC(e);
+
+ CRYPTO_r_lock(CRYPTO_LOCK_ERR_HASH);
+
+ if (error_hash != NULL)
+ {
+ d.error=ERR_PACK(l,f,0);
+ p=(ERR_STRING_DATA *)lh_retrieve(error_hash,(char *)&d);
+ }
+
+ CRYPTO_r_unlock(CRYPTO_LOCK_ERR_HASH);
+
+ return((p == NULL)?NULL:p->string);
+ }
+
+const char *ERR_reason_error_string(unsigned long e)
+ {
+ ERR_STRING_DATA d,*p=NULL;
+ unsigned long l,r;
+
+ l=ERR_GET_LIB(e);
+ r=ERR_GET_REASON(e);
+
+ CRYPTO_r_lock(CRYPTO_LOCK_ERR_HASH);
+
+ if (error_hash != NULL)
+ {
+ d.error=ERR_PACK(l,0,r);
+ p=(ERR_STRING_DATA *)lh_retrieve(error_hash,(char *)&d);
+ if (p == NULL)
+ {
+ d.error=ERR_PACK(0,0,r);
+ p=(ERR_STRING_DATA *)lh_retrieve(error_hash,
+ (char *)&d);
+ }
+ }
+
+ CRYPTO_r_unlock(CRYPTO_LOCK_ERR_HASH);
+
+ return((p == NULL)?NULL:p->string);
+ }
+
+static unsigned long err_hash(ERR_STRING_DATA *a)
+ {
+ unsigned long ret,l;
+
+ l=a->error;
+ ret=l^ERR_GET_LIB(l)^ERR_GET_FUNC(l);
+ return(ret^ret%19*13);
+ }
+
+static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b)
+ {
+ return((int)(a->error-b->error));
+ }
+
+static unsigned long pid_hash(ERR_STATE *a)
+ {
+ return(a->pid*13);
+ }
+
+static int pid_cmp(ERR_STATE *a, ERR_STATE *b)
+ {
+ return((int)((long)a->pid - (long)b->pid));
+ }
+
+void ERR_remove_state(unsigned long pid)
+ {
+ ERR_STATE *p,tmp;
+
+ if (thread_hash == NULL)
+ return;
+ if (pid == 0)
+ pid=(unsigned long)CRYPTO_thread_id();
+ tmp.pid=pid;
+ CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+ p=(ERR_STATE *)lh_delete(thread_hash,(char *)&tmp);
+ CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+
+ if (p != NULL) ERR_STATE_free(p);
+ }
+
+ERR_STATE *ERR_get_state(void)
+ {
+ static ERR_STATE fallback;
+ ERR_STATE *ret=NULL,tmp,*tmpp;
+ int i;
+ unsigned long pid;
+
+ pid=(unsigned long)CRYPTO_thread_id();
+
+ CRYPTO_r_lock(CRYPTO_LOCK_ERR);
+ if (thread_hash == NULL)
+ {
+ CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
+ CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+ if (thread_hash == NULL)
+ {
+ MemCheck_off();
+ thread_hash=lh_new(pid_hash,pid_cmp);
+ MemCheck_on();
+ CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+ if (thread_hash == NULL) return(&fallback);
+ }
+ else
+ CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+ }
+ else
+ {
+ tmp.pid=pid;
+ ret=(ERR_STATE *)lh_retrieve(thread_hash,(char *)&tmp);
+ CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
+ }
+
+ /* ret == the error state, if NULL, make a new one */
+ if (ret == NULL)
+ {
+ ret=(ERR_STATE *)Malloc(sizeof(ERR_STATE));
+ if (ret == NULL) return(&fallback);
+ ret->pid=pid;
+ ret->top=0;
+ ret->bottom=0;
+ for (i=0; i<ERR_NUM_ERRORS; i++)
+ {
+ ret->err_data[i]=NULL;
+ ret->err_data_flags[i]=0;
+ }
+ CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+ tmpp=(ERR_STATE *)lh_insert(thread_hash,(char *)ret);
+ CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+ if (tmpp != NULL) /* old entry - should not happen */
+ {
+ ERR_STATE_free(tmpp);
+ }
+ }
+ return(ret);
+ }
+
+int ERR_get_next_error_library(void)
+ {
+ static int value=ERR_LIB_USER;
+
+ return(value++);
+ }
+
+void ERR_set_error_data(char *data, int flags)
+ {
+ ERR_STATE *es;
+ int i;
+
+ es=ERR_get_state();
+
+ i=es->top;
+ if (i == 0)
+ i=ERR_NUM_ERRORS-1;
+
+ es->err_data[i]=data;
+ es->err_data_flags[es->top]=flags;
+ }
+
+void ERR_add_error_data(int num, ...)
+ {
+ va_list args;
+ int i,n,s;
+ char *str,*p,*a;
+
+ s=64;
+ str=Malloc(s+1);
+ if (str == NULL) return;
+ str[0]='\0';
+
+ va_start(args, num);
+ n=0;
+ for (i=0; i<num; i++)
+ {
+ a=va_arg(args, char*);
+ /* ignore NULLs, thanks to Bob Beck <beck@obtuse.com> */
+ if (a != NULL)
+ {
+ n+=strlen(a);
+ if (n > s)
+ {
+ s=n+20;
+ p=Realloc(str,s+1);
+ if (p == NULL)
+ {
+ Free(str);
+ return;
+ }
+ else
+ str=p;
+ }
+ strcat(str,a);
+ }
+ }
+ ERR_set_error_data(str,ERR_TXT_MALLOCED|ERR_TXT_STRING);
+
+ va_end(args);
+ }
+
diff --git a/lib/dns/sec/openssl/include/.cvsignore b/lib/dns/sec/openssl/include/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/lib/dns/sec/openssl/include/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/lib/dns/sec/openssl/include/Makefile.in b/lib/dns/sec/openssl/include/Makefile.in
new file mode 100644
index 00000000..dec51fc7
--- /dev/null
+++ b/lib/dns/sec/openssl/include/Makefile.in
@@ -0,0 +1,23 @@
+# Copyright (C) 1998, 1999, 2000 Internet Software Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+# CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+# SOFTWARE.
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+SUBDIRS = openssl
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/dns/sec/openssl/include/openssl/.cvsignore b/lib/dns/sec/openssl/include/openssl/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/lib/dns/sec/openssl/include/openssl/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/lib/dns/sec/openssl/include/openssl/Makefile.in b/lib/dns/sec/openssl/include/openssl/Makefile.in
new file mode 100644
index 00000000..b40cd263
--- /dev/null
+++ b/lib/dns/sec/openssl/include/openssl/Makefile.in
@@ -0,0 +1,41 @@
+# Copyright (C) 1998, 1999, 2000 Internet Software Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+# CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+# SOFTWARE.
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+HEADERS = bio.h bn.h buffer.h crypto.h dh.h dsa.h e_os.h e_os2.h err.h \
+ lhash.h md5.h opensslconf.h opensslv.h rand.h sha.h stack.h
+
+SUBDIRS =
+TARGETS =
+
+@BIND9_MAKE_RULES@
+
+installdirs:
+ if [ ! -d ${includedir} ]; then \
+ mkdir ${includedir} ; \
+ fi
+ if [ ! -d ${includedir}/dst ]; then \
+ mkdir ${includedir}/dst ; \
+ fi
+
+install:: installdirs
+ for i in ${HEADERS}; do \
+ ${INSTALL_DATA} ${srcdir}/$$i ${includedir}/dst ; \
+ done
diff --git a/lib/dns/sec/openssl/include/openssl/bio.h b/lib/dns/sec/openssl/include/openssl/bio.h
new file mode 100644
index 00000000..c41db123
--- /dev/null
+++ b/lib/dns/sec/openssl/include/openssl/bio.h
@@ -0,0 +1,596 @@
+/* crypto/bio/bio.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BIO_H
+#define HEADER_BIO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <openssl/crypto.h>
+
+/* These are the 'types' of BIOs */
+#define BIO_TYPE_NONE 0
+#define BIO_TYPE_MEM (1|0x0400)
+#define BIO_TYPE_FILE (2|0x0400)
+
+#define BIO_TYPE_FD (4|0x0400|0x0100)
+#define BIO_TYPE_SOCKET (5|0x0400|0x0100)
+#define BIO_TYPE_NULL (6|0x0400)
+#define BIO_TYPE_SSL (7|0x0200)
+#define BIO_TYPE_MD (8|0x0200) /* pasive filter */
+#define BIO_TYPE_BUFFER (9|0x0200) /* filter */
+#define BIO_TYPE_CIPHER (10|0x0200) /* filter */
+#define BIO_TYPE_BASE64 (11|0x0200) /* filter */
+#define BIO_TYPE_CONNECT (12|0x0400|0x0100) /* socket - connect */
+#define BIO_TYPE_ACCEPT (13|0x0400|0x0100) /* socket for accept */
+#define BIO_TYPE_PROXY_CLIENT (14|0x0200) /* client proxy BIO */
+#define BIO_TYPE_PROXY_SERVER (15|0x0200) /* server proxy BIO */
+#define BIO_TYPE_NBIO_TEST (16|0x0200) /* server proxy BIO */
+#define BIO_TYPE_NULL_FILTER (17|0x0200)
+#define BIO_TYPE_BER (18|0x0200) /* BER -> bin filter */
+
+#define BIO_TYPE_DESCRIPTOR 0x0100 /* socket, fd, connect or accept */
+#define BIO_TYPE_FILTER 0x0200
+#define BIO_TYPE_SOURCE_SINK 0x0400
+
+/* BIO_FILENAME_READ|BIO_CLOSE to open or close on free.
+ * BIO_set_fp(in,stdin,BIO_NOCLOSE); */
+#define BIO_NOCLOSE 0x00
+#define BIO_CLOSE 0x01
+
+/* These are used in the following macros and are passed to
+ * BIO_ctrl() */
+#define BIO_CTRL_RESET 1 /* opt - rewind/zero etc */
+#define BIO_CTRL_EOF 2 /* opt - are we at the eof */
+#define BIO_CTRL_INFO 3 /* opt - extra tit-bits */
+#define BIO_CTRL_SET 4 /* man - set the 'IO' type */
+#define BIO_CTRL_GET 5 /* man - get the 'IO' type */
+#define BIO_CTRL_PUSH 6 /* opt - internal, used to signify change */
+#define BIO_CTRL_POP 7 /* opt - internal, used to signify change */
+#define BIO_CTRL_GET_CLOSE 8 /* man - set the 'close' on free */
+#define BIO_CTRL_SET_CLOSE 9 /* man - set the 'close' on free */
+#define BIO_CTRL_PENDING 10 /* opt - is their more data buffered */
+#define BIO_CTRL_FLUSH 11 /* opt - 'flush' buffered output */
+#define BIO_CTRL_DUP 12 /* man - extra stuff for 'duped' BIO */
+#define BIO_CTRL_WPENDING 13 /* opt - number of bytes still to write */
+/* callback is int cb(BIO *bio,state,ret); */
+#define BIO_CTRL_SET_CALLBACK 14 /* opt - set callback function */
+#define BIO_CTRL_GET_CALLBACK 15 /* opt - set callback function */
+
+#define BIO_CTRL_SET_FILENAME 30 /* BIO_s_file special */
+
+/* modifiers */
+#define BIO_FP_READ 0x02
+#define BIO_FP_WRITE 0x04
+#define BIO_FP_APPEND 0x08
+#define BIO_FP_TEXT 0x10
+
+#define BIO_FLAGS_READ 0x01
+#define BIO_FLAGS_WRITE 0x02
+#define BIO_FLAGS_IO_SPECIAL 0x04
+#define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL)
+#define BIO_FLAGS_SHOULD_RETRY 0x08
+
+/* Used in BIO_gethostbyname() */
+#define BIO_GHBN_CTRL_HITS 1
+#define BIO_GHBN_CTRL_MISSES 2
+#define BIO_GHBN_CTRL_CACHE_SIZE 3
+#define BIO_GHBN_CTRL_GET_ENTRY 4
+#define BIO_GHBN_CTRL_FLUSH 5
+
+/* Mostly used in the SSL BIO */
+/* Not used anymore
+ * #define BIO_FLAGS_PROTOCOL_DELAYED_READ 0x10
+ * #define BIO_FLAGS_PROTOCOL_DELAYED_WRITE 0x20
+ * #define BIO_FLAGS_PROTOCOL_STARTUP 0x40
+ */
+
+#define BIO_FLAGS_BASE64_NO_NL 0x100
+
+#define BIO_set_flags(b,f) ((b)->flags|=(f))
+#define BIO_get_flags(b) ((b)->flags)
+#define BIO_set_retry_special(b) \
+ ((b)->flags|=(BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY))
+#define BIO_set_retry_read(b) \
+ ((b)->flags|=(BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY))
+#define BIO_set_retry_write(b) \
+ ((b)->flags|=(BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY))
+
+/* These are normally used internally in BIOs */
+#define BIO_clear_flags(b,f) ((b)->flags&= ~(f))
+#define BIO_clear_retry_flags(b) \
+ ((b)->flags&= ~(BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
+#define BIO_get_retry_flags(b) \
+ ((b)->flags&(BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
+
+/* These shouldbe used by the application to tell why we should retry */
+#define BIO_should_read(a) ((a)->flags & BIO_FLAGS_READ)
+#define BIO_should_write(a) ((a)->flags & BIO_FLAGS_WRITE)
+#define BIO_should_io_special(a) ((a)->flags & BIO_FLAGS_IO_SPECIAL)
+#define BIO_retry_type(a) ((a)->flags & BIO_FLAGS_RWS)
+#define BIO_should_retry(a) ((a)->flags & BIO_FLAGS_SHOULD_RETRY)
+
+/* The next two are used in conjunction with the
+ * BIO_should_io_special() condition. After this returns true,
+ * BIO *BIO_get_retry_BIO(BIO *bio, int *reason); will walk the BIO
+ * stack and return the 'reason' for the special and the offending BIO.
+ * Given a BIO, BIO_get_retry_reason(bio) will return the code. */
+/* Returned from the SSL bio when the certificate retrieval code had an error */
+#define BIO_RR_SSL_X509_LOOKUP 0x01
+/* Returned from the connect BIO when a connect would have blocked */
+#define BIO_RR_CONNECT 0x02
+
+/* These are passed by the BIO callback */
+#define BIO_CB_FREE 0x01
+#define BIO_CB_READ 0x02
+#define BIO_CB_WRITE 0x03
+#define BIO_CB_PUTS 0x04
+#define BIO_CB_GETS 0x05
+#define BIO_CB_CTRL 0x06
+
+/* The callback is called before and after the underling operation,
+ * The BIO_CB_RETURN flag indicates if it is after the call */
+#define BIO_CB_RETURN 0x80
+#define BIO_CB_return(a) ((a)|BIO_CB_RETURN))
+#define BIO_cb_pre(a) (!((a)&BIO_CB_RETURN))
+#define BIO_cb_post(a) ((a)&BIO_CB_RETURN)
+
+#define BIO_set_callback(b,cb) ((b)->callback=(cb))
+#define BIO_set_callback_arg(b,arg) ((b)->cb_arg=(char *)(arg))
+#define BIO_get_callback_arg(b) ((b)->cb_arg)
+#define BIO_get_callback(b) ((b)->callback)
+#define BIO_method_name(b) ((b)->method->name)
+#define BIO_method_type(b) ((b)->method->type)
+
+#ifndef WIN16
+typedef struct bio_method_st
+ {
+ int type;
+ const char *name;
+ int (*bwrite)();
+ int (*bread)();
+ int (*bputs)();
+ int (*bgets)();
+ long (*ctrl)();
+ int (*create)();
+ int (*destroy)();
+ } BIO_METHOD;
+#else
+typedef struct bio_method_st
+ {
+ int type;
+ const char *name;
+ int (_far *bwrite)();
+ int (_far *bread)();
+ int (_far *bputs)();
+ int (_far *bgets)();
+ long (_far *ctrl)();
+ int (_far *create)();
+ int (_far *destroy)();
+ } BIO_METHOD;
+#endif
+
+typedef struct bio_st
+ {
+ BIO_METHOD *method;
+ /* bio, mode, argp, argi, argl, ret */
+ long (*callback)(struct bio_st *,int,const char *,int, long,long);
+ char *cb_arg; /* first argument for the callback */
+
+ int init;
+ int shutdown;
+ int flags; /* extra storage */
+ int retry_reason;
+ int num;
+ char *ptr;
+ struct bio_st *next_bio; /* used by filter BIOs */
+ struct bio_st *prev_bio; /* used by filter BIOs */
+ int references;
+ unsigned long num_read;
+ unsigned long num_write;
+
+ CRYPTO_EX_DATA ex_data;
+ } BIO;
+
+typedef struct bio_f_buffer_ctx_struct
+ {
+ /* BIO *bio; */ /* this is now in the BIO struct */
+ int ibuf_size; /* how big is the input buffer */
+ int obuf_size; /* how big is the output buffer */
+
+ char *ibuf; /* the char array */
+ int ibuf_len; /* how many bytes are in it */
+ int ibuf_off; /* write/read offset */
+
+ char *obuf; /* the char array */
+ int obuf_len; /* how many bytes are in it */
+ int obuf_off; /* write/read offset */
+ } BIO_F_BUFFER_CTX;
+
+/* connect BIO stuff */
+#define BIO_CONN_S_BEFORE 1
+#define BIO_CONN_S_GET_IP 2
+#define BIO_CONN_S_GET_PORT 3
+#define BIO_CONN_S_CREATE_SOCKET 4
+#define BIO_CONN_S_CONNECT 5
+#define BIO_CONN_S_OK 6
+#define BIO_CONN_S_BLOCKED_CONNECT 7
+#define BIO_CONN_S_NBIO 8
+/*#define BIO_CONN_get_param_hostname BIO_ctrl */
+
+#define BIO_number_read(b) ((b)->num_read)
+#define BIO_number_written(b) ((b)->num_write)
+
+#define BIO_C_SET_CONNECT 100
+#define BIO_C_DO_STATE_MACHINE 101
+#define BIO_C_SET_NBIO 102
+#define BIO_C_SET_PROXY_PARAM 103
+#define BIO_C_SET_FD 104
+#define BIO_C_GET_FD 105
+#define BIO_C_SET_FILE_PTR 106
+#define BIO_C_GET_FILE_PTR 107
+#define BIO_C_SET_FILENAME 108
+#define BIO_C_SET_SSL 109
+#define BIO_C_GET_SSL 110
+#define BIO_C_SET_MD 111
+#define BIO_C_GET_MD 112
+#define BIO_C_GET_CIPHER_STATUS 113
+#define BIO_C_SET_BUF_MEM 114
+#define BIO_C_GET_BUF_MEM_PTR 115
+#define BIO_C_GET_BUFF_NUM_LINES 116
+#define BIO_C_SET_BUFF_SIZE 117
+#define BIO_C_SET_ACCEPT 118
+#define BIO_C_SSL_MODE 119
+#define BIO_C_GET_MD_CTX 120
+#define BIO_C_GET_PROXY_PARAM 121
+#define BIO_C_SET_BUFF_READ_DATA 122 /* data to read first */
+#define BIO_C_GET_CONNECT 123
+#define BIO_C_GET_ACCEPT 124
+#define BIO_C_SET_SSL_RENEGOTIATE_BYTES 125
+#define BIO_C_GET_SSL_NUM_RENEGOTIATES 126
+#define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT 127
+#define BIO_C_FILE_SEEK 128
+#define BIO_C_GET_CIPHER_CTX 129
+#define BIO_C_SET_BUF_MEM_EOF_RETURN 130/*return end of input value*/
+#define BIO_C_SET_BIND_MODE 131
+#define BIO_C_GET_BIND_MODE 132
+#define BIO_C_FILE_TELL 133
+#define BIO_C_GET_SOCKS 134
+#define BIO_C_SET_SOCKS 135
+
+#define BIO_set_app_data(s,arg) BIO_set_ex_data(s,0,(char *)arg)
+#define BIO_get_app_data(s) BIO_get_ex_data(s,0)
+
+/* BIO_s_connect() and BIO_s_socks4a_connect() */
+#define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0,(char *)name)
+#define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1,(char *)port)
+#define BIO_set_conn_ip(b,ip) BIO_ctrl(b,BIO_C_SET_CONNECT,2,(char *)ip)
+#define BIO_set_conn_int_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,3,(char *)port)
+#define BIO_get_conn_hostname(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0)
+#define BIO_get_conn_port(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1)
+#define BIO_get_conn_ip(b,ip) BIO_ptr_ctrl(b,BIO_C_SET_CONNECT,2)
+#define BIO_get_conn_int_port(b,port) BIO_int_ctrl(b,BIO_C_SET_CONNECT,3,port)
+
+
+#define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL)
+
+/* BIO_s_accept_socket() */
+#define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name)
+#define BIO_get_accept_port(b) BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0)
+/* #define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */
+#define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?"a":NULL)
+#define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(char *)bio)
+
+#define BIO_BIND_NORMAL 0
+#define BIO_BIND_REUSEADDR_IF_UNUSED 1
+#define BIO_BIND_REUSEADDR 2
+#define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL)
+#define BIO_get_bind_mode(b,mode) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL)
+
+#define BIO_do_connect(b) BIO_do_handshake(b)
+#define BIO_do_accept(b) BIO_do_handshake(b)
+#define BIO_do_handshake(b) BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL)
+
+/* BIO_s_proxy_client() */
+#define BIO_set_url(b,url) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,0,(char *)(url))
+#define BIO_set_proxies(b,p) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,1,(char *)(p))
+/* BIO_set_nbio(b,n) */
+#define BIO_set_filter_bio(b,s) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,2,(char *)(s))
+/* BIO *BIO_get_filter_bio(BIO *bio); */
+#define BIO_set_proxy_cb(b,cb) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,3,(char *)(cb))
+#define BIO_set_proxy_header(b,sk) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,4,(char *)sk)
+#define BIO_set_no_connect_return(b,bool) BIO_int_ctrl(b,BIO_C_SET_PROXY_PARAM,5,bool)
+
+#define BIO_get_proxy_header(b,skp) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,0,(char *)skp)
+#define BIO_get_proxies(b,pxy_p) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,1,(char *)(pxy_p))
+#define BIO_get_url(b,url) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,2,(char *)(url))
+#define BIO_get_no_connect_return(b) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,5,NULL)
+
+#define BIO_set_fd(b,fd,c) BIO_int_ctrl(b,BIO_C_SET_FD,c,fd)
+#define BIO_get_fd(b,c) BIO_ctrl(b,BIO_C_GET_FD,0,(char *)c)
+
+#define BIO_set_fp(b,fp,c) BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)fp)
+#define BIO_get_fp(b,fpp) BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)fpp)
+
+#define BIO_seek(b,ofs) (int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL)
+#define BIO_tell(b) (int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL)
+
+/* name is cast to lose const, but might be better to route through a function
+ so we can do it safely */
+#ifdef CONST_STRICT
+/* If you are wondering why this isn't defined, its because CONST_STRICT is
+ * purely a compile-time kludge to allow const to be checked.
+ */
+int BIO_read_filename(BIO *b,const char *name);
+#else
+#define BIO_read_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+ BIO_CLOSE|BIO_FP_READ,(char *)name)
+#endif
+#define BIO_write_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+ BIO_CLOSE|BIO_FP_WRITE,name)
+#define BIO_append_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+ BIO_CLOSE|BIO_FP_APPEND,name)
+#define BIO_rw_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+ BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name)
+
+/* WARNING WARNING, this ups the reference count on the read bio of the
+ * SSL structure. This is because the ssl read BIO is now pointed to by
+ * the next_bio field in the bio. So when you free the BIO, make sure
+ * you are doing a BIO_free_all() to catch the underlying BIO. */
+#define BIO_set_ssl(b,ssl,c) BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)ssl)
+#define BIO_get_ssl(b,sslp) BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)sslp)
+#define BIO_set_ssl_mode(b,client) BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL)
+#define BIO_set_ssl_renegotiate_bytes(b,num) \
+ BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL);
+#define BIO_get_num_renegotiates(b) \
+ BIO_ctrl(b,BIO_C_SET_SSL_NUM_RENEGOTIATES,0,NULL);
+#define BIO_set_ssl_renegotiate_timeout(b,seconds) \
+ BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL);
+
+/* defined in evp.h */
+/* #define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,1,(char *)md) */
+
+#define BIO_get_mem_data(b,pp) BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp)
+#define BIO_set_mem_buf(b,bm,c) BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)bm)
+#define BIO_get_mem_ptr(b,pp) BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0,(char *)pp)
+#define BIO_set_mem_eof_return(b,v) \
+ BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL)
+
+/* For the BIO_f_buffer() type */
+#define BIO_get_buffer_num_lines(b) BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL)
+#define BIO_set_buffer_size(b,size) BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL)
+#define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0)
+#define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1)
+#define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf)
+
+/* Don't use the next one unless you know what you are doing :-) */
+#define BIO_dup_state(b,ret) BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret))
+
+#define BIO_reset(b) (int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL)
+#define BIO_eof(b) (int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL)
+#define BIO_set_close(b,c) (int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL)
+#define BIO_get_close(b) (int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL)
+#define BIO_pending(b) (int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL)
+#define BIO_wpending(b) (int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL)
+#define BIO_flush(b) (int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL)
+#define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0,(char *)cbp)
+#define BIO_set_info_callback(b,cb) (int)BIO_ctrl(b,BIO_CTRL_SET_CALLBACK,0,(char *)cb)
+
+/* For the BIO_f_buffer() type */
+#define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL)
+
+#ifdef NO_STDIO
+#define NO_FP_API
+#endif
+
+
+/* These two aren't currently implemented */
+/* int BIO_get_ex_num(BIO *bio); */
+/* void BIO_set_ex_free_func(BIO *bio,int idx,void (*cb)()); */
+int BIO_set_ex_data(BIO *bio,int idx,char *data);
+char *BIO_get_ex_data(BIO *bio,int idx);
+int BIO_get_ex_new_index(long argl, char *argp, int (*new_func)(),
+ int (*dup_func)(), void (*free_func)());
+
+# if defined(WIN16) && defined(_WINDLL)
+BIO_METHOD *BIO_s_file_internal(void);
+BIO *BIO_new_file_internal(char *filename, char *mode);
+BIO *BIO_new_fp_internal(FILE *stream, int close_flag);
+# define BIO_s_file BIO_s_file_internal
+# define BIO_new_file BIO_new_file_internal
+# define BIO_new_fp BIO_new_fp_internal
+# else /* FP_API */
+BIO_METHOD *BIO_s_file(void );
+BIO *BIO_new_file(char *filename, char *mode);
+BIO *BIO_new_fp(FILE *stream, int close_flag);
+# define BIO_s_file_internal BIO_s_file
+# define BIO_new_file_internal BIO_new_file
+# define BIO_new_fp_internal BIO_s_file
+# endif /* FP_API */
+BIO * BIO_new(BIO_METHOD *type);
+int BIO_set(BIO *a,BIO_METHOD *type);
+int BIO_free(BIO *a);
+int BIO_read(BIO *b, void *data, int len);
+int BIO_gets(BIO *bp,char *buf, int size);
+int BIO_write(BIO *b, const char *data, int len);
+int BIO_puts(BIO *bp,const char *buf);
+long BIO_ctrl(BIO *bp,int cmd,long larg,char *parg);
+char * BIO_ptr_ctrl(BIO *bp,int cmd,long larg);
+long BIO_int_ctrl(BIO *bp,int cmd,long larg,int iarg);
+BIO * BIO_push(BIO *b,BIO *append);
+BIO * BIO_pop(BIO *b);
+void BIO_free_all(BIO *a);
+BIO * BIO_find_type(BIO *b,int bio_type);
+BIO * BIO_get_retry_BIO(BIO *bio, int *reason);
+int BIO_get_retry_reason(BIO *bio);
+BIO * BIO_dup_chain(BIO *in);
+
+#ifndef WIN16
+long BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi,
+ long argl,long ret);
+#else
+long _far _loadds BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi,
+ long argl,long ret);
+#endif
+
+BIO_METHOD *BIO_s_mem(void);
+BIO_METHOD *BIO_s_socket(void);
+BIO_METHOD *BIO_s_connect(void);
+BIO_METHOD *BIO_s_accept(void);
+BIO_METHOD *BIO_s_fd(void);
+BIO_METHOD *BIO_s_log(void);
+BIO_METHOD *BIO_s_null(void);
+BIO_METHOD *BIO_f_null(void);
+BIO_METHOD *BIO_f_buffer(void);
+BIO_METHOD *BIO_f_nbio_test(void);
+/* BIO_METHOD *BIO_f_ber(void); */
+
+int BIO_sock_should_retry(int i);
+int BIO_sock_non_fatal_error(int error);
+int BIO_fd_should_retry(int i);
+int BIO_fd_non_fatal_error(int error);
+int BIO_dump(BIO *b,const char *bytes,int len);
+
+struct hostent *BIO_gethostbyname(const char *name);
+int BIO_sock_error(int sock);
+int BIO_socket_ioctl(int fd, long type, unsigned long *arg);
+int BIO_socket_nbio(int fd,int mode);
+int BIO_get_port(const char *str, unsigned short *port_ptr);
+int BIO_get_host_ip(const char *str, unsigned char *ip);
+int BIO_get_accept_socket(char *host_port,int mode);
+int BIO_accept(int sock,char **ip_port);
+int BIO_sock_init(void );
+void BIO_sock_cleanup(void);
+int BIO_set_tcp_ndelay(int sock,int turn_on);
+
+void ERR_load_BIO_strings(void );
+
+BIO *BIO_new_socket(int sock, int close_flag);
+BIO *BIO_new_fd(int fd, int close_flag);
+BIO *BIO_new_connect(char *host_port);
+BIO *BIO_new_accept(char *host_port);
+
+void BIO_copy_next_retry(BIO *b);
+
+long BIO_ghbn_ctrl(int cmd,int iarg,char *parg);
+
+int BIO_printf(BIO *bio, ...);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+/* Error codes for the BIO functions. */
+
+/* Function codes. */
+#define BIO_F_ACPT_STATE 100
+#define BIO_F_BIO_ACCEPT 101
+#define BIO_F_BIO_BER_GET_HEADER 102
+#define BIO_F_BIO_CTRL 103
+#define BIO_F_BIO_GETHOSTBYNAME 120
+#define BIO_F_BIO_GETS 104
+#define BIO_F_BIO_GET_ACCEPT_SOCKET 105
+#define BIO_F_BIO_GET_HOST_IP 106
+#define BIO_F_BIO_GET_PORT 107
+#define BIO_F_BIO_NEW 108
+#define BIO_F_BIO_NEW_FILE 109
+#define BIO_F_BIO_PUTS 110
+#define BIO_F_BIO_READ 111
+#define BIO_F_BIO_SOCK_INIT 112
+#define BIO_F_BIO_WRITE 113
+#define BIO_F_BUFFER_CTRL 114
+#define BIO_F_CONN_STATE 115
+#define BIO_F_FILE_CTRL 116
+#define BIO_F_MEM_WRITE 117
+#define BIO_F_SSL_NEW 118
+#define BIO_F_WSASTARTUP 119
+
+/* Reason codes. */
+#define BIO_R_ACCEPT_ERROR 100
+#define BIO_R_BAD_FOPEN_MODE 101
+#define BIO_R_BAD_HOSTNAME_LOOKUP 102
+#define BIO_R_CONNECT_ERROR 103
+#define BIO_R_ERROR_SETTING_NBIO 104
+#define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET 105
+#define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET 106
+#define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET 107
+#define BIO_R_INVALID_IP_ADDRESS 108
+#define BIO_R_KEEPALIVE 109
+#define BIO_R_NBIO_CONNECT_ERROR 110
+#define BIO_R_NO_ACCEPT_PORT_SPECIFIED 111
+#define BIO_R_NO_HOSTNAME_SPECIFIED 112
+#define BIO_R_NO_PORT_DEFINED 113
+#define BIO_R_NO_PORT_SPECIFIED 114
+#define BIO_R_NULL_PARAMETER 115
+#define BIO_R_TAG_MISMATCH 116
+#define BIO_R_UNABLE_TO_BIND_SOCKET 117
+#define BIO_R_UNABLE_TO_CREATE_SOCKET 118
+#define BIO_R_UNABLE_TO_LISTEN_SOCKET 119
+#define BIO_R_UNINITIALIZED 120
+#define BIO_R_UNSUPPORTED_METHOD 121
+#define BIO_R_WSASTARTUP 122
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/lib/dns/sec/openssl/include/openssl/bn.h b/lib/dns/sec/openssl/include/openssl/bn.h
new file mode 100644
index 00000000..68aad7b7
--- /dev/null
+++ b/lib/dns/sec/openssl/include/openssl/bn.h
@@ -0,0 +1,473 @@
+/* crypto/bn/bn.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BN_H
+#define HEADER_BN_H
+
+#ifndef WIN16
+#include <stdio.h> /* FILE */
+#endif
+#include <openssl/opensslconf.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef VMS
+#undef BN_LLONG /* experimental, so far... */
+#endif
+
+#define BN_MUL_COMBA
+#define BN_SQR_COMBA
+#define BN_RECURSION
+#define RECP_MUL_MOD
+#define MONT_MUL_MOD
+#ifndef WIN32
+#define SIXTY_FOUR_BIT /* BEW */
+#define NO_ASM /* BEW */
+#else
+#define THIRTY_TWO_BIT /* DCL */
+#endif
+
+/* This next option uses the C libraries (2 word)/(1 word) function.
+ * If it is not defined, I use my C version (which is slower).
+ * The reason for this flag is that when the particular C compiler
+ * library routine is used, and the library is linked with a different
+ * compiler, the library is missing. This mostly happens when the
+ * library is built with gcc and then linked using nornal cc. This would
+ * be a common occurance because gcc normally produces code that is
+ * 2 times faster than system compilers for the big number stuff.
+ * For machines with only one compiler (or shared libraries), this should
+ * be on. Again this in only really a problem on machines
+ * using "long long's", are 32bit, and are not using my assember code. */
+#if defined(MSDOS) || defined(WINDOWS) || defined(linux)
+#define BN_DIV2W
+#endif
+
+/* assuming long is 64bit - this is the DEC Alpha
+ * unsigned long long is only 64 bits :-(, don't define
+ * BN_LLONG for the DEC Alpha */
+#ifdef SIXTY_FOUR_BIT_LONG
+#define BN_ULLONG unsigned long long
+#define BN_ULONG unsigned long
+#define BN_LONG long
+#define BN_BITS 128
+#define BN_BYTES 8
+#define BN_BITS2 64
+#define BN_BITS4 32
+#define BN_MASK (0xffffffffffffffffffffffffffffffffLL)
+#define BN_MASK2 (0xffffffffffffffffL)
+#define BN_MASK2l (0xffffffffL)
+#define BN_MASK2h (0xffffffff00000000L)
+#define BN_MASK2h1 (0xffffffff80000000L)
+#define BN_TBIT (0x8000000000000000L)
+#define BN_DEC_CONV (10000000000000000000UL)
+#define BN_DEC_FMT1 "%lu"
+#define BN_DEC_FMT2 "%019lu"
+#define BN_DEC_NUM 19
+#endif
+
+/* This is where the long long data type is 64 bits, but long is 32.
+ * For machines where there are 64bit registers, this is the mode to use.
+ * IRIX, on R4000 and above should use this mode, along with the relevent
+ * assember code :-). Do NOT define BN_LLONG.
+ */
+#ifdef SIXTY_FOUR_BIT
+#undef BN_LLONG
+#undef BN_ULLONG
+#define BN_ULONG unsigned long long
+#define BN_LONG long long
+#define BN_BITS 128
+#define BN_BYTES 8
+#define BN_BITS2 64
+#define BN_BITS4 32
+#define BN_MASK2 (0xffffffffffffffffLL)
+#define BN_MASK2l (0xffffffffL)
+#define BN_MASK2h (0xffffffff00000000LL)
+#define BN_MASK2h1 (0xffffffff80000000LL)
+#define BN_TBIT (0x8000000000000000LL)
+#define BN_DEC_CONV (10000000000000000000LL)
+#define BN_DEC_FMT1 "%llu"
+#define BN_DEC_FMT2 "%019llu"
+#define BN_DEC_NUM 19
+#endif
+
+#ifdef THIRTY_TWO_BIT
+#if defined(WIN32) && !defined(__GNUC__)
+#define BN_ULLONG unsigned _int64
+#else
+#define BN_ULLONG unsigned long long
+#endif
+#define BN_ULONG unsigned long
+#define BN_LONG long
+#define BN_BITS 64
+#define BN_BYTES 4
+#define BN_BITS2 32
+#define BN_BITS4 16
+#ifdef WIN32
+/* VC++ doesn't like the LL suffix */
+#define BN_MASK (0xffffffffffffffffL)
+#else
+#define BN_MASK (0xffffffffffffffffLL)
+#endif
+#define BN_MASK2 (0xffffffffL)
+#define BN_MASK2l (0xffff)
+#define BN_MASK2h1 (0xffff8000L)
+#define BN_MASK2h (0xffff0000L)
+#define BN_TBIT (0x80000000L)
+#define BN_DEC_CONV (1000000000L)
+#define BN_DEC_FMT1 "%lu"
+#define BN_DEC_FMT2 "%09lu"
+#define BN_DEC_NUM 9
+#endif
+
+#ifdef SIXTEEN_BIT
+#ifndef BN_DIV2W
+#define BN_DIV2W
+#endif
+#define BN_ULLONG unsigned long
+#define BN_ULONG unsigned short
+#define BN_LONG short
+#define BN_BITS 32
+#define BN_BYTES 2
+#define BN_BITS2 16
+#define BN_BITS4 8
+#define BN_MASK (0xffffffff)
+#define BN_MASK2 (0xffff)
+#define BN_MASK2l (0xff)
+#define BN_MASK2h1 (0xff80)
+#define BN_MASK2h (0xff00)
+#define BN_TBIT (0x8000)
+#define BN_DEC_CONV (100000)
+#define BN_DEC_FMT1 "%u"
+#define BN_DEC_FMT2 "%05u"
+#define BN_DEC_NUM 5
+#endif
+
+#ifdef EIGHT_BIT
+#ifndef BN_DIV2W
+#define BN_DIV2W
+#endif
+#define BN_ULLONG unsigned short
+#define BN_ULONG unsigned char
+#define BN_LONG char
+#define BN_BITS 16
+#define BN_BYTES 1
+#define BN_BITS2 8
+#define BN_BITS4 4
+#define BN_MASK (0xffff)
+#define BN_MASK2 (0xff)
+#define BN_MASK2l (0xf)
+#define BN_MASK2h1 (0xf8)
+#define BN_MASK2h (0xf0)
+#define BN_TBIT (0x80)
+#define BN_DEC_CONV (100)
+#define BN_DEC_FMT1 "%u"
+#define BN_DEC_FMT2 "%02u"
+#define BN_DEC_NUM 2
+#endif
+
+#define BN_DEFAULT_BITS 1280
+
+#ifdef BIGNUM
+#undef BIGNUM
+#endif
+
+#define BN_FLG_MALLOCED 0x01
+#define BN_FLG_STATIC_DATA 0x02
+#define BN_FLG_FREE 0x8000 /* used for debuging */
+#define BN_set_flags(b,n) ((b)->flags|=(n))
+#define BN_get_flags(b,n) ((b)->flags&(n))
+
+typedef struct bignum_st
+ {
+ BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */
+ int top; /* Index of last used d +1. */
+ /* The next are internal book keeping for bn_expand. */
+ int max; /* Size of the d array. */
+ int neg; /* one if the number is negative */
+ int flags;
+ } BIGNUM;
+
+/* Used for temp variables */
+#define BN_CTX_NUM 12
+typedef struct bignum_ctx
+ {
+ int tos;
+ BIGNUM bn[BN_CTX_NUM+1];
+ int flags;
+ } BN_CTX;
+
+typedef struct bn_blinding_st
+ {
+ int init;
+ BIGNUM *A;
+ BIGNUM *Ai;
+ BIGNUM *mod; /* just a reference */
+ } BN_BLINDING;
+
+/* Used for montgomery multiplication */
+typedef struct bn_mont_ctx_st
+ {
+ int use_word; /* 0 for word form, 1 for long form */
+ int ri; /* number of bits in R */
+ BIGNUM RR; /* used to convert to montgomery form */
+ BIGNUM N; /* The modulus */
+ BIGNUM Ni; /* The inverse of N */
+ BN_ULONG n0; /* word form of inverse, normally only one of
+ * Ni or n0 is defined */
+ int flags;
+ } BN_MONT_CTX;
+
+/* Used for reciprocal division/mod functions
+ * It cannot be shared between threads
+ */
+typedef struct bn_recp_ctx_st
+ {
+ BIGNUM N; /* the divisor */
+ BIGNUM Nr; /* the reciprocal */
+ int num_bits;
+ int shift;
+ int flags;
+ } BN_RECP_CTX;
+
+#define BN_to_montgomery(r,a,mont,ctx) BN_mod_mul_montgomery(\
+ r,a,&((mont)->RR),(mont),ctx)
+
+#define BN_prime_checks (5)
+
+#define BN_num_bytes(a) ((BN_num_bits(a)+7)/8)
+#define BN_is_word(a,w) (((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w)))
+#define BN_is_zero(a) (((a)->top == 0) || BN_is_word(a,0))
+#define BN_is_one(a) (BN_is_word((a),1))
+#define BN_is_odd(a) (((a)->top > 0) && ((a)->d[0] & 1))
+#define BN_one(a) (BN_set_word((a),1))
+#define BN_zero(a) (BN_set_word((a),0))
+
+/*#define BN_ascii2bn(a) BN_hex2bn(a) */
+/*#define BN_bn2ascii(a) BN_bn2hex(a) */
+
+#define bn_expand(n,b) ((((((b+BN_BITS2-1))/BN_BITS2)) <= (n)->max)?\
+ (n):bn_expand2((n),(b)/BN_BITS2+1))
+#define bn_wexpand(n,b) (((b) <= (n)->max)?(n):bn_expand2((n),(b)))
+
+#define bn_fix_top(a) \
+ { \
+ BN_ULONG *ftl; \
+ if ((a)->top > 0) \
+ { \
+ for (ftl= &((a)->d[(a)->top-1]); (a)->top > 0; (a)->top--) \
+ if (*(ftl--)) break; \
+ } \
+ }
+
+BIGNUM *BN_value_one(void);
+char * BN_options(void);
+BN_CTX *BN_CTX_new(void);
+void BN_CTX_init(BN_CTX *c);
+void BN_CTX_free(BN_CTX *c);
+int BN_rand(BIGNUM *rnd, int bits, int top,int bottom);
+int BN_num_bits(const BIGNUM *a);
+int BN_num_bits_word(BN_ULONG);
+BIGNUM *BN_new(void);
+void BN_init(BIGNUM *);
+void BN_clear_free(BIGNUM *a);
+BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b);
+BIGNUM *BN_bin2bn(const unsigned char *s,int len,BIGNUM *ret);
+int BN_bn2bin(const BIGNUM *a, unsigned char *to);
+BIGNUM *BN_mpi2bn(unsigned char *s,int len,BIGNUM *ret);
+int BN_bn2mpi(const BIGNUM *a, unsigned char *to);
+int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b);
+int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
+int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
+ BN_CTX *ctx);
+int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b,BN_CTX *ctx);
+int BN_sqr(BIGNUM *r, BIGNUM *a,BN_CTX *ctx);
+BN_ULONG BN_mod_word(BIGNUM *a, BN_ULONG w);
+BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
+int BN_mul_word(BIGNUM *a, BN_ULONG w);
+int BN_add_word(BIGNUM *a, BN_ULONG w);
+int BN_sub_word(BIGNUM *a, BN_ULONG w);
+int BN_set_word(BIGNUM *a, BN_ULONG w);
+BN_ULONG BN_get_word(BIGNUM *a);
+int BN_cmp(const BIGNUM *a, const BIGNUM *b);
+void BN_free(BIGNUM *a);
+int BN_is_bit_set(const BIGNUM *a, int n);
+int BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
+int BN_lshift1(BIGNUM *r, BIGNUM *a);
+int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p,BN_CTX *ctx);
+int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m,BN_CTX *ctx);
+int BN_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int BN_mod_exp2_mont(BIGNUM *r, BIGNUM *a1, BIGNUM *p1,BIGNUM *a2,
+ BIGNUM *p2,BIGNUM *m,BN_CTX *ctx,BN_MONT_CTX *m_ctx);
+int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p,
+ BIGNUM *m,BN_CTX *ctx);
+int BN_mask_bits(BIGNUM *a,int n);
+int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
+#ifndef WIN16
+int BN_print_fp(FILE *fp, BIGNUM *a);
+#endif
+#ifdef HEADER_BIO_H
+int BN_print(BIO *fp, const BIGNUM *a);
+#else
+int BN_print(char *fp, const BIGNUM *a);
+#endif
+int BN_reciprocal(BIGNUM *r, BIGNUM *m, int len, BN_CTX *ctx);
+int BN_rshift(BIGNUM *r, BIGNUM *a, int n);
+int BN_rshift1(BIGNUM *r, BIGNUM *a);
+void BN_clear(BIGNUM *a);
+BIGNUM *bn_expand2(BIGNUM *b, int bits);
+BIGNUM *BN_dup(const BIGNUM *a);
+int BN_ucmp(const BIGNUM *a, const BIGNUM *b);
+int BN_set_bit(BIGNUM *a, int n);
+int BN_clear_bit(BIGNUM *a, int n);
+char * BN_bn2hex(const BIGNUM *a);
+char * BN_bn2dec(const BIGNUM *a);
+int BN_hex2bn(BIGNUM **a, const char *str);
+int BN_dec2bn(BIGNUM **a, const char *str);
+int BN_gcd(BIGNUM *r,BIGNUM *in_a,BIGNUM *in_b,BN_CTX *ctx);
+BIGNUM *BN_mod_inverse(BIGNUM *ret,BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
+BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int strong,BIGNUM *add,
+ BIGNUM *rem,void (*callback)(int,int,void *),void *cb_arg);
+int BN_is_prime(BIGNUM *p,int nchecks,void (*callback)(int,int,void *),
+ BN_CTX *ctx,void *cb_arg);
+void ERR_load_BN_strings(void );
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w);
+BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w);
+void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num);
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
+BN_ULONG bn_add_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num);
+BN_ULONG bn_sub_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num);
+
+BN_MONT_CTX *BN_MONT_CTX_new(void );
+void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
+int BN_mod_mul_montgomery(BIGNUM *r,BIGNUM *a,BIGNUM *b,BN_MONT_CTX *mont,
+ BN_CTX *ctx);
+int BN_from_montgomery(BIGNUM *r,BIGNUM *a,BN_MONT_CTX *mont,BN_CTX *ctx);
+void BN_MONT_CTX_free(BN_MONT_CTX *mont);
+int BN_MONT_CTX_set(BN_MONT_CTX *mont,const BIGNUM *modulus,BN_CTX *ctx);
+BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,BN_MONT_CTX *from);
+
+BN_BLINDING *BN_BLINDING_new(BIGNUM *A,BIGNUM *Ai,BIGNUM *mod);
+void BN_BLINDING_free(BN_BLINDING *b);
+int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx);
+int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *r, BN_CTX *ctx);
+int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
+
+void BN_set_params(int mul,int high,int low,int mont);
+int BN_get_params(int which); /* 0, mul, 1 high, 2 low, 3 mont */
+
+void BN_RECP_CTX_init(BN_RECP_CTX *recp);
+BN_RECP_CTX *BN_RECP_CTX_new(void);
+void BN_RECP_CTX_free(BN_RECP_CTX *recp);
+int BN_RECP_CTX_set(BN_RECP_CTX *recp,const BIGNUM *rdiv,BN_CTX *ctx);
+int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y,
+ BN_RECP_CTX *recp,BN_CTX *ctx);
+int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx);
+int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m,
+ BN_RECP_CTX *recp, BN_CTX *ctx);
+
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+/* Error codes for the BN functions. */
+
+/* Function codes. */
+#define BN_F_BN_BLINDING_CONVERT 100
+#define BN_F_BN_BLINDING_INVERT 101
+#define BN_F_BN_BLINDING_NEW 102
+#define BN_F_BN_BLINDING_UPDATE 103
+#define BN_F_BN_BN2DEC 104
+#define BN_F_BN_BN2HEX 105
+#define BN_F_BN_CTX_NEW 106
+#define BN_F_BN_DIV 107
+#define BN_F_BN_EXPAND2 108
+#define BN_F_BN_MOD_EXP_MONT 109
+#define BN_F_BN_MOD_INVERSE 110
+#define BN_F_BN_MOD_MUL_RECIPROCAL 111
+#define BN_F_BN_MPI2BN 112
+#define BN_F_BN_NEW 113
+#define BN_F_BN_RAND 114
+#define BN_F_BN_USUB 115
+
+/* Reason codes. */
+#define BN_R_ARG2_LT_ARG3 100
+#define BN_R_BAD_RECIPROCAL 101
+#define BN_R_CALLED_WITH_EVEN_MODULUS 102
+#define BN_R_DIV_BY_ZERO 103
+#define BN_R_ENCODING_ERROR 104
+#define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA 105
+#define BN_R_INVALID_LENGTH 106
+#define BN_R_NOT_INITIALIZED 107
+#define BN_R_NO_INVERSE 108
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/lib/dns/sec/openssl/include/openssl/buffer.h b/lib/dns/sec/openssl/include/openssl/buffer.h
new file mode 100644
index 00000000..bff26bf3
--- /dev/null
+++ b/lib/dns/sec/openssl/include/openssl/buffer.h
@@ -0,0 +1,98 @@
+/* crypto/buffer/buffer.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BUFFER_H
+#define HEADER_BUFFER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct buf_mem_st
+ {
+ int length; /* current number of bytes */
+ char *data;
+ int max; /* size of buffer */
+ } BUF_MEM;
+
+BUF_MEM *BUF_MEM_new(void);
+void BUF_MEM_free(BUF_MEM *a);
+int BUF_MEM_grow(BUF_MEM *str, int len);
+char * BUF_strdup(const char *str);
+
+void ERR_load_BUF_strings(void );
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+/* Error codes for the BUF functions. */
+
+/* Function codes. */
+#define BUF_F_BUF_MEM_GROW 100
+#define BUF_F_BUF_MEM_NEW 101
+#define BUF_F_BUF_STRDUP 102
+
+/* Reason codes. */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/lib/dns/sec/openssl/include/openssl/crypto.h b/lib/dns/sec/openssl/include/openssl/crypto.h
new file mode 100644
index 00000000..7418274b
--- /dev/null
+++ b/lib/dns/sec/openssl/include/openssl/crypto.h
@@ -0,0 +1,314 @@
+/* crypto/crypto.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_CRYPTO_H
+#define HEADER_CRYPTO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef NO_FP_API
+#include <stdio.h>
+#endif
+
+#include <openssl/stack.h>
+#include <openssl/opensslv.h>
+
+/* Backward compatibility to SSLeay */
+/* This is more to be used to check the correct DLL is being used
+ * in the MS world. */
+#define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER
+#define SSLEAY_VERSION 0
+/* #define SSLEAY_OPTIONS 1 no longer supported */
+#define SSLEAY_CFLAGS 2
+#define SSLEAY_BUILT_ON 3
+#define SSLEAY_PLATFORM 4
+
+/* When changing the CRYPTO_LOCK_* list, be sure to maintin the text lock
+ * names in cryptlib.c
+ */
+
+#define CRYPTO_LOCK_ERR 1
+#define CRYPTO_LOCK_ERR_HASH 2
+#define CRYPTO_LOCK_X509 3
+#define CRYPTO_LOCK_X509_INFO 4
+#define CRYPTO_LOCK_X509_PKEY 5
+#define CRYPTO_LOCK_X509_CRL 6
+#define CRYPTO_LOCK_X509_REQ 7
+#define CRYPTO_LOCK_DSA 8
+#define CRYPTO_LOCK_RSA 9
+#define CRYPTO_LOCK_EVP_PKEY 10
+#define CRYPTO_LOCK_X509_STORE 11
+#define CRYPTO_LOCK_SSL_CTX 12
+#define CRYPTO_LOCK_SSL_CERT 13
+#define CRYPTO_LOCK_SSL_SESSION 14
+#define CRYPTO_LOCK_SSL_SESS_CERT 15
+#define CRYPTO_LOCK_SSL 16
+#define CRYPTO_LOCK_RAND 17
+#define CRYPTO_LOCK_MALLOC 18
+#define CRYPTO_LOCK_BIO 19
+#define CRYPTO_LOCK_GETHOSTBYNAME 20
+#define CRYPTO_LOCK_GETSERVBYNAME 21
+#define CRYPTO_LOCK_READDIR 22
+#define CRYPTO_LOCK_RSA_BLINDING 23
+#define CRYPTO_NUM_LOCKS 24
+
+#define CRYPTO_LOCK 1
+#define CRYPTO_UNLOCK 2
+#define CRYPTO_READ 4
+#define CRYPTO_WRITE 8
+
+#ifndef NO_LOCKING
+#ifndef CRYPTO_w_lock
+#define CRYPTO_w_lock(type) \
+ CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
+#define CRYPTO_w_unlock(type) \
+ CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
+#define CRYPTO_r_lock(type) \
+ CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__)
+#define CRYPTO_r_unlock(type) \
+ CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__)
+#define CRYPTO_add(addr,amount,type) \
+ CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__)
+#endif
+#else
+#define CRYPTO_w_lock(a)
+#define CRYPTO_w_unlock(a)
+#define CRYPTO_r_lock(a)
+#define CRYPTO_r_unlock(a)
+#define CRYPTO_add(a,b,c) ((*(a))+=(b))
+#endif
+
+/* The following can be used to detect memory leaks in the SSLeay library.
+ * It used, it turns on malloc checking */
+
+#define CRYPTO_MEM_CHECK_OFF 0x0 /* an enume */
+#define CRYPTO_MEM_CHECK_ON 0x1 /* a bit */
+#define CRYPTO_MEM_CHECK_ENABLE 0x2 /* a bit */
+#define CRYPTO_MEM_CHECK_DISABLE 0x3 /* an enume */
+
+/*
+typedef struct crypto_mem_st
+ {
+ char *(*malloc_func)();
+ char *(*realloc_func)();
+ void (*free_func)();
+ } CRYPTO_MEM_FUNC;
+*/
+
+/* predec of the BIO type */
+typedef struct bio_st BIO_dummy;
+
+typedef struct crypto_ex_data_st
+ {
+ STACK *sk;
+ int dummy; /* gcc is screwing up this data structure :-( */
+ } CRYPTO_EX_DATA;
+
+/* This stuff is basically class callback functions
+ * The current classes are SSL_CTX, SSL, SSL_SESION, and a few more */
+typedef struct crypto_ex_data_func_st
+ {
+ long argl; /* Arbitary long */
+ char *argp; /* Arbitary char * */
+ /* Called when a new object is created */
+ int (*new_func)(/*char *obj,
+ char *item,int index,long argl,char *argp*/);
+ /* Called when this object is free()ed */
+ void (*free_func)(/*char *obj,
+ char *item,int index,long argl,char *argp*/);
+
+ /* Called when we need to dup this one */
+ int (*dup_func)(/*char *obj_to,char *obj_from,
+ char **new,int index,long argl,char *argp*/);
+ } CRYPTO_EX_DATA_FUNCS;
+
+/* Per class, we have a STACK of CRYPTO_EX_DATA_FUNCS for each CRYPTO_EX_DATA
+ * entry.
+ */
+
+#define CRYPTO_EX_INDEX_BIO 0
+#define CRYPTO_EX_INDEX_SSL 1
+#define CRYPTO_EX_INDEX_SSL_CTX 2
+#define CRYPTO_EX_INDEX_SSL_SESSION 3
+#define CRYPTO_EX_INDEX_X509_STORE 4
+#define CRYPTO_EX_INDEX_X509_STORE_CTX 5
+
+/* Use this for win32 DLL's */
+#define CRYPTO_malloc_init() CRYPTO_set_mem_functions(\
+ (char *(*)())malloc,\
+ (char *(*)())realloc,\
+ (void (*)())free)
+
+#ifdef CRYPTO_MDEBUG
+#define MemCheck_start() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON)
+#define MemCheck_stop() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF)
+#define MemCheck_on() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE)
+#define MemCheck_off() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE)
+#define Malloc(num) CRYPTO_dbg_malloc((int)num,__FILE__,__LINE__)
+#define Realloc(addr,num) \
+ CRYPTO_dbg_realloc((char *)addr,(int)num,__FILE__,__LINE__)
+#define Remalloc(addr,num) \
+ CRYPTO_dbg_remalloc((char **)addr,(int)num,__FILE__,__LINE__)
+#define FreeFunc CRYPTO_dbg_free
+#define Free(addr) CRYPTO_dbg_free(addr)
+#define Malloc_locked(num) CRYPTO_malloc_locked((int)num)
+#define Free_locked(addr) CRYPTO_free_locked(addr)
+#else
+#define MemCheck_start()
+#define MemCheck_stop()
+#define MemCheck_on()
+#define MemCheck_off()
+#define Remalloc CRYPTO_remalloc
+#if defined(WIN32) || defined(MFUNC)
+#define Malloc CRYPTO_malloc
+#define Realloc(a,n) CRYPTO_realloc(a,(n))
+#define FreeFunc CRYPTO_free
+#define Free(addr) CRYPTO_free(addr)
+#define Malloc_locked CRYPTO_malloc_locked
+#define Free_locked(addr) CRYPTO_free_locked(addr)
+#else
+#define Malloc malloc
+#define Realloc realloc
+#define FreeFunc free
+#define Free(addr) free(addr)
+#define Malloc_locked malloc
+#define Free_locked(addr) free(addr)
+#endif /* WIN32 || MFUNC */
+#endif /* MDEBUG */
+
+/* Case insensiteve linking causes problems.... */
+#if defined(WIN16) || defined(VMS)
+#define ERR_load_CRYPTO_strings ERR_load_CRYPTOlib_strings
+#endif
+
+
+const char *SSLeay_version(int type);
+unsigned long SSLeay(void);
+
+int CRYPTO_get_ex_new_index(int idx,STACK **sk,long argl,char *argp,
+ int (*new_func)(),int (*dup_func)(),void (*free_func)());
+int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad,int idx,char *val);
+char *CRYPTO_get_ex_data(CRYPTO_EX_DATA *ad,int idx);
+int CRYPTO_dup_ex_data(STACK *meth,CRYPTO_EX_DATA *from,CRYPTO_EX_DATA *to);
+void CRYPTO_free_ex_data(STACK *meth,char *obj,CRYPTO_EX_DATA *ad);
+void CRYPTO_new_ex_data(STACK *meth, char *obj, CRYPTO_EX_DATA *ad);
+
+int CRYPTO_mem_ctrl(int mode);
+int CRYPTO_get_new_lockid(char *name);
+void CRYPTO_lock(int mode, int type,const char *file,int line);
+void CRYPTO_set_locking_callback(void (*func)(int mode,int type,
+ const char *file,int line));
+void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file,
+ int line);
+void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type,
+ const char *file, int line));
+int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
+ const char *file,int line);
+void CRYPTO_set_id_callback(unsigned long (*func)(void));
+unsigned long (*CRYPTO_get_id_callback(void))(void);
+unsigned long CRYPTO_thread_id(void);
+const char *CRYPTO_get_lock_name(int type);
+int CRYPTO_add_lock(int *pointer,int amount,int type, const char *file,
+ int line);
+
+void CRYPTO_set_mem_functions(void *(*m)(),void *(*r)(), void (*free_func)());
+void CRYPTO_get_mem_functions(void *(**m)(),void *(**r)(), void (**f)());
+void CRYPTO_set_locked_mem_functions(void *(*m)(), void (*free_func)());
+void CRYPTO_get_locked_mem_functions(void *(**m)(), void (**f)());
+
+void *CRYPTO_malloc_locked(int num);
+void CRYPTO_free_locked(void *);
+void *CRYPTO_malloc(int num);
+void CRYPTO_free(void *);
+void *CRYPTO_realloc(void *addr,int num);
+void *CRYPTO_remalloc(void *addr,int num);
+
+void *CRYPTO_dbg_malloc(int num,const char *file,int line);
+void *CRYPTO_dbg_realloc(void *addr,int num,const char *file,int line);
+void CRYPTO_dbg_free(void *);
+void *CRYPTO_dbg_remalloc(void *addr,int num,const char *file,int line);
+#ifndef NO_FP_API
+void CRYPTO_mem_leaks_fp(FILE *);
+#endif
+void CRYPTO_mem_leaks(struct bio_st *bio);
+/* unsigned long order, char *file, int line, int num_bytes, char *addr */
+void CRYPTO_mem_leaks_cb(void (*cb)());
+
+void ERR_load_CRYPTO_strings(void );
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+/* Error codes for the CRYPTO functions. */
+
+/* Function codes. */
+#define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX 100
+#define CRYPTO_F_CRYPTO_GET_NEW_LOCKID 101
+#define CRYPTO_F_CRYPTO_SET_EX_DATA 102
+
+/* Reason codes. */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/lib/dns/sec/openssl/include/openssl/dh.h b/lib/dns/sec/openssl/include/openssl/dh.h
new file mode 100644
index 00000000..2cc3797a
--- /dev/null
+++ b/lib/dns/sec/openssl/include/openssl/dh.h
@@ -0,0 +1,158 @@
+/* crypto/dh/dh.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_DH_H
+#define HEADER_DH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef NO_DH
+#error DH is disabled.
+#endif
+
+#include <openssl/bn.h>
+
+#define DH_FLAG_CACHE_MONT_P 0x01
+
+typedef struct dh_st
+ {
+ /* This first argument is used to pick up errors when
+ * a DH is passed instead of a EVP_PKEY */
+ int pad;
+ int version;
+ BIGNUM *p;
+ BIGNUM *g;
+ int length; /* optional */
+ BIGNUM *pub_key; /* y */
+ BIGNUM *priv_key; /* x */
+
+ int flags;
+ char *method_mont_p;
+ } DH;
+
+#define DH_GENERATOR_2 2
+/* #define DH_GENERATOR_3 3 */
+#define DH_GENERATOR_5 5
+
+/* DH_check error codes */
+#define DH_CHECK_P_NOT_PRIME 0x01
+#define DH_CHECK_P_NOT_STRONG_PRIME 0x02
+#define DH_UNABLE_TO_CHECK_GENERATOR 0x04
+#define DH_NOT_SUITABLE_GENERATOR 0x08
+
+#define DHparams_dup(x) (DH *)ASN1_dup((int (*)())i2d_DHparams, \
+ (char *(*)())d2i_DHparams,(char *)(x))
+#define d2i_DHparams_fp(fp,x) (DH *)ASN1_d2i_fp((char *(*)())DH_new, \
+ (char *(*)())d2i_DHparams,(fp),(unsigned char **)(x))
+#define i2d_DHparams_fp(fp,x) ASN1_i2d_fp(i2d_DHparams,(fp), \
+ (unsigned char *)(x))
+#define d2i_DHparams_bio(bp,x) (DH *)ASN1_d2i_bio((char *(*)())DH_new, \
+ (char *(*)())d2i_DHparams,(bp),(unsigned char **)(x))
+#ifdef __cplusplus
+#define i2d_DHparams_bio(bp,x) ASN1_i2d_bio((int (*)())i2d_DHparams,(bp), \
+ (unsigned char *)(x))
+#else
+#define i2d_DHparams_bio(bp,x) ASN1_i2d_bio(i2d_DHparams,(bp), \
+ (unsigned char *)(x))
+#endif
+
+DH * DH_new(void);
+void DH_free(DH *dh);
+int DH_size(DH *dh);
+DH * DH_generate_parameters(int prime_len,int generator,
+ void (*callback)(int,int,void *),void *cb_arg);
+int DH_check(DH *dh,int *codes);
+int DH_generate_key(DH *dh);
+int DH_compute_key(unsigned char *key,BIGNUM *pub_key,DH *dh);
+DH * d2i_DHparams(DH **a,unsigned char **pp, long length);
+int i2d_DHparams(DH *a,unsigned char **pp);
+#ifndef NO_FP_API
+int DHparams_print_fp(FILE *fp, DH *x);
+#endif
+#ifdef HEADER_BIO_H
+int DHparams_print(BIO *bp, DH *x);
+#else
+int DHparams_print(char *bp, DH *x);
+#endif
+void ERR_load_DH_strings(void );
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+/* Error codes for the DH functions. */
+
+/* Function codes. */
+#define DH_F_DHPARAMS_PRINT 100
+#define DH_F_DHPARAMS_PRINT_FP 101
+#define DH_F_DH_COMPUTE_KEY 102
+#define DH_F_DH_GENERATE_KEY 103
+#define DH_F_DH_GENERATE_PARAMETERS 104
+#define DH_F_DH_NEW 105
+
+/* Reason codes. */
+#define DH_R_NO_PRIVATE_VALUE 100
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/lib/dns/sec/openssl/include/openssl/dsa.h b/lib/dns/sec/openssl/include/openssl/dsa.h
new file mode 100644
index 00000000..d9ff1933
--- /dev/null
+++ b/lib/dns/sec/openssl/include/openssl/dsa.h
@@ -0,0 +1,195 @@
+/* crypto/dsa/dsa.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/*
+ * The DSS routines are based on patches supplied by
+ * Steven Schoch <schoch@sheba.arc.nasa.gov>. He basically did the
+ * work and I have just tweaked them a little to fit into my
+ * stylistic vision for SSLeay :-) */
+
+#ifndef HEADER_DSA_H
+#define HEADER_DSA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef NO_DSA
+#error DSA is disabled.
+#endif
+
+#include <openssl/bn.h>
+
+#define DSA_FLAG_CACHE_MONT_P 0x01
+
+typedef struct dsa_st
+ {
+ /* This first variable is used to pick up errors where
+ * a DSA is passed instead of of a EVP_PKEY */
+ int pad;
+ int version;
+ int write_params;
+ BIGNUM *p;
+ BIGNUM *q; /* == 20 */
+ BIGNUM *g;
+
+ BIGNUM *pub_key; /* y public key */
+ BIGNUM *priv_key; /* x private key */
+
+ BIGNUM *kinv; /* Signing pre-calc */
+ BIGNUM *r; /* Signing pre-calc */
+
+ int flags;
+ /* Normally used to cache montgomery values */
+ char *method_mont_p;
+
+ int references;
+ } DSA;
+
+typedef struct DSA_SIG_st
+ {
+ BIGNUM *r;
+ BIGNUM *s;
+ } DSA_SIG;
+
+#define DSAparams_dup(x) (DSA *)ASN1_dup((int (*)())i2d_DSAparams, \
+ (char *(*)())d2i_DSAparams,(char *)(x))
+#define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \
+ (char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x))
+#define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \
+ (unsigned char *)(x))
+#define d2i_DSAparams_bio(bp,x) (DSA *)ASN1_d2i_bio((char *(*)())DSA_new, \
+ (char *(*)())d2i_DSAparams,(bp),(unsigned char **)(x))
+#define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio(i2d_DSAparams,(bp), \
+ (unsigned char *)(x))
+
+
+DSA_SIG * DSA_SIG_new(void);
+void DSA_SIG_free(DSA_SIG *a);
+int i2d_DSA_SIG(DSA_SIG *a, unsigned char **pp);
+DSA_SIG * d2i_DSA_SIG(DSA_SIG **v, unsigned char **pp, long length);
+
+DSA_SIG * DSA_do_sign(const unsigned char *dgst,int dlen,DSA *dsa);
+int DSA_do_verify(const unsigned char *dgst,int dgst_len,
+ DSA_SIG *sig,DSA *dsa);
+
+DSA * DSA_new(void);
+int DSA_size(DSA *);
+ /* next 4 return -1 on error */
+int DSA_sign_setup( DSA *dsa,BN_CTX *ctx_in,BIGNUM **kinvp,BIGNUM **rp);
+int DSA_sign(int type,const unsigned char *dgst,int dlen,
+ unsigned char *sig, unsigned int *siglen, DSA *dsa);
+int DSA_verify(int type,const unsigned char *dgst,int dgst_len,
+ unsigned char *sigbuf, int siglen, DSA *dsa);
+void DSA_free (DSA *r);
+
+void ERR_load_DSA_strings(void );
+
+DSA * d2i_DSAPublicKey(DSA **a, unsigned char **pp, long length);
+DSA * d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length);
+DSA * d2i_DSAparams(DSA **a, unsigned char **pp, long length);
+DSA * DSA_generate_parameters(int bits, unsigned char *seed,int seed_len,
+ int *counter_ret, unsigned long *h_ret,void
+ (*callback)(),char *cb_arg);
+int DSA_generate_key(DSA *a);
+int i2d_DSAPublicKey(DSA *a, unsigned char **pp);
+int i2d_DSAPrivateKey(DSA *a, unsigned char **pp);
+int i2d_DSAparams(DSA *a,unsigned char **pp);
+
+#ifdef HEADER_BIO_H
+int DSAparams_print(BIO *bp, DSA *x);
+int DSA_print(BIO *bp, DSA *x, int off);
+#endif
+#ifndef NO_FP_API
+int DSAparams_print_fp(FILE *fp, DSA *x);
+int DSA_print_fp(FILE *bp, DSA *x, int off);
+#endif
+
+int DSA_is_prime(BIGNUM *q,void (*callback)(),char *cb_arg);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+/* Error codes for the DSA functions. */
+
+/* Function codes. */
+#define DSA_F_D2I_DSA_SIG 110
+#define DSA_F_DSAPARAMS_PRINT 100
+#define DSA_F_DSAPARAMS_PRINT_FP 101
+#define DSA_F_DSA_DO_SIGN 112
+#define DSA_F_DSA_DO_VERIFY 113
+#define DSA_F_DSA_IS_PRIME 102
+#define DSA_F_DSA_NEW 103
+#define DSA_F_DSA_PRINT 104
+#define DSA_F_DSA_PRINT_FP 105
+#define DSA_F_DSA_SIGN 106
+#define DSA_F_DSA_SIGN_SETUP 107
+#define DSA_F_DSA_SIG_NEW 109
+#define DSA_F_DSA_VERIFY 108
+#define DSA_F_I2D_DSA_SIG 111
+
+/* Reason codes. */
+#define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 100
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/lib/dns/sec/openssl/include/openssl/e_os.h b/lib/dns/sec/openssl/include/openssl/e_os.h
new file mode 100644
index 00000000..b8d053bd
--- /dev/null
+++ b/lib/dns/sec/openssl/include/openssl/e_os.h
@@ -0,0 +1,373 @@
+/* e_os.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_E_OS_H
+#define HEADER_E_OS_H
+
+#include <openssl/e_os2.h>
+/* <openssl/e_os2.h> contains what we can justify to make visible
+ * to the outside; this file e_os.h is not part of the exported
+ * interface. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Used to checking reference counts, most while doing perl5 stuff :-) */
+#ifdef REF_PRINT
+#undef REF_PRINT
+#define REF_PRINT(a,b) fprintf(stderr,"%08X:%4d:%s\n",(int)b,b->references,a)
+#endif
+
+#ifndef DEVRANDOM
+/* set this to your 'random' device if you have one.
+ * My default, we will try to read this file */
+#define DEVRANDOM "/dev/urandom"
+#endif
+
+/********************************************************************
+ The Microsoft section
+ ********************************************************************/
+/* The following is used becaue of the small stack in some
+ * Microsoft operating systems */
+#if defined(WIN16) || defined(MSDOS)
+# define MS_STATIC static
+#else
+# define MS_STATIC
+#endif
+
+#if defined(WIN32) || defined(WIN16)
+# ifndef WINDOWS
+# define WINDOWS
+# endif
+# ifndef MSDOS
+# define MSDOS
+# endif
+#endif
+
+#ifdef WIN32
+#define get_last_sys_error() GetLastError()
+#define clear_sys_error() SetLastError(0)
+#if !defined(WINNT)
+#define WIN_CONSOLE_BUG
+#endif
+#else
+#define get_last_sys_error() errno
+#define clear_sys_error() errno=0
+#endif
+
+#ifdef WINDOWS
+#define get_last_socket_error() WSAGetLastError()
+#define clear_socket_error() WSASetLastError(0)
+#define readsocket(s,b,n) recv((s),(b),(n),0)
+#define writesocket(s,b,n) send((s),(b),(n),0)
+#define EADDRINUSE WSAEADDRINUSE
+#else
+#define get_last_socket_error() errno
+#define clear_socket_error() errno=0
+#define ioctlsocket(a,b,c) ioctl(a,b,c)
+#define closesocket(s) close(s)
+#define readsocket(s,b,n) read((s),(b),(n))
+#define writesocket(s,b,n) write((s),(b),(n))
+#endif
+
+#ifdef WIN16
+# define NO_FP_API
+# define MS_CALLBACK _far _loadds
+# define MS_FAR _far
+#else
+# define MS_CALLBACK
+# define MS_FAR
+#endif
+
+#ifdef NO_STDIO
+# define NO_FP_API
+#endif
+
+#if defined(WINDOWS) || defined(MSDOS)
+
+#ifndef S_IFDIR
+#define S_IFDIR _S_IFDIR
+#endif
+
+#ifndef S_IFMT
+#define S_IFMT _S_IFMT
+
+#if !defined(WINNT)
+#define NO_SYSLOG
+#endif
+#define NO_DIRENT
+
+#endif
+
+# ifdef WINDOWS
+# include <windows.h>
+# include <stddef.h>
+# include <errno.h>
+# include <string.h>
+# include <malloc.h>
+# endif
+# include <io.h>
+# include <fcntl.h>
+
+#if defined (__BORLANDC__)
+#define _setmode setmode
+#define _O_TEXT O_TEXT
+#define _O_BINARY O_BINARY
+#define _int64 __int64
+#endif
+
+#if defined(WIN16) && !defined(MONOLITH) && defined(SSLEAY) && defined(_WINEXITNOPERSIST)
+# define EXIT(n) { if (n == 0) _wsetexit(_WINEXITNOPERSIST); return(n); }
+#else
+# define EXIT(n) return(n);
+#endif
+# define LIST_SEPARATOR_CHAR ';'
+#ifndef X_OK
+# define X_OK 0
+#endif
+#ifndef W_OK
+# define W_OK 2
+#endif
+#ifndef R_OK
+# define R_OK 4
+#endif
+# define OPENSSL_CONF "openssl.cnf"
+# define SSLEAY_CONF OPENSSL_CONF
+# define NUL_DEV "nul"
+# define RFILE ".rnd"
+
+#else /* The non-microsoft world world */
+
+# if defined(__VMS) && !defined(VMS)
+# define VMS 1
+# endif
+
+# ifdef VMS
+ /* some programs don't include stdlib, so exit() and others give implicit
+ function warnings */
+# include <stdlib.h>
+# if defined(__DECC)
+# include <unistd.h>
+# else
+# include <unixlib.h>
+# endif
+# define OPENSSL_CONF "openssl.cnf"
+# define SSLEAY_CONF OPENSSL_CONF
+# define RFILE ".rnd"
+# define LIST_SEPARATOR_CHAR ','
+# define NUL_DEV "NLA0:"
+ /* We need to do this, because DEC C converts exit code 0 to 1, but not 1
+ to 0. We will convert 1 to 3! Also, add the inhibit message bit... */
+# ifndef MONOLITH
+# define EXIT(n) do { int __VMS_EXIT = n; \
+ if (__VMS_EXIT == 1) __VMS_EXIT = 3; \
+ __VMS_EXIT |= 0x10000000; \
+ exit(n); return(n); } while(0)
+# else
+# define EXIT(n) do { int __VMS_EXIT = n; \
+ if (__VMS_EXIT == 1) __VMS_EXIT = 3; \
+ __VMS_EXIT |= 0x10000000; \
+ return(n); } while(0)
+# endif
+# else
+# include <unistd.h>
+
+# define OPENSSL_CONF "openssl.cnf"
+# define SSLEAY_CONF OPENSSL_CONF
+# define RFILE ".rnd"
+# define LIST_SEPARATOR_CHAR ':'
+# define NUL_DEV "/dev/null"
+# ifndef MONOLITH
+# define EXIT(n) exit(n); return(n)
+# else
+# define EXIT(n) return(n)
+# endif
+# endif
+
+# define SSLeay_getpid() getpid()
+
+#endif
+
+
+/*************/
+
+#ifdef USE_SOCKETS
+# if defined(WINDOWS) || defined(MSDOS)
+ /* windows world */
+
+# ifdef NO_SOCK
+# define SSLeay_Write(a,b,c) (-1)
+# define SSLeay_Read(a,b,c) (-1)
+# define SHUTDOWN(fd) close(fd)
+# define SHUTDOWN2(fd) close(fd)
+# else
+# include <winsock.h>
+extern HINSTANCE _hInstance;
+# define SSLeay_Write(a,b,c) send((a),(b),(c),0)
+# define SSLeay_Read(a,b,c) recv((a),(b),(c),0)
+# define SHUTDOWN(fd) { shutdown((fd),0); closesocket(fd); }
+# define SHUTDOWN2(fd) { shutdown((fd),2); closesocket(fd); }
+# endif
+
+
+# else
+
+# include <sys/types.h>
+# ifndef VMS
+# include <sys/param.h>
+# endif
+# include <sys/time.h> /* Needed under linux for FD_XXX */
+
+# include <netdb.h>
+# if defined(VMS) && !defined(__DECC)
+# include <socket.h>
+# include <in.h>
+# else
+# include <sys/socket.h>
+# ifdef FILIO_H
+# include <sys/filio.h> /* Added for FIONBIO under unixware */
+# endif
+# include <netinet/in.h>
+# endif
+
+# if defined(NeXT) || defined(_NEXT_SOURCE)
+# include <sys/fcntl.h>
+# include <sys/types.h>
+# endif
+
+# ifdef AIX
+# include <sys/select.h>
+# endif
+
+# if defined(sun)
+# include <sys/filio.h>
+# else
+# ifndef VMS
+# include <sys/ioctl.h>
+# else
+ /* ioctl is only in VMS > 7.0 and when socketshr is not used */
+# if !defined(TCPIP_TYPE_SOCKETSHR) && defined(__VMS_VER) && (__VMS_VER > 70000000)
+# include <sys/ioctl.h>
+# endif
+# endif
+# endif
+
+# ifdef VMS
+# include <unixio.h>
+# if defined(TCPIP_TYPE_SOCKETSHR)
+# include <socketshr.h>
+# endif
+# endif
+
+# define SSLeay_Read(a,b,c) read((a),(b),(c))
+# define SSLeay_Write(a,b,c) write((a),(b),(c))
+# define SHUTDOWN(fd) { shutdown((fd),0); close((fd)); }
+# define SHUTDOWN2(fd) { shutdown((fd),2); close((fd)); }
+# define INVALID_SOCKET (-1)
+# endif
+#endif
+
+#if defined(THREADS) || defined(sun)
+#ifndef _REENTRANT
+#define _REENTRANT
+#endif
+#endif
+
+/***********************************************/
+
+/* do we need to do this for getenv.
+ * Just define getenv for use under windows */
+
+#ifdef WIN16
+/* How to do this needs to be thought out a bit more.... */
+/*char *GETENV(char *);
+#define Getenv GETENV*/
+#define Getenv getenv
+#else
+#define Getenv getenv
+#endif
+
+#define DG_GCC_BUG /* gcc < 2.6.3 on DGUX */
+
+#ifdef sgi
+#define IRIX_CC_BUG /* all version of IRIX I've tested (4.* 5.*) */
+#endif
+#ifdef SNI
+#define IRIX_CC_BUG /* CDS++ up to V2.0Bsomething suffered from the same bug.*/
+#endif
+
+#ifdef NO_MD2
+#define MD2_Init MD2Init
+#define MD2_Update MD2Update
+#define MD2_Final MD2Final
+#define MD2_DIGEST_LENGTH 16
+#endif
+#ifdef NO_MD5
+#define MD5_Init MD5Init
+#define MD5_Update MD5Update
+#define MD5_Final MD5Final
+#define MD5_DIGEST_LENGTH 16
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/lib/dns/sec/openssl/include/openssl/e_os2.h b/lib/dns/sec/openssl/include/openssl/e_os2.h
new file mode 100644
index 00000000..2bc0b487
--- /dev/null
+++ b/lib/dns/sec/openssl/include/openssl/e_os2.h
@@ -0,0 +1,28 @@
+/* e_os2.h */
+
+#ifndef HEADER_E_OS2_H
+#define HEADER_E_OS2_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Definitions of OPENSSL_GLOBAL and OPENSSL_EXTERN,
+ to define and declare certain global
+ symbols that, with some compilers under VMS, have to be defined and
+ declared explicitely with globaldef and globalref. On other OS:es,
+ these macros are defined with something sensible. */
+
+#if defined(VMS) && !defined(__DECC)
+# define OPENSSL_EXTERN globalref
+# define OPENSSL_GLOBAL globaldef
+#else
+# define OPENSSL_EXTERN extern
+# define OPENSSL_GLOBAL
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/lib/dns/sec/openssl/include/openssl/err.h b/lib/dns/sec/openssl/include/openssl/err.h
new file mode 100644
index 00000000..0ef83d5e
--- /dev/null
+++ b/lib/dns/sec/openssl/include/openssl/err.h
@@ -0,0 +1,262 @@
+/* crypto/err/err.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_ERR_H
+#define HEADER_ERR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef NO_FP_API
+#include <stdio.h>
+#endif
+
+/* The following is a bit of a trick to help the object files only contain
+ * the 'name of the file' string once. Since 'err.h' is protected by the
+ * HEADER_ERR_H stuff, this should be included only once per file. */
+
+#define ERR_file_name __FILE__
+
+#ifndef NO_ERR
+#define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,d,e)
+#else
+#define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,NULL,0)
+#endif
+
+#include <errno.h>
+
+#define ERR_TXT_MALLOCED 0x01
+#define ERR_TXT_STRING 0x02
+
+#define ERR_NUM_ERRORS 16
+typedef struct err_state_st
+ {
+ unsigned long pid;
+ unsigned long err_buffer[ERR_NUM_ERRORS];
+ char *err_data[ERR_NUM_ERRORS];
+ int err_data_flags[ERR_NUM_ERRORS];
+ const char *err_file[ERR_NUM_ERRORS];
+ int err_line[ERR_NUM_ERRORS];
+ int top,bottom;
+ } ERR_STATE;
+
+/* library */
+#define ERR_LIB_NONE 1
+#define ERR_LIB_SYS 2
+#define ERR_LIB_BN 3
+#define ERR_LIB_RSA 4
+#define ERR_LIB_DH 5
+#define ERR_LIB_EVP 6
+#define ERR_LIB_BUF 7
+#define ERR_LIB_OBJ 8
+#define ERR_LIB_PEM 9
+#define ERR_LIB_DSA 10
+#define ERR_LIB_X509 11
+#define ERR_LIB_METH 12
+#define ERR_LIB_ASN1 13
+#define ERR_LIB_CONF 14
+#define ERR_LIB_CRYPTO 15
+#define ERR_LIB_SSL 20
+#define ERR_LIB_SSL23 21
+#define ERR_LIB_SSL2 22
+#define ERR_LIB_SSL3 23
+#define ERR_LIB_RSAREF 30
+#define ERR_LIB_PROXY 31
+#define ERR_LIB_BIO 32
+#define ERR_LIB_PKCS7 33
+#define ERR_LIB_X509V3 34
+#define ERR_LIB_PKCS12 35
+
+#define ERR_LIB_USER 128
+
+#define SYSerr(f,r) ERR_PUT_error(ERR_LIB_SYS,(f),(r),ERR_file_name,__LINE__)
+#define BNerr(f,r) ERR_PUT_error(ERR_LIB_BN,(f),(r),ERR_file_name,__LINE__)
+#define RSAerr(f,r) ERR_PUT_error(ERR_LIB_RSA,(f),(r),ERR_file_name,__LINE__)
+#define DHerr(f,r) ERR_PUT_error(ERR_LIB_DH,(f),(r),ERR_file_name,__LINE__)
+#define EVPerr(f,r) ERR_PUT_error(ERR_LIB_EVP,(f),(r),ERR_file_name,__LINE__)
+#define BUFerr(f,r) ERR_PUT_error(ERR_LIB_BUF,(f),(r),ERR_file_name,__LINE__)
+#define BIOerr(f,r) ERR_PUT_error(ERR_LIB_BIO,(f),(r),ERR_file_name,__LINE__)
+#define OBJerr(f,r) ERR_PUT_error(ERR_LIB_OBJ,(f),(r),ERR_file_name,__LINE__)
+#define PEMerr(f,r) ERR_PUT_error(ERR_LIB_PEM,(f),(r),ERR_file_name,__LINE__)
+#define DSAerr(f,r) ERR_PUT_error(ERR_LIB_DSA,(f),(r),ERR_file_name,__LINE__)
+#define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,(f),(r),ERR_file_name,__LINE__)
+#define METHerr(f,r) ERR_PUT_error(ERR_LIB_METH,(f),(r),ERR_file_name,__LINE__)
+#define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),ERR_file_name,__LINE__)
+#define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,(f),(r),ERR_file_name,__LINE__)
+#define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,(f),(r),ERR_file_name,__LINE__)
+#define SSLerr(f,r) ERR_PUT_error(ERR_LIB_SSL,(f),(r),ERR_file_name,__LINE__)
+#define SSL23err(f,r) ERR_PUT_error(ERR_LIB_SSL23,(f),(r),ERR_file_name,__LINE__)
+#define SSL2err(f,r) ERR_PUT_error(ERR_LIB_SSL2,(f),(r),ERR_file_name,__LINE__)
+#define SSL3err(f,r) ERR_PUT_error(ERR_LIB_SSL3,(f),(r),ERR_file_name,__LINE__)
+#define RSAREFerr(f,r) ERR_PUT_error(ERR_LIB_RSAREF,(f),(r),ERR_file_name,__LINE__)
+#define PROXYerr(f,r) ERR_PUT_error(ERR_LIB_PROXY,(f),(r),ERR_file_name,__LINE__)
+#define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),ERR_file_name,__LINE__)
+#define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),ERR_file_name,__LINE__)
+#define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),ERR_file_name,__LINE__)
+
+/* Borland C seems too stupid to be able to shift and do longs in
+ * the pre-processor :-( */
+#define ERR_PACK(l,f,r) (((((unsigned long)l)&0xffL)*0x1000000)| \
+ ((((unsigned long)f)&0xfffL)*0x1000)| \
+ ((((unsigned long)r)&0xfffL)))
+#define ERR_GET_LIB(l) (int)((((unsigned long)l)>>24L)&0xffL)
+#define ERR_GET_FUNC(l) (int)((((unsigned long)l)>>12L)&0xfffL)
+#define ERR_GET_REASON(l) (int)((l)&0xfffL)
+#define ERR_FATAL_ERROR(l) (int)((l)&ERR_R_FATAL)
+
+/* OS fuctions */
+#define SYS_F_FOPEN 1
+#define SYS_F_CONNECT 2
+#define SYS_F_GETSERVBYNAME 3
+#define SYS_F_SOCKET 4
+#define SYS_F_IOCTLSOCKET 5
+#define SYS_F_BIND 6
+#define SYS_F_LISTEN 7
+#define SYS_F_ACCEPT 8
+#define SYS_F_WSASTARTUP 9 /* Winsock stuff */
+
+#define ERR_R_FATAL 32
+/* reasons */
+#define ERR_R_SYS_LIB ERR_LIB_SYS
+#define ERR_R_BN_LIB ERR_LIB_BN
+#define ERR_R_RSA_LIB ERR_LIB_RSA
+#define ERR_R_DSA_LIB ERR_LIB_DSA
+#define ERR_R_DH_LIB ERR_LIB_DH
+#define ERR_R_EVP_LIB ERR_LIB_EVP
+#define ERR_R_BUF_LIB ERR_LIB_BUF
+#define ERR_R_BIO_LIB ERR_LIB_BIO
+#define ERR_R_OBJ_LIB ERR_LIB_OBJ
+#define ERR_R_PEM_LIB ERR_LIB_PEM
+#define ERR_R_X509_LIB ERR_LIB_X509
+#define ERR_R_METH_LIB ERR_LIB_METH
+#define ERR_R_ASN1_LIB ERR_LIB_ASN1
+#define ERR_R_CONF_LIB ERR_LIB_CONF
+#define ERR_R_CRYPTO_LIB ERR_LIB_CRYPTO
+#define ERR_R_SSL_LIB ERR_LIB_SSL
+#define ERR_R_SSL23_LIB ERR_LIB_SSL23
+#define ERR_R_SSL2_LIB ERR_LIB_SSL2
+#define ERR_R_SSL3_LIB ERR_LIB_SSL3
+#define ERR_R_PROXY_LIB ERR_LIB_PROXY
+#define ERR_R_BIO_LIB ERR_LIB_BIO
+#define ERR_R_PKCS7_LIB ERR_LIB_PKCS7
+#define ERR_R_PKCS12_LIB ERR_LIB_PKCS12
+
+/* fatal error */
+#define ERR_R_MALLOC_FAILURE (1|ERR_R_FATAL)
+#define ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED (2|ERR_R_FATAL)
+#define ERR_R_PASSED_NULL_PARAMETER (3|ERR_R_FATAL)
+#define ERR_R_NESTED_ASN1_ERROR (4)
+#define ERR_R_BAD_ASN1_OBJECT_HEADER (5)
+#define ERR_R_BAD_GET_ASN1_OBJECT_CALL (6)
+#define ERR_R_EXPECTING_AN_ASN1_SEQUENCE (7)
+#define ERR_R_ASN1_LENGTH_MISMATCH (8)
+#define ERR_R_MISSING_ASN1_EOS (9)
+
+typedef struct ERR_string_data_st
+ {
+ unsigned long error;
+ const char *string;
+ } ERR_STRING_DATA;
+
+void ERR_put_error(int lib, int func,int reason,const char *file,int line);
+void ERR_set_error_data(char *data,int flags);
+
+unsigned long ERR_get_error(void );
+unsigned long ERR_get_error_line(const char **file,int *line);
+unsigned long ERR_get_error_line_data(const char **file,int *line,
+ const char **data, int *flags);
+unsigned long ERR_peek_error(void );
+unsigned long ERR_peek_error_line(const char **file,int *line);
+unsigned long ERR_peek_error_line_data(const char **file,int *line,
+ const char **data,int *flags);
+void ERR_clear_error(void );
+char *ERR_error_string(unsigned long e,char *buf);
+const char *ERR_lib_error_string(unsigned long e);
+const char *ERR_func_error_string(unsigned long e);
+const char *ERR_reason_error_string(unsigned long e);
+#ifndef NO_FP_API
+void ERR_print_errors_fp(FILE *fp);
+#endif
+#ifdef HEADER_BIO_H
+void ERR_print_errors(BIO *bp);
+void ERR_add_error_data(int num, ...);
+#endif
+void ERR_load_strings(int lib,ERR_STRING_DATA str[]);
+void ERR_load_ERR_strings(void );
+void ERR_load_crypto_strings(void );
+void ERR_free_strings(void );
+
+void ERR_remove_state(unsigned long pid); /* if zero we look it up */
+ERR_STATE *ERR_get_state(void);
+
+#ifdef HEADER_LHASH_H
+LHASH *ERR_get_string_table(void );
+LHASH *ERR_get_err_state_table(void );
+#else
+char *ERR_get_string_table(void );
+char *ERR_get_err_state_table(void );
+#endif
+
+int ERR_get_next_error_library(void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/dns/sec/openssl/include/openssl/lhash.h b/lib/dns/sec/openssl/include/openssl/lhash.h
new file mode 100644
index 00000000..6e5a1fe7
--- /dev/null
+++ b/lib/dns/sec/openssl/include/openssl/lhash.h
@@ -0,0 +1,144 @@
+/* crypto/lhash/lhash.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Header for dynamic hash table routines
+ * Author - Eric Young
+ */
+
+#ifndef HEADER_LHASH_H
+#define HEADER_LHASH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef NO_FP_API
+#include <stdio.h>
+#endif
+
+typedef struct lhash_node_st
+ {
+ char *data;
+ struct lhash_node_st *next;
+#ifndef NO_HASH_COMP
+ unsigned long hash;
+#endif
+ } LHASH_NODE;
+
+typedef struct lhash_st
+ {
+ LHASH_NODE **b;
+ int (*comp)();
+ unsigned long (*hash)();
+ unsigned int num_nodes;
+ unsigned int num_alloc_nodes;
+ unsigned int p;
+ unsigned int pmax;
+ unsigned long up_load; /* load times 256 */
+ unsigned long down_load; /* load times 256 */
+ unsigned long num_items;
+
+ unsigned long num_expands;
+ unsigned long num_expand_reallocs;
+ unsigned long num_contracts;
+ unsigned long num_contract_reallocs;
+ unsigned long num_hash_calls;
+ unsigned long num_comp_calls;
+ unsigned long num_insert;
+ unsigned long num_replace;
+ unsigned long num_delete;
+ unsigned long num_no_delete;
+ unsigned long num_retrieve;
+ unsigned long num_retrieve_miss;
+ unsigned long num_hash_comps;
+
+ int error;
+ } LHASH;
+
+#define LH_LOAD_MULT 256
+
+/* Indicates a malloc() error in the last call, this is only bad
+ * in lh_insert(). */
+#define lh_error(lh) ((lh)->error)
+
+LHASH *lh_new(unsigned long (*h)(), int (*c)());
+void lh_free(LHASH *lh);
+char *lh_insert(LHASH *lh, char *data);
+char *lh_delete(LHASH *lh, char *data);
+char *lh_retrieve(LHASH *lh, char *data);
+void lh_doall(LHASH *lh, void (*func)(/* char *b */));
+void lh_doall_arg(LHASH *lh, void (*func)(/*char *a,char *b*/),char *arg);
+unsigned long lh_strhash(const char *c);
+
+#ifndef NO_FP_API
+void lh_stats(LHASH *lh, FILE *out);
+void lh_node_stats(LHASH *lh, FILE *out);
+void lh_node_usage_stats(LHASH *lh, FILE *out);
+#endif
+
+#ifdef HEADER_BIO_H
+void lh_stats_bio(LHASH *lh, BIO *out);
+void lh_node_stats_bio(LHASH *lh, BIO *out);
+void lh_node_usage_stats_bio(LHASH *lh, BIO *out);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/lib/dns/sec/openssl/include/openssl/md5.h b/lib/dns/sec/openssl/include/openssl/md5.h
new file mode 100644
index 00000000..bdab6d45
--- /dev/null
+++ b/lib/dns/sec/openssl/include/openssl/md5.h
@@ -0,0 +1,114 @@
+/* crypto/md5/md5.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_MD5_H
+#define HEADER_MD5_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef NO_MD5
+#error MD5 is disabled.
+#endif
+
+/*
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! MD5_LONG has to be at least 32 bits wide. If it's wider, then !
+ * ! MD5_LONG_LOG2 has to be defined along. !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+#if defined(WIN16) || defined(__LP32__)
+#define MD5_LONG unsigned long
+#elif defined(_CRAY) || defined(__ILP64__)
+#define MD5_LONG unsigned long
+#define MD5_LONG_LOG2 3
+/*
+ * _CRAY note. I could declare short, but I have no idea what impact
+ * does it have on performance on none-T3E machines. I could declare
+ * int, but at least on C90 sizeof(int) can be chosen at compile time.
+ * So I've chosen long...
+ * <appro@fy.chalmers.se>
+ */
+#else
+#define MD5_LONG unsigned int
+#endif
+
+#define MD5_CBLOCK 64
+#define MD5_LBLOCK (MD5_CBLOCK/4)
+#define MD5_DIGEST_LENGTH 16
+
+typedef struct MD5state_st
+ {
+ MD5_LONG A,B,C,D;
+ MD5_LONG Nl,Nh;
+ MD5_LONG data[MD5_LBLOCK];
+ int num;
+ } MD5_CTX;
+
+void MD5_Init(MD5_CTX *c);
+void MD5_Update(MD5_CTX *c, const unsigned char *data, unsigned long len);
+void MD5_Final(unsigned char *md, MD5_CTX *c);
+unsigned char *MD5(unsigned char *d, unsigned long n, unsigned char *md);
+void MD5_Transform(MD5_CTX *c, const unsigned char *b);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/dns/sec/openssl/include/openssl/opensslconf.h b/lib/dns/sec/openssl/include/openssl/opensslconf.h
new file mode 100644
index 00000000..1ff8fea1
--- /dev/null
+++ b/lib/dns/sec/openssl/include/openssl/opensslconf.h
@@ -0,0 +1,7 @@
+#ifndef HEADER_OPENSSLCONF_H
+#define HEADER_OPENSSLCONF_H
+
+/* This would be filled in by the openssl configure script if it was run. */
+
+#endif /* HEADER_OPENSSLCONF_H */
+
diff --git a/lib/dns/sec/openssl/include/openssl/opensslv.h b/lib/dns/sec/openssl/include/openssl/opensslv.h
new file mode 100644
index 00000000..b34462e9
--- /dev/null
+++ b/lib/dns/sec/openssl/include/openssl/opensslv.h
@@ -0,0 +1,20 @@
+#ifndef HEADER_OPENSSLV_H
+#define HEADER_OPENSSLV_H
+
+/* Numeric release version identifier:
+ * MMNNFFRBB: major minor fix final beta/patch
+ * For example:
+ * 0.9.3-dev 0x00903000
+ * 0.9.3beta1 0x00903001
+ * 0.9.3beta2-dev 0x00903002
+ * 0.9.3beta2 0x00903002
+ * 0.9.3 0x00903100
+ * 0.9.3a 0x00903101
+ * 1.2.3z 0x1020311a
+ * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.)
+ */
+#define OPENSSL_VERSION_NUMBER 0x00903101L
+#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.3a 29 May 1999"
+#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
+
+#endif /* HEADER_OPENSSLV_H */
diff --git a/lib/dns/sec/openssl/include/openssl/rand.h b/lib/dns/sec/openssl/include/openssl/rand.h
new file mode 100644
index 00000000..fd8ee383
--- /dev/null
+++ b/lib/dns/sec/openssl/include/openssl/rand.h
@@ -0,0 +1,89 @@
+/* crypto/rand/rand.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RAND_H
+#define HEADER_RAND_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct rand_meth_st
+ {
+ void (*seed)(const void *buf, int num);
+ void (*bytes)(unsigned char *buf, int num);
+ void (*cleanup)(void);
+ } RAND_METHOD;
+
+void RAND_set_rand_method(RAND_METHOD *meth);
+RAND_METHOD *RAND_get_rand_method(void );
+RAND_METHOD *RAND_SSLeay(void);
+void RAND_cleanup(void );
+void RAND_bytes(unsigned char *buf,int num);
+void RAND_seed(const void *buf,int num);
+int RAND_load_file(const char *file,long max_bytes);
+int RAND_write_file(const char *file);
+char *RAND_file_name(char *file,int num);
+#ifdef WINDOWS
+void RAND_screen(void);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/dns/sec/openssl/include/openssl/sha.h b/lib/dns/sec/openssl/include/openssl/sha.h
new file mode 100644
index 00000000..cd6960ee
--- /dev/null
+++ b/lib/dns/sec/openssl/include/openssl/sha.h
@@ -0,0 +1,119 @@
+/* crypto/sha/sha.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_SHA_H
+#define HEADER_SHA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef NO_SHA
+#error SHA is disabled.
+#endif
+
+/*
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then !
+ * ! SHA_LONG_LOG2 has to be defined along. !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+#if defined(WIN16) || defined(__LP32__)
+#define SHA_LONG unsigned long
+#elif defined(_CRAY) || defined(__ILP64__)
+#define SHA_LONG unsigned long
+#define SHA_LONG_LOG2 3
+#else
+#define SHA_LONG unsigned int
+#endif
+
+#define SHA_LBLOCK 16
+#define SHA_CBLOCK (SHA_LBLOCK*4) /* SHA treats input data as a
+ * contiguous array of 32 bit
+ * wide big-endian values. */
+#define SHA_LAST_BLOCK (SHA_CBLOCK-8)
+#define SHA_DIGEST_LENGTH 20
+
+typedef struct SHAstate_st
+ {
+ SHA_LONG h0,h1,h2,h3,h4;
+ SHA_LONG Nl,Nh;
+ SHA_LONG data[SHA_LBLOCK];
+ int num;
+ } SHA_CTX;
+
+#ifndef NO_SHA0
+void SHA_Init(SHA_CTX *c);
+void SHA_Update(SHA_CTX *c, const unsigned char *data, unsigned long len);
+void SHA_Final(unsigned char *md, SHA_CTX *c);
+unsigned char *SHA(const unsigned char *d, unsigned long n,unsigned char *md);
+void SHA_Transform(SHA_CTX *c, unsigned char *data);
+#endif
+#ifndef NO_SHA1
+void SHA1_Init(SHA_CTX *c);
+void SHA1_Update(SHA_CTX *c, const unsigned char *data, unsigned long len);
+void SHA1_Final(unsigned char *md, SHA_CTX *c);
+unsigned char *SHA1(const unsigned char *d, unsigned long n,unsigned char *md);
+void SHA1_Transform(SHA_CTX *c, unsigned char *data);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/dns/sec/openssl/include/openssl/stack.h b/lib/dns/sec/openssl/include/openssl/stack.h
new file mode 100644
index 00000000..ec629d0f
--- /dev/null
+++ b/lib/dns/sec/openssl/include/openssl/stack.h
@@ -0,0 +1,106 @@
+/* crypto/stack/stack.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_STACK_H
+#define HEADER_STACK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct stack_st
+ {
+ int num;
+ char **data;
+ int sorted;
+
+ int num_alloc;
+ int (*comp)();
+ } STACK;
+
+
+#define sk_new_null() sk_new(NULL)
+
+#define M_sk_num(sk) ((sk)->num)
+#define M_sk_value(sk,n) ((sk)->data[n])
+
+int sk_num(STACK *);
+char *sk_value(STACK *, int);
+
+char *sk_set(STACK *, int, char *);
+
+STACK *sk_new(int (*cmp)());
+void sk_free(STACK *);
+void sk_pop_free(STACK *st, void (*func)());
+int sk_insert(STACK *sk,char *data,int where);
+char *sk_delete(STACK *st,int loc);
+char *sk_delete_ptr(STACK *st, char *p);
+int sk_find(STACK *st,char *data);
+int sk_push(STACK *st,char *data);
+int sk_unshift(STACK *st,char *data);
+char *sk_shift(STACK *st);
+char *sk_pop(STACK *st);
+void sk_zero(STACK *st);
+int (*sk_set_cmp_func(STACK *sk, int (*c)()))();
+STACK *sk_dup(STACK *st);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/dns/sec/openssl/lhash.c b/lib/dns/sec/openssl/lhash.c
new file mode 100644
index 00000000..801322be
--- /dev/null
+++ b/lib/dns/sec/openssl/lhash.c
@@ -0,0 +1,476 @@
+/* crypto/lhash/lhash.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Code for dynamic hash table routines
+ * Author - Eric Young v 2.0
+ *
+ * 2.2 eay - added #include "crypto.h" so the memory leak checking code is
+ * present. eay 18-Jun-98
+ *
+ * 2.1 eay - Added an 'error in last operation' flag. eay 6-May-98
+ *
+ * 2.0 eay - Fixed a bug that occured when using lh_delete
+ * from inside lh_doall(). As entries were deleted,
+ * the 'table' was 'contract()ed', making some entries
+ * jump from the end of the table to the start, there by
+ * skiping the lh_doall() processing. eay - 4/12/95
+ *
+ * 1.9 eay - Fixed a memory leak in lh_free, the LHASH_NODEs
+ * were not being free()ed. 21/11/95
+ *
+ * 1.8 eay - Put the stats routines into a separate file, lh_stats.c
+ * 19/09/95
+ *
+ * 1.7 eay - Removed the fputs() for realloc failures - the code
+ * should silently tolerate them. I have also fixed things
+ * lint complained about 04/05/95
+ *
+ * 1.6 eay - Fixed an invalid pointers in contract/expand 27/07/92
+ *
+ * 1.5 eay - Fixed a misuse of realloc in expand 02/03/1992
+ *
+ * 1.4 eay - Fixed lh_doall so the function can call lh_delete 28/05/91
+ *
+ * 1.3 eay - Fixed a few lint problems 19/3/1991
+ *
+ * 1.2 eay - Fixed lh_doall problem 13/3/1991
+ *
+ * 1.1 eay - Added lh_doall
+ *
+ * 1.0 eay - First version
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <openssl/crypto.h>
+#include <openssl/lhash.h>
+
+const char *lh_version="lhash" OPENSSL_VERSION_PTEXT;
+
+#undef MIN_NODES
+#define MIN_NODES 16
+#define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */
+#define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */
+
+
+#define P_CP char *
+#define P_CPP char *,char *
+static void expand(LHASH *lh);
+static void contract(LHASH *lh);
+static LHASH_NODE **getrn(LHASH *lh, char *data, unsigned long *rhash);
+
+LHASH *lh_new(unsigned long (*h)(), int (*c)())
+ {
+ LHASH *ret;
+ int i;
+
+ if ((ret=(LHASH *)Malloc(sizeof(LHASH))) == NULL)
+ goto err0;
+ if ((ret->b=(LHASH_NODE **)Malloc(sizeof(LHASH_NODE *)*MIN_NODES)) == NULL)
+ goto err1;
+ for (i=0; i<MIN_NODES; i++)
+ ret->b[i]=NULL;
+ ret->comp=((c == NULL)?(int (*)())strcmp:c);
+ ret->hash=((h == NULL)?(unsigned long (*)())lh_strhash:h);
+ ret->num_nodes=MIN_NODES/2;
+ ret->num_alloc_nodes=MIN_NODES;
+ ret->p=0;
+ ret->pmax=MIN_NODES/2;
+ ret->up_load=UP_LOAD;
+ ret->down_load=DOWN_LOAD;
+ ret->num_items=0;
+
+ ret->num_expands=0;
+ ret->num_expand_reallocs=0;
+ ret->num_contracts=0;
+ ret->num_contract_reallocs=0;
+ ret->num_hash_calls=0;
+ ret->num_comp_calls=0;
+ ret->num_insert=0;
+ ret->num_replace=0;
+ ret->num_delete=0;
+ ret->num_no_delete=0;
+ ret->num_retrieve=0;
+ ret->num_retrieve_miss=0;
+ ret->num_hash_comps=0;
+
+ ret->error=0;
+ return(ret);
+err1:
+ Free((char *)ret);
+err0:
+ return(NULL);
+ }
+
+void lh_free(LHASH *lh)
+ {
+ unsigned int i;
+ LHASH_NODE *n,*nn;
+
+ if(lh == NULL)
+ return;
+
+ for (i=0; i<lh->num_nodes; i++)
+ {
+ n=lh->b[i];
+ while (n != NULL)
+ {
+ nn=n->next;
+ Free(n);
+ n=nn;
+ }
+ }
+ Free((char *)lh->b);
+ Free((char *)lh);
+ }
+
+char *lh_insert(LHASH *lh, char *data)
+ {
+ unsigned long hash;
+ LHASH_NODE *nn,**rn;
+ char *ret;
+
+ lh->error=0;
+ if (lh->up_load <= (lh->num_items*LH_LOAD_MULT/lh->num_nodes))
+ expand(lh);
+
+ rn=getrn(lh,data,&hash);
+
+ if (*rn == NULL)
+ {
+ if ((nn=(LHASH_NODE *)Malloc(sizeof(LHASH_NODE))) == NULL)
+ {
+ lh->error++;
+ return(NULL);
+ }
+ nn->data=data;
+ nn->next=NULL;
+#ifndef NO_HASH_COMP
+ nn->hash=hash;
+#endif
+ *rn=nn;
+ ret=NULL;
+ lh->num_insert++;
+ lh->num_items++;
+ }
+ else /* replace same key */
+ {
+ ret= (*rn)->data;
+ (*rn)->data=data;
+ lh->num_replace++;
+ }
+ return(ret);
+ }
+
+char *lh_delete(LHASH *lh, char *data)
+ {
+ unsigned long hash;
+ LHASH_NODE *nn,**rn;
+ char *ret;
+
+ lh->error=0;
+ rn=getrn(lh,data,&hash);
+
+ if (*rn == NULL)
+ {
+ lh->num_no_delete++;
+ return(NULL);
+ }
+ else
+ {
+ nn= *rn;
+ *rn=nn->next;
+ ret=nn->data;
+ Free((char *)nn);
+ lh->num_delete++;
+ }
+
+ lh->num_items--;
+ if ((lh->num_nodes > MIN_NODES) &&
+ (lh->down_load >= (lh->num_items*LH_LOAD_MULT/lh->num_nodes)))
+ contract(lh);
+
+ return(ret);
+ }
+
+char *lh_retrieve(LHASH *lh, char *data)
+ {
+ unsigned long hash;
+ LHASH_NODE **rn;
+ char *ret;
+
+ lh->error=0;
+ rn=getrn(lh,data,&hash);
+
+ if (*rn == NULL)
+ {
+ lh->num_retrieve_miss++;
+ return(NULL);
+ }
+ else
+ {
+ ret= (*rn)->data;
+ lh->num_retrieve++;
+ }
+ return(ret);
+ }
+
+void lh_doall(LHASH *lh, void (*func)())
+ {
+ lh_doall_arg(lh,func,NULL);
+ }
+
+void lh_doall_arg(LHASH *lh, void (*func)(), char *arg)
+ {
+ int i;
+ LHASH_NODE *a,*n;
+
+ /* reverse the order so we search from 'top to bottom'
+ * We were having memory leaks otherwise */
+ for (i=lh->num_nodes-1; i>=0; i--)
+ {
+ a=lh->b[i];
+ while (a != NULL)
+ {
+ /* 28/05/91 - eay - n added so items can be deleted
+ * via lh_doall */
+ n=a->next;
+ func(a->data,arg);
+ a=n;
+ }
+ }
+ }
+
+static void expand(LHASH *lh)
+ {
+ LHASH_NODE **n,**n1,**n2,*np;
+ unsigned int p,i,j;
+ unsigned long hash,nni;
+
+ lh->num_nodes++;
+ lh->num_expands++;
+ p=(int)lh->p++;
+ n1= &(lh->b[p]);
+ n2= &(lh->b[p+(int)lh->pmax]);
+ *n2=NULL; /* 27/07/92 - eay - undefined pointer bug */
+ nni=lh->num_alloc_nodes;
+
+ for (np= *n1; np != NULL; )
+ {
+#ifndef NO_HASH_COMP
+ hash=np->hash;
+#else
+ hash=(*(lh->hash))(np->data);
+ lh->num_hash_calls++;
+#endif
+ if ((hash%nni) != p)
+ { /* move it */
+ *n1= (*n1)->next;
+ np->next= *n2;
+ *n2=np;
+ }
+ else
+ n1= &((*n1)->next);
+ np= *n1;
+ }
+
+ if ((lh->p) >= lh->pmax)
+ {
+ j=(int)lh->num_alloc_nodes*2;
+ n=(LHASH_NODE **)Realloc((char *)lh->b,
+ (unsigned int)sizeof(LHASH_NODE *)*j);
+ if (n == NULL)
+ {
+/* fputs("realloc error in lhash",stderr); */
+ lh->error++;
+ lh->p=0;
+ return;
+ }
+ /* else */
+ for (i=(int)lh->num_alloc_nodes; i<j; i++)/* 26/02/92 eay */
+ n[i]=NULL; /* 02/03/92 eay */
+ lh->pmax=lh->num_alloc_nodes;
+ lh->num_alloc_nodes=j;
+ lh->num_expand_reallocs++;
+ lh->p=0;
+ lh->b=n;
+ }
+ }
+
+static void contract(LHASH *lh)
+ {
+ LHASH_NODE **n,*n1,*np;
+
+ np=lh->b[lh->p+lh->pmax-1];
+ lh->b[lh->p+lh->pmax-1]=NULL; /* 24/07-92 - eay - weird but :-( */
+ if (lh->p == 0)
+ {
+ n=(LHASH_NODE **)Realloc((char *)lh->b,
+ (unsigned int)(sizeof(LHASH_NODE *)*lh->pmax));
+ if (n == NULL)
+ {
+/* fputs("realloc error in lhash",stderr); */
+ lh->error++;
+ return;
+ }
+ lh->num_contract_reallocs++;
+ lh->num_alloc_nodes/=2;
+ lh->pmax/=2;
+ lh->p=lh->pmax-1;
+ lh->b=n;
+ }
+ else
+ lh->p--;
+
+ lh->num_nodes--;
+ lh->num_contracts++;
+
+ n1=lh->b[(int)lh->p];
+ if (n1 == NULL)
+ lh->b[(int)lh->p]=np;
+ else
+ {
+ while (n1->next != NULL)
+ n1=n1->next;
+ n1->next=np;
+ }
+ }
+
+static LHASH_NODE **getrn(LHASH *lh, char *data, unsigned long *rhash)
+ {
+ LHASH_NODE **ret,*n1;
+ unsigned long hash,nn;
+ int (*cf)();
+
+ hash=(*(lh->hash))(data);
+ lh->num_hash_calls++;
+ *rhash=hash;
+
+ nn=hash%lh->pmax;
+ if (nn < lh->p)
+ nn=hash%lh->num_alloc_nodes;
+
+ cf=lh->comp;
+ ret= &(lh->b[(int)nn]);
+ for (n1= *ret; n1 != NULL; n1=n1->next)
+ {
+#ifndef NO_HASH_COMP
+ lh->num_hash_comps++;
+ if (n1->hash != hash)
+ {
+ ret= &(n1->next);
+ continue;
+ }
+#endif
+ lh->num_comp_calls++;
+ if ((*cf)(n1->data,data) == 0)
+ break;
+ ret= &(n1->next);
+ }
+ return(ret);
+ }
+
+/*
+static unsigned long lh_strhash(str)
+char *str;
+ {
+ int i,l;
+ unsigned long ret=0;
+ unsigned short *s;
+
+ if (str == NULL) return(0);
+ l=(strlen(str)+1)/2;
+ s=(unsigned short *)str;
+ for (i=0; i<l; i++)
+ ret^=(s[i]<<(i&0x0f));
+ return(ret);
+ } */
+
+/* The following hash seems to work very well on normal text strings
+ * no collisions on /usr/dict/words and it distributes on %2^n quite
+ * well, not as good as MD5, but still good.
+ */
+unsigned long lh_strhash(const char *c)
+ {
+ unsigned long ret=0;
+ long n;
+ unsigned long v;
+ int r;
+
+ if ((c == NULL) || (*c == '\0'))
+ return(ret);
+/*
+ unsigned char b[16];
+ MD5(c,strlen(c),b);
+ return(b[0]|(b[1]<<8)|(b[2]<<16)|(b[3]<<24));
+*/
+
+ n=0x100;
+ while (*c)
+ {
+ v=n|(*c);
+ n+=0x100;
+ r= (int)((v>>2)^v)&0x0f;
+ ret=(ret<<r)|(ret>>(32-r));
+ ret&=0xFFFFFFFFL;
+ ret^=v*v;
+ c++;
+ }
+ return((ret>>16)^ret);
+ }
+
diff --git a/lib/dns/sec/openssl/md32_common.h b/lib/dns/sec/openssl/md32_common.h
new file mode 100644
index 00000000..f19e1bf7
--- /dev/null
+++ b/lib/dns/sec/openssl/md32_common.h
@@ -0,0 +1,594 @@
+/* crypto/md32_common.h */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/*
+ * This is a generic 32 bit "collector" for message digest algorithms.
+ * Whenever needed it collects input character stream into chunks of
+ * 32 bit values and invokes a block function that performs actual hash
+ * calculations.
+ *
+ * Porting guide.
+ *
+ * Obligatory macros:
+ *
+ * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
+ * this macro defines byte order of input stream.
+ * HASH_CBLOCK
+ * size of a unit chunk HASH_BLOCK operates on.
+ * HASH_LONG
+ * has to be at lest 32 bit wide, if it's wider, then
+ * HASH_LONG_LOG2 *has to* be defined along
+ * HASH_CTX
+ * context structure that at least contains following
+ * members:
+ * typedef struct {
+ * ...
+ * HASH_LONG Nl,Nh;
+ * HASH_LONG data[HASH_LBLOCK];
+ * int num;
+ * ...
+ * } HASH_CTX;
+ * HASH_UPDATE
+ * name of "Update" function, implemented here.
+ * HASH_TRANSFORM
+ * name of "Transform" function, implemented here.
+ * HASH_FINAL
+ * name of "Final" function, implemented here.
+ * HASH_BLOCK_HOST_ORDER
+ * name of "block" function treating *aligned* input message
+ * in host byte order, implemented externally.
+ * HASH_BLOCK_DATA_ORDER
+ * name of "block" function treating *unaligned* input message
+ * in original (data) byte order, implemented externally (it
+ * actually is optional if data and host are of the same
+ * "endianess").
+ *
+ * Optional macros:
+ *
+ * B_ENDIAN or L_ENDIAN
+ * defines host byte-order.
+ * HASH_LONG_LOG2
+ * defaults to 2 if not states otherwise.
+ * HASH_LBLOCK
+ * assumed to be HASH_CBLOCK/4 if not stated otherwise.
+ * HASH_BLOCK_DATA_ORDER_ALIGNED
+ * alternative "block" function capable of treating
+ * aligned input message in original (data) order,
+ * implemented externally.
+ *
+ * MD5 example:
+ *
+ * #define DATA_ORDER_IS_LITTLE_ENDIAN
+ *
+ * #define HASH_LONG MD5_LONG
+ * #define HASH_LONG_LOG2 MD5_LONG_LOG2
+ * #define HASH_CTX MD5_CTX
+ * #define HASH_CBLOCK MD5_CBLOCK
+ * #define HASH_LBLOCK MD5_LBLOCK
+ * #define HASH_UPDATE MD5_Update
+ * #define HASH_TRANSFORM MD5_Transform
+ * #define HASH_FINAL MD5_Final
+ * #define HASH_BLOCK_HOST_ORDER md5_block_host_order
+ * #define HASH_BLOCK_DATA_ORDER md5_block_data_order
+ *
+ * <appro@fy.chalmers.se>
+ */
+
+#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+#error "DATA_ORDER must be defined!"
+#endif
+
+#ifndef HASH_CBLOCK
+#error "HASH_CBLOCK must be defined!"
+#endif
+#ifndef HASH_LONG
+#error "HASH_LONG must be defined!"
+#endif
+#ifndef HASH_CTX
+#error "HASH_CTX must be defined!"
+#endif
+
+#ifndef HASH_UPDATE
+#error "HASH_UPDATE must be defined!"
+#endif
+#ifndef HASH_TRANSFORM
+#error "HASH_TRANSFORM must be defined!"
+#endif
+#ifndef HASH_FINAL
+#error "HASH_FINAL must be defined!"
+#endif
+
+#ifndef HASH_BLOCK_HOST_ORDER
+#error "HASH_BLOCK_HOST_ORDER must be defined!"
+#endif
+
+#if 0
+/*
+ * Moved below as it's required only if HASH_BLOCK_DATA_ORDER_ALIGNED
+ * isn't defined.
+ */
+#ifndef HASH_BLOCK_DATA_ORDER
+#error "HASH_BLOCK_DATA_ORDER must be defined!"
+#endif
+#endif
+
+#ifndef HASH_LBLOCK
+#define HASH_LBLOCK (HASH_CBLOCK/4)
+#endif
+
+#ifndef HASH_LONG_LOG2
+#define HASH_LONG_LOG2 2
+#endif
+
+/*
+ * Engage compiler specific rotate intrinsic function if available.
+ */
+#undef ROTATE
+#ifndef PEDANTIC
+# if defined(_MSC_VER)
+# define ROTATE(a,n) _lrotl(a,n)
+# elif defined(__GNUC__) && __GNUC__>=2
+ /*
+ * Some GNU C inline assembler templates. Note that these are
+ * rotates by *constant* number of bits! But that's exactly
+ * what we need here...
+ *
+ * <appro@fy.chalmers.se>
+ */
+# if defined(__i386)
+# define ROTATE(a,n) ({ register unsigned int ret; \
+ asm volatile ( \
+ "roll %1,%0" \
+ : "=r"(ret) \
+ : "I"(n), "0"(a) \
+ : "cc"); \
+ ret; \
+ })
+# elif defined(__powerpc)
+# define ROTATE(a,n) ({ register unsigned int ret; \
+ asm volatile ( \
+ "rlwinm %0,%1,%2,0,31" \
+ : "=r"(ret) \
+ : "r"(a), "I"(n)); \
+ ret; \
+ })
+# endif
+# endif
+
+/*
+ * Engage compiler specific "fetch in reverse byte order"
+ * intrinsic function if available.
+ */
+# if defined(__GNUC__) && __GNUC__>=2
+ /* some GNU C inline assembler templates by <appro@fy.chalmers.se> */
+# if defined(__i386) && !defined(I386_ONLY)
+# define BE_FETCH32(a) ({ register unsigned int l=(a);\
+ asm volatile ( \
+ "bswapl %0" \
+ : "=r"(l) : "0"(l)); \
+ l; \
+ })
+# elif defined(__powerpc)
+# define LE_FETCH32(a) ({ register unsigned int l; \
+ asm volatile ( \
+ "lwbrx %0,0,%1" \
+ : "=r"(l) \
+ : "r"(a)); \
+ l; \
+ })
+
+# elif defined(__sparc) && defined(ULTRASPARC)
+# define LE_FETCH32(a) ({ register unsigned int l; \
+ asm volatile ( \
+ "lda [%1]#ASI_PRIMARY_LITTLE,%0"\
+ : "=r"(l) \
+ : "r"(a)); \
+ l; \
+ })
+# endif
+# endif
+#endif /* PEDANTIC */
+
+#if HASH_LONG_LOG2==2 /* Engage only if sizeof(HASH_LONG)== 4 */
+/* A nice byte order reversal from Wei Dai <weidai@eskimo.com> */
+#ifdef ROTATE
+/* 5 instructions with rotate instruction, else 9 */
+#define REVERSE_FETCH32(a,l) ( \
+ l=*(const HASH_LONG *)(a), \
+ ((ROTATE(l,8)&0x00FF00FF)|(ROTATE((l&0x00FF00FF),24))) \
+ )
+#else
+/* 6 instructions with rotate instruction, else 8 */
+#define REVERSE_FETCH32(a,l) ( \
+ l=*(const HASH_LONG *)(a), \
+ l=(((l>>8)&0x00FF00FF)|((l&0x00FF00FF)<<8)), \
+ ROTATE(l,16) \
+ )
+/*
+ * Originally the middle line started with l=(((l&0xFF00FF00)>>8)|...
+ * It's rewritten as above for two reasons:
+ * - RISCs aren't good at long constants and have to explicitely
+ * compose 'em with several (well, usually 2) instructions in a
+ * register before performing the actual operation and (as you
+ * already realized:-) having same constant should inspire the
+ * compiler to permanently allocate the only register for it;
+ * - most modern CPUs have two ALUs, but usually only one has
+ * circuitry for shifts:-( this minor tweak inspires compiler
+ * to schedule shift instructions in a better way...
+ *
+ * <appro@fy.chalmers.se>
+ */
+#endif
+#endif
+
+#ifndef ROTATE
+#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
+#endif
+
+/*
+ * Make some obvious choices. E.g., HASH_BLOCK_DATA_ORDER_ALIGNED
+ * and HASH_BLOCK_HOST_ORDER ought to be the same if input data
+ * and host are of the same "endianess". It's possible to mask
+ * this with blank #define HASH_BLOCK_DATA_ORDER though...
+ *
+ * <appro@fy.chalmers.se>
+ */
+#if defined(B_ENDIAN)
+# if defined(DATA_ORDER_IS_BIG_ENDIAN)
+# if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2
+# define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER
+# endif
+# elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+# ifndef HOST_FETCH32
+# ifdef LE_FETCH32
+# define HOST_FETCH32(p,l) LE_FETCH32(p)
+# elif defined(REVERSE_FETCH32)
+# define HOST_FETCH32(p,l) REVERSE_FETCH32(p,l)
+# endif
+# endif
+# endif
+#elif defined(L_ENDIAN)
+# if defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+# if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2
+# define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER
+# endif
+# elif defined(DATA_ORDER_IS_BIG_ENDIAN)
+# ifndef HOST_FETCH32
+# ifdef BE_FETCH32
+# define HOST_FETCH32(p,l) BE_FETCH32(p)
+# elif defined(REVERSE_FETCH32)
+# define HOST_FETCH32(p,l) REVERSE_FETCH32(p,l)
+# endif
+# endif
+# endif
+#endif
+
+#if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) || HASH_BLOCK_DATA_ORDER_ALIGNED==1
+#ifndef HASH_BLOCK_DATA_ORDER
+#error "HASH_BLOCK_DATA_ORDER must be defined!"
+#endif
+#endif
+
+#if defined(DATA_ORDER_IS_BIG_ENDIAN)
+
+#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \
+ l|=(((unsigned long)(*((c)++)))<<16), \
+ l|=(((unsigned long)(*((c)++)))<< 8), \
+ l|=(((unsigned long)(*((c)++))) ), \
+ l)
+#define HOST_p_c2l(c,l,n) { \
+ switch (n) { \
+ case 0: l =((unsigned long)(*((c)++)))<<24; \
+ case 1: l|=((unsigned long)(*((c)++)))<<16; \
+ case 2: l|=((unsigned long)(*((c)++)))<< 8; \
+ case 3: l|=((unsigned long)(*((c)++))); \
+ } }
+#define HOST_p_c2l_p(c,l,sc,len) { \
+ switch (sc) { \
+ case 0: l =((unsigned long)(*((c)++)))<<24; \
+ if (--len == 0) break; \
+ case 1: l|=((unsigned long)(*((c)++)))<<16; \
+ if (--len == 0) break; \
+ case 2: l|=((unsigned long)(*((c)++)))<< 8; \
+ } }
+/* NOTE the pointer is not incremented at the end of this */
+#define HOST_c2l_p(c,l,n) { \
+ l=0; (c)+=n; \
+ switch (n) { \
+ case 3: l =((unsigned long)(*(--(c))))<< 8; \
+ case 2: l|=((unsigned long)(*(--(c))))<<16; \
+ case 1: l|=((unsigned long)(*(--(c))))<<24; \
+ } }
+#define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l) )&0xff), \
+ l)
+
+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+
+#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \
+ l|=(((unsigned long)(*((c)++)))<< 8), \
+ l|=(((unsigned long)(*((c)++)))<<16), \
+ l|=(((unsigned long)(*((c)++)))<<24), \
+ l)
+#define HOST_p_c2l(c,l,n) { \
+ switch (n) { \
+ case 0: l =((unsigned long)(*((c)++))); \
+ case 1: l|=((unsigned long)(*((c)++)))<< 8; \
+ case 2: l|=((unsigned long)(*((c)++)))<<16; \
+ case 3: l|=((unsigned long)(*((c)++)))<<24; \
+ } }
+#define HOST_p_c2l_p(c,l,sc,len) { \
+ switch (sc) { \
+ case 0: l =((unsigned long)(*((c)++))); \
+ if (--len == 0) break; \
+ case 1: l|=((unsigned long)(*((c)++)))<< 8; \
+ if (--len == 0) break; \
+ case 2: l|=((unsigned long)(*((c)++)))<<16; \
+ } }
+/* NOTE the pointer is not incremented at the end of this */
+#define HOST_c2l_p(c,l,n) { \
+ l=0; (c)+=n; \
+ switch (n) { \
+ case 3: l =((unsigned long)(*(--(c))))<<16; \
+ case 2: l|=((unsigned long)(*(--(c))))<< 8; \
+ case 1: l|=((unsigned long)(*(--(c)))); \
+ } }
+#define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>24)&0xff), \
+ l)
+
+#endif
+
+/*
+ * Time for some action:-)
+ */
+
+void HASH_UPDATE (HASH_CTX *c, const unsigned char *data, unsigned long len)
+ {
+ register HASH_LONG * p;
+ register unsigned long l;
+ int sw,sc,ew,ec;
+
+ if (len==0) return;
+
+ l=(c->Nl+(len<<3))&0xffffffffL;
+ /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
+ * Wei Dai <weidai@eskimo.com> for pointing it out. */
+ if (l < c->Nl) /* overflow */
+ c->Nh++;
+ c->Nh+=(len>>29);
+ c->Nl=l;
+
+ if (c->num != 0)
+ {
+ p=c->data;
+ sw=c->num>>2;
+ sc=c->num&0x03;
+
+ if ((c->num+len) >= HASH_CBLOCK)
+ {
+ l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l;
+ for (; sw<HASH_LBLOCK; sw++)
+ {
+ HOST_c2l(data,l); p[sw]=l;
+ }
+ HASH_BLOCK_HOST_ORDER (c,p,1);
+ len-=(HASH_CBLOCK-c->num);
+ c->num=0;
+ /* drop through and do the rest */
+ }
+ else
+ {
+ c->num+=len;
+ if ((sc+len) < 4) /* ugly, add char's to a word */
+ {
+ l=p[sw]; HOST_p_c2l_p(data,l,sc,len); p[sw]=l;
+ }
+ else
+ {
+ ew=(c->num>>2);
+ ec=(c->num&0x03);
+ l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l;
+ for (; sw < ew; sw++)
+ {
+ HOST_c2l(data,l); p[sw]=l;
+ }
+ if (ec)
+ {
+ HOST_c2l_p(data,l,ec); p[sw]=l;
+ }
+ }
+ return;
+ }
+ }
+
+ sw=len/HASH_CBLOCK;
+ if (sw > 0)
+ {
+#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_BLOCK_DATA_ORDER_ALIGNED!=1
+ /*
+ * Note that HASH_BLOCK_DATA_ORDER_ALIGNED gets defined
+ * only if sizeof(HASH_LONG)==4.
+ */
+ if ((((unsigned long)data)%4) == 0)
+ {
+ /* data is properly aligned so that we can cast it: */
+ HASH_BLOCK_DATA_ORDER_ALIGNED (c,(HASH_LONG *)data,sw);
+ sw*=HASH_CBLOCK;
+ data+=sw;
+ len-=sw;
+ }
+ else
+#if !defined(HASH_BLOCK_DATA_ORDER)
+ while (sw--)
+ {
+ memcpy (p=c->data,data,HASH_CBLOCK);
+ HASH_BLOCK_DATA_ORDER_ALIGNED(c,p,1);
+ data+=HASH_CBLOCK;
+ len-=HASH_CBLOCK;
+ }
+#endif
+#endif
+#if defined(HASH_BLOCK_DATA_ORDER)
+ {
+ HASH_BLOCK_DATA_ORDER(c,data,sw);
+ sw*=HASH_CBLOCK;
+ data+=sw;
+ len-=sw;
+ }
+#endif
+ }
+
+ if (len!=0)
+ {
+ p = c->data;
+ c->num = len;
+ ew=len>>2; /* words to copy */
+ ec=len&0x03;
+ for (; ew; ew--,p++)
+ {
+ HOST_c2l(data,l); *p=l;
+ }
+ HOST_c2l_p(data,l,ec);
+ *p=l;
+ }
+ }
+
+
+void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data)
+ {
+#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_BLOCK_DATA_ORDER_ALIGNED!=1
+ if ((((unsigned long)data)%4) == 0)
+ /* data is properly aligned so that we can cast it: */
+ HASH_BLOCK_DATA_ORDER_ALIGNED (c,(HASH_LONG *)data,1);
+ else
+#if !defined(HASH_BLOCK_DATA_ORDER)
+ {
+ memcpy (c->data,data,HASH_CBLOCK);
+ HASH_BLOCK_DATA_ORDER_ALIGNED (c,c->data,1);
+ }
+#endif
+#endif
+#if defined(HASH_BLOCK_DATA_ORDER)
+ HASH_BLOCK_DATA_ORDER (c,data,1);
+#endif
+ }
+
+
+void HASH_FINAL (unsigned char *md, HASH_CTX *c)
+ {
+ register HASH_LONG *p;
+ register unsigned long l;
+ register int i,j;
+ static const unsigned char end[4]={0x80,0x00,0x00,0x00};
+ const unsigned char *cp=end;
+
+ /* c->num should definitly have room for at least one more byte. */
+ p=c->data;
+ i=c->num>>2;
+ j=c->num&0x03;
+
+#if 0
+ /* purify often complains about the following line as an
+ * Uninitialized Memory Read. While this can be true, the
+ * following p_c2l macro will reset l when that case is true.
+ * This is because j&0x03 contains the number of 'valid' bytes
+ * already in p[i]. If and only if j&0x03 == 0, the UMR will
+ * occur but this is also the only time p_c2l will do
+ * l= *(cp++) instead of l|= *(cp++)
+ * Many thanks to Alex Tang <altitude@cic.net> for pickup this
+ * 'potential bug' */
+#ifdef PURIFY
+ if (j==0) p[i]=0; /* Yeah, but that's not the way to fix it:-) */
+#endif
+ l=p[i];
+#else
+ l = (j==0) ? 0 : p[i];
+#endif
+ HOST_p_c2l(cp,l,j); p[i++]=l; /* i is the next 'undefined word' */
+
+ if (i>(HASH_LBLOCK-2)) /* save room for Nl and Nh */
+ {
+ if (i<HASH_LBLOCK) p[i]=0;
+ HASH_BLOCK_HOST_ORDER (c,p,1);
+ i=0;
+ }
+ for (; i<(HASH_LBLOCK-2); i++)
+ p[i]=0;
+
+#if defined(DATA_ORDER_IS_BIG_ENDIAN)
+ p[HASH_LBLOCK-2]=c->Nh;
+ p[HASH_LBLOCK-1]=c->Nl;
+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+ p[HASH_LBLOCK-2]=c->Nl;
+ p[HASH_LBLOCK-1]=c->Nh;
+#endif
+ HASH_BLOCK_HOST_ORDER (c,p,1);
+
+ l=c->A; HOST_l2c(l,md);
+ l=c->B; HOST_l2c(l,md);
+ l=c->C; HOST_l2c(l,md);
+ l=c->D; HOST_l2c(l,md);
+
+ c->num=0;
+ /* clear stuff, HASH_BLOCK may be leaving some stuff on the stack
+ * but I'm not worried :-)
+ memset((void *)c,0,sizeof(HASH_CTX));
+ */
+ }
diff --git a/lib/dns/sec/openssl/md5_dgst.c b/lib/dns/sec/openssl/md5_dgst.c
new file mode 100644
index 00000000..ba0115ae
--- /dev/null
+++ b/lib/dns/sec/openssl/md5_dgst.c
@@ -0,0 +1,317 @@
+/* crypto/md5/md5_dgst.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "md5_locl.h"
+#include <openssl/opensslv.h>
+
+char *MD5_version="MD5" OPENSSL_VERSION_PTEXT;
+
+/* Implemented from RFC1321 The MD5 Message-Digest Algorithm
+ */
+
+#define INIT_DATA_A (unsigned long)0x67452301L
+#define INIT_DATA_B (unsigned long)0xefcdab89L
+#define INIT_DATA_C (unsigned long)0x98badcfeL
+#define INIT_DATA_D (unsigned long)0x10325476L
+
+void MD5_Init(MD5_CTX *c)
+ {
+ c->A=INIT_DATA_A;
+ c->B=INIT_DATA_B;
+ c->C=INIT_DATA_C;
+ c->D=INIT_DATA_D;
+ c->Nl=0;
+ c->Nh=0;
+ c->num=0;
+ }
+
+#ifndef md5_block_host_order
+void md5_block_host_order (MD5_CTX *c, const void *data, int num)
+ {
+ const MD5_LONG *X=data;
+ register unsigned long A,B,C,D;
+ /*
+ * In case you wonder why A-D are declared as long and not
+ * as MD5_LONG. Doing so results in slight performance
+ * boost on LP64 architectures. The catch is we don't
+ * really care if 32 MSBs of a 64-bit register get polluted
+ * with eventual overflows as we *save* only 32 LSBs in
+ * *either* case. Now declaring 'em long excuses the compiler
+ * from keeping 32 MSBs zeroed resulting in 13% performance
+ * improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
+ * Well, to be honest it should say that this *prevents*
+ * performance degradation.
+ *
+ * <appro@fy.chalmers.se>
+ */
+
+ A=c->A;
+ B=c->B;
+ C=c->C;
+ D=c->D;
+
+ for (;num--;X+=HASH_LBLOCK)
+ {
+ /* Round 0 */
+ R0(A,B,C,D,X[ 0], 7,0xd76aa478L);
+ R0(D,A,B,C,X[ 1],12,0xe8c7b756L);
+ R0(C,D,A,B,X[ 2],17,0x242070dbL);
+ R0(B,C,D,A,X[ 3],22,0xc1bdceeeL);
+ R0(A,B,C,D,X[ 4], 7,0xf57c0fafL);
+ R0(D,A,B,C,X[ 5],12,0x4787c62aL);
+ R0(C,D,A,B,X[ 6],17,0xa8304613L);
+ R0(B,C,D,A,X[ 7],22,0xfd469501L);
+ R0(A,B,C,D,X[ 8], 7,0x698098d8L);
+ R0(D,A,B,C,X[ 9],12,0x8b44f7afL);
+ R0(C,D,A,B,X[10],17,0xffff5bb1L);
+ R0(B,C,D,A,X[11],22,0x895cd7beL);
+ R0(A,B,C,D,X[12], 7,0x6b901122L);
+ R0(D,A,B,C,X[13],12,0xfd987193L);
+ R0(C,D,A,B,X[14],17,0xa679438eL);
+ R0(B,C,D,A,X[15],22,0x49b40821L);
+ /* Round 1 */
+ R1(A,B,C,D,X[ 1], 5,0xf61e2562L);
+ R1(D,A,B,C,X[ 6], 9,0xc040b340L);
+ R1(C,D,A,B,X[11],14,0x265e5a51L);
+ R1(B,C,D,A,X[ 0],20,0xe9b6c7aaL);
+ R1(A,B,C,D,X[ 5], 5,0xd62f105dL);
+ R1(D,A,B,C,X[10], 9,0x02441453L);
+ R1(C,D,A,B,X[15],14,0xd8a1e681L);
+ R1(B,C,D,A,X[ 4],20,0xe7d3fbc8L);
+ R1(A,B,C,D,X[ 9], 5,0x21e1cde6L);
+ R1(D,A,B,C,X[14], 9,0xc33707d6L);
+ R1(C,D,A,B,X[ 3],14,0xf4d50d87L);
+ R1(B,C,D,A,X[ 8],20,0x455a14edL);
+ R1(A,B,C,D,X[13], 5,0xa9e3e905L);
+ R1(D,A,B,C,X[ 2], 9,0xfcefa3f8L);
+ R1(C,D,A,B,X[ 7],14,0x676f02d9L);
+ R1(B,C,D,A,X[12],20,0x8d2a4c8aL);
+ /* Round 2 */
+ R2(A,B,C,D,X[ 5], 4,0xfffa3942L);
+ R2(D,A,B,C,X[ 8],11,0x8771f681L);
+ R2(C,D,A,B,X[11],16,0x6d9d6122L);
+ R2(B,C,D,A,X[14],23,0xfde5380cL);
+ R2(A,B,C,D,X[ 1], 4,0xa4beea44L);
+ R2(D,A,B,C,X[ 4],11,0x4bdecfa9L);
+ R2(C,D,A,B,X[ 7],16,0xf6bb4b60L);
+ R2(B,C,D,A,X[10],23,0xbebfbc70L);
+ R2(A,B,C,D,X[13], 4,0x289b7ec6L);
+ R2(D,A,B,C,X[ 0],11,0xeaa127faL);
+ R2(C,D,A,B,X[ 3],16,0xd4ef3085L);
+ R2(B,C,D,A,X[ 6],23,0x04881d05L);
+ R2(A,B,C,D,X[ 9], 4,0xd9d4d039L);
+ R2(D,A,B,C,X[12],11,0xe6db99e5L);
+ R2(C,D,A,B,X[15],16,0x1fa27cf8L);
+ R2(B,C,D,A,X[ 2],23,0xc4ac5665L);
+ /* Round 3 */
+ R3(A,B,C,D,X[ 0], 6,0xf4292244L);
+ R3(D,A,B,C,X[ 7],10,0x432aff97L);
+ R3(C,D,A,B,X[14],15,0xab9423a7L);
+ R3(B,C,D,A,X[ 5],21,0xfc93a039L);
+ R3(A,B,C,D,X[12], 6,0x655b59c3L);
+ R3(D,A,B,C,X[ 3],10,0x8f0ccc92L);
+ R3(C,D,A,B,X[10],15,0xffeff47dL);
+ R3(B,C,D,A,X[ 1],21,0x85845dd1L);
+ R3(A,B,C,D,X[ 8], 6,0x6fa87e4fL);
+ R3(D,A,B,C,X[15],10,0xfe2ce6e0L);
+ R3(C,D,A,B,X[ 6],15,0xa3014314L);
+ R3(B,C,D,A,X[13],21,0x4e0811a1L);
+ R3(A,B,C,D,X[ 4], 6,0xf7537e82L);
+ R3(D,A,B,C,X[11],10,0xbd3af235L);
+ R3(C,D,A,B,X[ 2],15,0x2ad7d2bbL);
+ R3(B,C,D,A,X[ 9],21,0xeb86d391L);
+
+ A = c->A += A;
+ B = c->B += B;
+ C = c->C += C;
+ D = c->D += D;
+ }
+ }
+#endif
+
+#ifndef md5_block_data_order
+void md5_block_data_order (MD5_CTX *c, const void *data_, int num)
+ {
+ const unsigned char *data=data_;
+ register unsigned long A,B,C,D,l;
+ /*
+ * In case you wonder why A-D are declared as long and not
+ * as MD5_LONG. Doing so results in slight performance
+ * boost on LP64 architectures. The catch is we don't
+ * really care if 32 MSBs of a 64-bit register get polluted
+ * with eventual overflows as we *save* only 32 LSBs in
+ * *either* case. Now declaring 'em long excuses the compiler
+ * from keeping 32 MSBs zeroed resulting in 13% performance
+ * improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
+ * Well, to be honest it should say that this *prevents*
+ * performance degradation.
+ *
+ * <appro@fy.chalmers.se>
+ */
+ MD5_LONG X[MD5_LBLOCK];
+ /*
+ * In case you wonder why don't I use c->data for this.
+ * RISCs usually have a handful of registers and if X is
+ * declared as automatic array good optimizing compiler
+ * shall accomodate at least part of it in register bank
+ * instead of memory.
+ *
+ * <appro@fy.chalmers.se>
+ */
+
+ A=c->A;
+ B=c->B;
+ C=c->C;
+ D=c->D;
+
+ for (;num--;)
+ {
+ HOST_c2l(data,l); X[ 0]=l; HOST_c2l(data,l); X[ 1]=l;
+ /* Round 0 */
+ R0(A,B,C,D,X[ 0], 7,0xd76aa478L); HOST_c2l(data,l); X[ 2]=l;
+ R0(D,A,B,C,X[ 1],12,0xe8c7b756L); HOST_c2l(data,l); X[ 3]=l;
+ R0(C,D,A,B,X[ 2],17,0x242070dbL); HOST_c2l(data,l); X[ 4]=l;
+ R0(B,C,D,A,X[ 3],22,0xc1bdceeeL); HOST_c2l(data,l); X[ 5]=l;
+ R0(A,B,C,D,X[ 4], 7,0xf57c0fafL); HOST_c2l(data,l); X[ 6]=l;
+ R0(D,A,B,C,X[ 5],12,0x4787c62aL); HOST_c2l(data,l); X[ 7]=l;
+ R0(C,D,A,B,X[ 6],17,0xa8304613L); HOST_c2l(data,l); X[ 8]=l;
+ R0(B,C,D,A,X[ 7],22,0xfd469501L); HOST_c2l(data,l); X[ 9]=l;
+ R0(A,B,C,D,X[ 8], 7,0x698098d8L); HOST_c2l(data,l); X[10]=l;
+ R0(D,A,B,C,X[ 9],12,0x8b44f7afL); HOST_c2l(data,l); X[11]=l;
+ R0(C,D,A,B,X[10],17,0xffff5bb1L); HOST_c2l(data,l); X[12]=l;
+ R0(B,C,D,A,X[11],22,0x895cd7beL); HOST_c2l(data,l); X[13]=l;
+ R0(A,B,C,D,X[12], 7,0x6b901122L); HOST_c2l(data,l); X[14]=l;
+ R0(D,A,B,C,X[13],12,0xfd987193L); HOST_c2l(data,l); X[15]=l;
+ R0(C,D,A,B,X[14],17,0xa679438eL);
+ R0(B,C,D,A,X[15],22,0x49b40821L);
+ /* Round 1 */
+ R1(A,B,C,D,X[ 1], 5,0xf61e2562L);
+ R1(D,A,B,C,X[ 6], 9,0xc040b340L);
+ R1(C,D,A,B,X[11],14,0x265e5a51L);
+ R1(B,C,D,A,X[ 0],20,0xe9b6c7aaL);
+ R1(A,B,C,D,X[ 5], 5,0xd62f105dL);
+ R1(D,A,B,C,X[10], 9,0x02441453L);
+ R1(C,D,A,B,X[15],14,0xd8a1e681L);
+ R1(B,C,D,A,X[ 4],20,0xe7d3fbc8L);
+ R1(A,B,C,D,X[ 9], 5,0x21e1cde6L);
+ R1(D,A,B,C,X[14], 9,0xc33707d6L);
+ R1(C,D,A,B,X[ 3],14,0xf4d50d87L);
+ R1(B,C,D,A,X[ 8],20,0x455a14edL);
+ R1(A,B,C,D,X[13], 5,0xa9e3e905L);
+ R1(D,A,B,C,X[ 2], 9,0xfcefa3f8L);
+ R1(C,D,A,B,X[ 7],14,0x676f02d9L);
+ R1(B,C,D,A,X[12],20,0x8d2a4c8aL);
+ /* Round 2 */
+ R2(A,B,C,D,X[ 5], 4,0xfffa3942L);
+ R2(D,A,B,C,X[ 8],11,0x8771f681L);
+ R2(C,D,A,B,X[11],16,0x6d9d6122L);
+ R2(B,C,D,A,X[14],23,0xfde5380cL);
+ R2(A,B,C,D,X[ 1], 4,0xa4beea44L);
+ R2(D,A,B,C,X[ 4],11,0x4bdecfa9L);
+ R2(C,D,A,B,X[ 7],16,0xf6bb4b60L);
+ R2(B,C,D,A,X[10],23,0xbebfbc70L);
+ R2(A,B,C,D,X[13], 4,0x289b7ec6L);
+ R2(D,A,B,C,X[ 0],11,0xeaa127faL);
+ R2(C,D,A,B,X[ 3],16,0xd4ef3085L);
+ R2(B,C,D,A,X[ 6],23,0x04881d05L);
+ R2(A,B,C,D,X[ 9], 4,0xd9d4d039L);
+ R2(D,A,B,C,X[12],11,0xe6db99e5L);
+ R2(C,D,A,B,X[15],16,0x1fa27cf8L);
+ R2(B,C,D,A,X[ 2],23,0xc4ac5665L);
+ /* Round 3 */
+ R3(A,B,C,D,X[ 0], 6,0xf4292244L);
+ R3(D,A,B,C,X[ 7],10,0x432aff97L);
+ R3(C,D,A,B,X[14],15,0xab9423a7L);
+ R3(B,C,D,A,X[ 5],21,0xfc93a039L);
+ R3(A,B,C,D,X[12], 6,0x655b59c3L);
+ R3(D,A,B,C,X[ 3],10,0x8f0ccc92L);
+ R3(C,D,A,B,X[10],15,0xffeff47dL);
+ R3(B,C,D,A,X[ 1],21,0x85845dd1L);
+ R3(A,B,C,D,X[ 8], 6,0x6fa87e4fL);
+ R3(D,A,B,C,X[15],10,0xfe2ce6e0L);
+ R3(C,D,A,B,X[ 6],15,0xa3014314L);
+ R3(B,C,D,A,X[13],21,0x4e0811a1L);
+ R3(A,B,C,D,X[ 4], 6,0xf7537e82L);
+ R3(D,A,B,C,X[11],10,0xbd3af235L);
+ R3(C,D,A,B,X[ 2],15,0x2ad7d2bbL);
+ R3(B,C,D,A,X[ 9],21,0xeb86d391L);
+
+ A = c->A += A;
+ B = c->B += B;
+ C = c->C += C;
+ D = c->D += D;
+ }
+ }
+#endif
+
+#ifdef undef
+int printit(unsigned long *l)
+ {
+ int i,ii;
+
+ for (i=0; i<2; i++)
+ {
+ for (ii=0; ii<8; ii++)
+ {
+ fprintf(stderr,"%08lx ",l[i*8+ii]);
+ }
+ fprintf(stderr,"\n");
+ }
+ }
+#endif
diff --git a/lib/dns/sec/openssl/md5_locl.h b/lib/dns/sec/openssl/md5_locl.h
new file mode 100644
index 00000000..849b7938
--- /dev/null
+++ b/lib/dns/sec/openssl/md5_locl.h
@@ -0,0 +1,172 @@
+/* crypto/md5/md5_locl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/opensslconf.h>
+#include <openssl/md5.h>
+
+#ifndef MD5_LONG_LOG2
+#define MD5_LONG_LOG2 2 /* default to 32 bits */
+#endif
+
+#ifdef MD5_ASM
+# if defined(__i386) || defined(WIN32)
+# define md5_block_host_order md5_block_asm_host_order
+# elif defined(__sparc) && defined(ULTRASPARC)
+ void md5_block_asm_data_order_aligned (MD5_CTX *c, const MD5_LONG *p,int num);
+# define HASH_BLOCK_DATA_ORDER_ALIGNED md5_block_asm_data_order_aligned
+# endif
+#endif
+
+void md5_block_host_order (MD5_CTX *c, const void *p,int num);
+void md5_block_data_order (MD5_CTX *c, const void *p,int num);
+
+#if defined(__i386)
+/*
+ * *_block_host_order is expected to handle aligned data while
+ * *_block_data_order - unaligned. As algorithm and host (x86)
+ * are in this case of the same "endianess" these two are
+ * otherwise indistinguishable. But normally you don't want to
+ * call the same function because unaligned access in places
+ * where alignment is expected is usually a "Bad Thing". Indeed,
+ * on RISCs you get punished with BUS ERROR signal or *severe*
+ * performance degradation. Intel CPUs are in turn perfectly
+ * capable of loading unaligned data without such drastic side
+ * effect. Yes, they say it's slower than aligned load, but no
+ * exception is generated and therefore performance degradation
+ * is *incomparable* with RISCs. What we should weight here is
+ * costs of unaligned access against costs of aligning data.
+ * According to my measurements allowing unaligned access results
+ * in ~9% performance improvement on Pentium II operating at
+ * 266MHz. I won't be surprised if the difference will be higher
+ * on faster systems:-)
+ *
+ * <appro@fy.chalmers.se>
+ */
+#define md5_block_data_order md5_block_host_order
+#endif
+
+#define DATA_ORDER_IS_LITTLE_ENDIAN
+
+#define HASH_LONG MD5_LONG
+#define HASH_LONG_LOG2 MD5_LONG_LOG2
+#define HASH_CTX MD5_CTX
+#define HASH_CBLOCK MD5_CBLOCK
+#define HASH_LBLOCK MD5_LBLOCK
+#define HASH_UPDATE MD5_Update
+#define HASH_TRANSFORM MD5_Transform
+#define HASH_FINAL MD5_Final
+#define HASH_BLOCK_HOST_ORDER md5_block_host_order
+#if !defined(L_ENDIAN) || defined(md5_block_data_order)
+#define HASH_BLOCK_DATA_ORDER md5_block_data_order
+/*
+ * Little-endians (Intel and Alpha) feel better without this.
+ * It looks like memcpy does better job than generic
+ * md5_block_data_order on copying-n-aligning input data.
+ * But franlky speaking I didn't expect such result on Alpha.
+ * On the other hand I've got this with egcs-1.0.2 and if
+ * program is compiled with another (better?) compiler it
+ * might turn out other way around.
+ *
+ * <appro@fy.chalmers.se>
+ */
+#endif
+
+/* BEW */
+#define FLAT_INC
+
+#ifndef FLAT_INC
+#include "../md32_common.h"
+#else
+#include "md32_common.h"
+#endif
+
+/*
+#define F(x,y,z) (((x) & (y)) | ((~(x)) & (z)))
+#define G(x,y,z) (((x) & (z)) | ((y) & (~(z))))
+*/
+
+/* As pointed out by Wei Dai <weidai@eskimo.com>, the above can be
+ * simplified to the code below. Wei attributes these optimisations
+ * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
+ */
+#define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
+#define G(b,c,d) ((((b) ^ (c)) & (d)) ^ (c))
+#define H(b,c,d) ((b) ^ (c) ^ (d))
+#define I(b,c,d) (((~(d)) | (b)) ^ (c))
+
+#define R0(a,b,c,d,k,s,t) { \
+ a+=((k)+(t)+F((b),(c),(d))); \
+ a=ROTATE(a,s); \
+ a+=b; };\
+
+#define R1(a,b,c,d,k,s,t) { \
+ a+=((k)+(t)+G((b),(c),(d))); \
+ a=ROTATE(a,s); \
+ a+=b; };
+
+#define R2(a,b,c,d,k,s,t) { \
+ a+=((k)+(t)+H((b),(c),(d))); \
+ a=ROTATE(a,s); \
+ a+=b; };
+
+#define R3(a,b,c,d,k,s,t) { \
+ a+=((k)+(t)+I((b),(c),(d))); \
+ a=ROTATE(a,s); \
+ a+=b; };
diff --git a/lib/dns/sec/openssl/md_rand.c b/lib/dns/sec/openssl/md_rand.c
new file mode 100644
index 00000000..6bd1960e
--- /dev/null
+++ b/lib/dns/sec/openssl/md_rand.c
@@ -0,0 +1,429 @@
+/* crypto/rand/md_rand.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <time.h>
+#include <string.h>
+
+#include "openssl/e_os.h"
+
+#include <openssl/crypto.h>
+
+#if !defined(USE_MD5_RAND) && !defined(USE_SHA1_RAND) && !defined(USE_MDC2_RAND) && !defined(USE_MD2_RAND)
+#if !defined(NO_SHA) && !defined(NO_SHA1)
+#define USE_SHA1_RAND
+#elif !defined(NO_MD5)
+#define USE_MD5_RAND
+#elif !defined(NO_MDC2) && !defined(NO_DES)
+#define USE_MDC2_RAND
+#elif !defined(NO_MD2)
+#define USE_MD2_RAND
+#else
+#error No message digest algorithm available
+#endif
+#endif
+
+/* Changed how the state buffer used. I now attempt to 'wrap' such
+ * that I don't run over the same locations the next time go through
+ * the 1023 bytes - many thanks to
+ * Robert J. LeBlanc <rjl@renaissoft.com> for his comments
+ */
+
+#if defined(USE_MD5_RAND)
+#include <openssl/md5.h>
+#define MD_DIGEST_LENGTH MD5_DIGEST_LENGTH
+#define MD_CTX MD5_CTX
+#define MD_Init(a) MD5_Init(a)
+#define MD_Update(a,b,c) MD5_Update(a,b,c)
+#define MD_Final(a,b) MD5_Final(a,b)
+#define MD(a,b,c) MD5(a,b,c)
+#elif defined(USE_SHA1_RAND)
+#include <openssl/sha.h>
+#define MD_DIGEST_LENGTH SHA_DIGEST_LENGTH
+#define MD_CTX SHA_CTX
+#define MD_Init(a) SHA1_Init(a)
+#define MD_Update(a,b,c) SHA1_Update(a,b,c)
+#define MD_Final(a,b) SHA1_Final(a,b)
+#define MD(a,b,c) SHA1(a,b,c)
+#elif defined(USE_MDC2_RAND)
+#include <openssl/mdc2.h>
+#define MD_DIGEST_LENGTH MDC2_DIGEST_LENGTH
+#define MD_CTX MDC2_CTX
+#define MD_Init(a) MDC2_Init(a)
+#define MD_Update(a,b,c) MDC2_Update(a,b,c)
+#define MD_Final(a,b) MDC2_Final(a,b)
+#define MD(a,b,c) MDC2(a,b,c)
+#elif defined(USE_MD2_RAND)
+#include <openssl/md2.h>
+#define MD_DIGEST_LENGTH MD2_DIGEST_LENGTH
+#define MD_CTX MD2_CTX
+#define MD_Init(a) MD2_Init(a)
+#define MD_Update(a,b,c) MD2_Update(a,b,c)
+#define MD_Final(a,b) MD2_Final(a,b)
+#define MD(a,b,c) MD2(a,b,c)
+#endif
+
+#include <openssl/rand.h>
+
+/* #define NORAND 1 */
+/* #define PREDICT 1 */
+
+#define STATE_SIZE 1023
+static int state_num=0,state_index=0;
+static unsigned char state[STATE_SIZE+MD_DIGEST_LENGTH];
+static unsigned char md[MD_DIGEST_LENGTH];
+static long md_count[2]={0,0};
+
+const char *RAND_version="RAND" OPENSSL_VERSION_PTEXT;
+
+static void ssleay_rand_cleanup(void);
+static void ssleay_rand_seed(const void *buf, int num);
+static void ssleay_rand_bytes(unsigned char *buf, int num);
+
+RAND_METHOD rand_ssleay_meth={
+ ssleay_rand_seed,
+ ssleay_rand_bytes,
+ ssleay_rand_cleanup,
+ };
+
+RAND_METHOD *RAND_SSLeay(void)
+ {
+ return(&rand_ssleay_meth);
+ }
+
+static void ssleay_rand_cleanup(void)
+ {
+ memset(state,0,sizeof(state));
+ state_num=0;
+ state_index=0;
+ memset(md,0,MD_DIGEST_LENGTH);
+ md_count[0]=0;
+ md_count[1]=0;
+ }
+
+static void ssleay_rand_seed(const void *buf, int num)
+ {
+ int i,j,k,st_idx,st_num;
+ MD_CTX m;
+
+#ifdef NORAND
+ return;
+#endif
+
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+ st_idx=state_index;
+ st_num=state_num;
+
+ state_index=(state_index+num);
+ if (state_index >= STATE_SIZE)
+ {
+ state_index%=STATE_SIZE;
+ state_num=STATE_SIZE;
+ }
+ else if (state_num < STATE_SIZE)
+ {
+ if (state_index > state_num)
+ state_num=state_index;
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+
+ for (i=0; i<num; i+=MD_DIGEST_LENGTH)
+ {
+ j=(num-i);
+ j=(j > MD_DIGEST_LENGTH)?MD_DIGEST_LENGTH:j;
+
+ MD_Init(&m);
+ MD_Update(&m,md,MD_DIGEST_LENGTH);
+ k=(st_idx+j)-STATE_SIZE;
+ if (k > 0)
+ {
+ MD_Update(&m,&(state[st_idx]),j-k);
+ MD_Update(&m,&(state[0]),k);
+ }
+ else
+ MD_Update(&m,&(state[st_idx]),j);
+
+ MD_Update(&m,buf,j);
+ MD_Update(&m,(unsigned char *)&(md_count[0]),sizeof(md_count));
+ MD_Final(md,&m);
+ md_count[1]++;
+
+ buf=(const char *)buf + j;
+
+ for (k=0; k<j; k++)
+ {
+ state[st_idx++]^=md[k];
+ if (st_idx >= STATE_SIZE)
+ {
+ st_idx=0;
+ st_num=STATE_SIZE;
+ }
+ }
+ }
+ memset((char *)&m,0,sizeof(m));
+ }
+
+static void ssleay_rand_bytes(unsigned char *buf, int num)
+ {
+ int i,j,k,st_num,st_idx;
+ MD_CTX m;
+ static int init=1;
+ unsigned long l;
+#ifdef DEVRANDOM
+ FILE *fh;
+#endif
+
+#ifdef PREDICT
+ {
+ static unsigned char val=0;
+
+ for (i=0; i<num; i++)
+ buf[i]=val++;
+ return;
+ }
+#endif
+
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+
+ if (init)
+ {
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+ /* put in some default random data, we need more than
+ * just this */
+ RAND_seed(&m,sizeof(m));
+#ifndef MSDOS
+ l=getpid();
+ RAND_seed(&l,sizeof(l));
+ l=getuid();
+ RAND_seed(&l,sizeof(l));
+#endif
+ l=time(NULL);
+ RAND_seed(&l,sizeof(l));
+
+/* #ifdef DEVRANDOM */
+ /*
+ * Use a random entropy pool device.
+ * Linux 1.3.x and FreeBSD-Current has
+ * this. Use /dev/urandom if you can
+ * as /dev/random will block if it runs out
+ * of random entries.
+ */
+ if ((fh = fopen(DEVRANDOM, "r")) != NULL)
+ {
+ unsigned char tmpbuf[32];
+
+ fread((unsigned char *)tmpbuf,1,32,fh);
+ /* we don't care how many bytes we read,
+ * we will just copy the 'stack' if there is
+ * nothing else :-) */
+ fclose(fh);
+ RAND_seed(tmpbuf,32);
+ memset(tmpbuf,0,32);
+ }
+/* #endif */
+#ifdef PURIFY
+ memset(state,0,STATE_SIZE);
+ memset(md,0,MD_DIGEST_LENGTH);
+#endif
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+ init=0;
+ }
+
+ st_idx=state_index;
+ st_num=state_num;
+ state_index+=num;
+ if (state_index > state_num)
+ state_index=(state_index%state_num);
+
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+
+ while (num > 0)
+ {
+ j=(num >= MD_DIGEST_LENGTH/2)?MD_DIGEST_LENGTH/2:num;
+ num-=j;
+ MD_Init(&m);
+ MD_Update(&m,&(md[MD_DIGEST_LENGTH/2]),MD_DIGEST_LENGTH/2);
+ MD_Update(&m,(unsigned char *)&(md_count[0]),sizeof(md_count));
+#ifndef PURIFY
+ MD_Update(&m,buf,j); /* purify complains */
+#endif
+ k=(st_idx+j)-st_num;
+ if (k > 0)
+ {
+ MD_Update(&m,&(state[st_idx]),j-k);
+ MD_Update(&m,&(state[0]),k);
+ }
+ else
+ MD_Update(&m,&(state[st_idx]),j);
+ MD_Final(md,&m);
+
+ for (i=0; i<j; i++)
+ {
+ if (st_idx >= st_num)
+ st_idx=0;
+ state[st_idx++]^=md[i];
+ *(buf++)=md[i+MD_DIGEST_LENGTH/2];
+ }
+ }
+
+ MD_Init(&m);
+ MD_Update(&m,(unsigned char *)&(md_count[0]),sizeof(md_count));
+ md_count[0]++;
+ MD_Update(&m,md,MD_DIGEST_LENGTH);
+ MD_Final(md,&m);
+ memset(&m,0,sizeof(m));
+ }
+
+#ifdef WINDOWS
+#include <windows.h>
+#include <openssl/rand.h>
+
+/*****************************************************************************
+ * Initialisation function for the SSL random generator. Takes the contents
+ * of the screen as random seed.
+ *
+ * Created 960901 by Gertjan van Oosten, gertjan@West.NL, West Consulting B.V.
+ *
+ * Code adapted from
+ * <URL:http://www.microsoft.com/kb/developr/win_dk/q97193.htm>;
+ * the original copyright message is:
+ *
+ * (C) Copyright Microsoft Corp. 1993. All rights reserved.
+ *
+ * You have a royalty-free right to use, modify, reproduce and
+ * distribute the Sample Files (and/or any modified version) in
+ * any way you find useful, provided that you agree that
+ * Microsoft has no warranty obligations or liability for any
+ * Sample Application Files which are modified.
+ */
+/*
+ * I have modified the loading of bytes via RAND_seed() mechanism since
+ * the origional would have been very very CPU intensive since RAND_seed()
+ * does an MD5 per 16 bytes of input. The cost to digest 16 bytes is the same
+ * as that to digest 56 bytes. So under the old system, a screen of
+ * 1024*768*256 would have been CPU cost of approximatly 49,000 56 byte MD5
+ * digests or digesting 2.7 mbytes. What I have put in place would
+ * be 48 16k MD5 digests, or efectivly 48*16+48 MD5 bytes or 816 kbytes
+ * or about 3.5 times as much.
+ * - eric
+ */
+void RAND_screen(void)
+{
+ HDC hScrDC; /* screen DC */
+ HDC hMemDC; /* memory DC */
+ HBITMAP hBitmap; /* handle for our bitmap */
+ HBITMAP hOldBitmap; /* handle for previous bitmap */
+ BITMAP bm; /* bitmap properties */
+ unsigned int size; /* size of bitmap */
+ char *bmbits; /* contents of bitmap */
+ int w; /* screen width */
+ int h; /* screen height */
+ int y; /* y-coordinate of screen lines to grab */
+ int n = 16; /* number of screen lines to grab at a time */
+
+ /* Create a screen DC and a memory DC compatible to screen DC */
+ hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
+ hMemDC = CreateCompatibleDC(hScrDC);
+
+ /* Get screen resolution */
+ w = GetDeviceCaps(hScrDC, HORZRES);
+ h = GetDeviceCaps(hScrDC, VERTRES);
+
+ /* Create a bitmap compatible with the screen DC */
+ hBitmap = CreateCompatibleBitmap(hScrDC, w, n);
+
+ /* Select new bitmap into memory DC */
+ hOldBitmap = SelectObject(hMemDC, hBitmap);
+
+ /* Get bitmap properties */
+ GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
+ size = (unsigned int)bm.bmWidthBytes * bm.bmHeight * bm.bmPlanes;
+
+ bmbits = Malloc(size);
+ if (bmbits) {
+ /* Now go through the whole screen, repeatedly grabbing n lines */
+ for (y = 0; y < h-n; y += n)
+ {
+ unsigned char md[MD_DIGEST_LENGTH];
+
+ /* Bitblt screen DC to memory DC */
+ BitBlt(hMemDC, 0, 0, w, n, hScrDC, 0, y, SRCCOPY);
+
+ /* Copy bitmap bits from memory DC to bmbits */
+ GetBitmapBits(hBitmap, size, bmbits);
+
+ /* Get the MD5 of the bitmap */
+ MD(bmbits,size,md);
+
+ /* Seed the random generator with the MD5 digest */
+ RAND_seed(md, MD_DIGEST_LENGTH);
+ }
+
+ Free(bmbits);
+ }
+
+ /* Select old bitmap back into memory DC */
+ hBitmap = SelectObject(hMemDC, hOldBitmap);
+
+ /* Clean up */
+ DeleteObject(hBitmap);
+ DeleteDC(hMemDC);
+ DeleteDC(hScrDC);
+}
+#endif
diff --git a/lib/dns/sec/openssl/mem.c b/lib/dns/sec/openssl/mem.c
new file mode 100644
index 00000000..2848d1f2
--- /dev/null
+++ b/lib/dns/sec/openssl/mem.c
@@ -0,0 +1,382 @@
+/* crypto/mem.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openssl/buffer.h>
+#include <openssl/bio.h>
+#include <openssl/lhash.h>
+#include "cryptlib.h"
+
+#ifdef CRYPTO_MDEBUG
+static int mh_mode=CRYPTO_MEM_CHECK_ON;
+#else
+static int mh_mode=CRYPTO_MEM_CHECK_OFF;
+#endif
+static unsigned long order=0;
+
+static LHASH *mh=NULL;
+
+typedef struct mem_st
+ {
+ char *addr;
+ int num;
+ const char *file;
+ int line;
+ unsigned long order;
+ } MEM;
+
+int CRYPTO_mem_ctrl(int mode)
+ {
+ int ret=mh_mode;
+
+ CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
+ switch (mode)
+ {
+ case CRYPTO_MEM_CHECK_ON:
+ mh_mode|=CRYPTO_MEM_CHECK_ON;
+ break;
+ case CRYPTO_MEM_CHECK_OFF:
+ mh_mode&= ~CRYPTO_MEM_CHECK_ON;
+ break;
+ case CRYPTO_MEM_CHECK_DISABLE:
+ mh_mode&= ~CRYPTO_MEM_CHECK_ENABLE;
+ break;
+ case CRYPTO_MEM_CHECK_ENABLE:
+ if (mh_mode&CRYPTO_MEM_CHECK_ON)
+ mh_mode|=CRYPTO_MEM_CHECK_ENABLE;
+ break;
+ default:
+ break;
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
+ return(ret);
+ }
+
+static int mem_cmp(MEM *a, MEM *b)
+ {
+ return(a->addr - b->addr);
+ }
+
+static unsigned long mem_hash(MEM *a)
+ {
+ unsigned long ret;
+
+ ret=(unsigned long)a->addr;
+
+ ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
+ return(ret);
+ }
+
+static void *(*malloc_locked_func)(int)=(void *(*)(int))malloc;
+static void (*free_locked_func)(void *)=(void (*)(void *))free;
+static void *(*malloc_func)(int)= (void *(*)(int))malloc;
+static void *(*realloc_func)(void *, int)= (void *(*)(void *, int))realloc;
+static void (*free_func)(void *)= (void (*)(void *))free;
+
+void CRYPTO_set_mem_functions(void *(*m)(int), void *(*r)(void *, int),
+ void (*f)(void *))
+ {
+ if ((m == NULL) || (r == NULL) || (f == NULL)) return;
+ malloc_func=m;
+ realloc_func=r;
+ free_func=f;
+ malloc_locked_func=m;
+ free_locked_func=f;
+ }
+
+void CRYPTO_set_locked_mem_functions(void *(*m)(int), void (*f)(void *))
+ {
+ if ((m == NULL) || (f == NULL)) return;
+ malloc_locked_func=m;
+ free_locked_func=f;
+ }
+
+void CRYPTO_get_mem_functions(void *(**m)(int), void *(**r)(void *, int),
+ void (**f)(void *))
+ {
+ if (m != NULL) *m=malloc_func;
+ if (r != NULL) *r=realloc_func;
+ if (f != NULL) *f=free_func;
+ }
+
+void CRYPTO_get_locked_mem_functions(void *(**m)(), void (**f)())
+ {
+ if (m != NULL) *m=malloc_locked_func;
+ if (f != NULL) *f=free_locked_func;
+ }
+
+void *CRYPTO_malloc_locked(int num)
+ {
+ return(malloc_locked_func(num));
+ }
+
+void CRYPTO_free_locked(void *str)
+ {
+ free_locked_func(str);
+ }
+
+void *CRYPTO_malloc(int num)
+ {
+ return(malloc_func(num));
+ }
+
+void *CRYPTO_realloc(void *str, int num)
+ {
+ return(realloc_func(str,num));
+ }
+
+void CRYPTO_free(void *str)
+ {
+ free_func(str);
+ }
+
+static unsigned long break_order_num=0;
+void *CRYPTO_dbg_malloc(int num, const char *file, int line)
+ {
+ char *ret;
+ MEM *m,*mm;
+
+ if ((ret=malloc_func(num)) == NULL)
+ return(NULL);
+
+ if (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
+ {
+ MemCheck_off();
+ if ((m=(MEM *)Malloc(sizeof(MEM))) == NULL)
+ {
+ Free(ret);
+ MemCheck_on();
+ return(NULL);
+ }
+ CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
+ if (mh == NULL)
+ {
+ if ((mh=lh_new(mem_hash,mem_cmp)) == NULL)
+ {
+ Free(ret);
+ Free(m);
+ ret=NULL;
+ goto err;
+ }
+ }
+
+ m->addr=ret;
+ m->file=file;
+ m->line=line;
+ m->num=num;
+ if (order == break_order_num)
+ {
+ /* BREAK HERE */
+ m->order=order;
+ }
+ m->order=order++;
+ if ((mm=(MEM *)lh_insert(mh,(char *)m)) != NULL)
+ {
+ /* Not good, but don't sweat it */
+ Free(mm);
+ }
+err:
+ CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
+ MemCheck_on();
+ }
+ return(ret);
+ }
+
+void CRYPTO_dbg_free(void *addr)
+ {
+ MEM m,*mp;
+
+ if ((mh_mode & CRYPTO_MEM_CHECK_ENABLE) && (mh != NULL))
+ {
+ MemCheck_off();
+ CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
+ m.addr=addr;
+ mp=(MEM *)lh_delete(mh,(char *)&m);
+ if (mp != NULL)
+ Free(mp);
+ CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
+ MemCheck_on();
+ }
+ free_func(addr);
+ }
+
+void *CRYPTO_dbg_realloc(void *addr, int num, const char *file, int line)
+ {
+ char *ret;
+ MEM m,*mp;
+
+ file = file; /* BEW - quiet the compiler */
+ line = line;
+
+ ret=realloc_func(addr,num);
+ if (ret == (char *)addr) return(ret);
+
+ if (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
+ {
+ MemCheck_off();
+ if (ret == NULL) return(NULL);
+ m.addr=addr;
+ CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
+ mp=(MEM *)lh_delete(mh,(char *)&m);
+ if (mp != NULL)
+ {
+ mp->addr=ret;
+ lh_insert(mh,(char *)mp);
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
+ MemCheck_on();
+ }
+ return(ret);
+ }
+
+void *CRYPTO_remalloc(void *a, int n)
+ {
+ if (a != NULL) Free(a);
+ a=(char *)Malloc(n);
+ return(a);
+ }
+
+void *CRYPTO_dbg_remalloc(void *a, int n, const char *file, int line)
+ {
+ if (a != NULL) CRYPTO_dbg_free(a);
+ a=(char *)CRYPTO_dbg_malloc(n,file,line);
+ return(a);
+ }
+
+/* BEW */
+#if 0
+typedef struct mem_leak_st
+ {
+ BIO *bio;
+ int chunks;
+ long bytes;
+ } MEM_LEAK;
+
+static void print_leak(MEM *m, MEM_LEAK *l)
+ {
+ char buf[128];
+
+ if(m->addr == (char *)l->bio)
+ return;
+ sprintf(buf,"%5lu file=%s, line=%d, number=%d, address=%08lX\n",
+ m->order,m->file,m->line,m->num,(unsigned long)m->addr);
+ BIO_puts(l->bio,buf);
+ l->chunks++;
+ l->bytes+=m->num;
+ }
+
+void CRYPTO_mem_leaks(BIO *b)
+ {
+ MEM_LEAK ml;
+ char buf[80];
+
+ if (mh == NULL) return;
+ ml.bio=b;
+ ml.bytes=0;
+ ml.chunks=0;
+ CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
+ lh_doall_arg(mh,(void (*)())print_leak,(char *)&ml);
+ CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
+ if (ml.chunks != 0)
+ {
+ sprintf(buf,"%ld bytes leaked in %d chunks\n",
+ ml.bytes,ml.chunks);
+ BIO_puts(b,buf);
+ }
+
+#if 0
+ lh_stats_bio(mh,b);
+ lh_node_stats_bio(mh,b);
+ lh_node_usage_stats_bio(mh,b);
+#endif
+ }
+
+static void (*mem_cb)()=NULL;
+
+static void cb_leak(MEM *m, char *cb)
+ {
+ void (*mem_callback)()=(void (*)())cb;
+ mem_callback(m->order,m->file,m->line,m->num,m->addr);
+ }
+
+void CRYPTO_mem_leaks_cb(void (*cb)())
+ {
+ if (mh == NULL) return;
+ CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
+ mem_cb=cb;
+ lh_doall_arg(mh,(void (*)())cb_leak,(char *)mem_cb);
+ mem_cb=NULL;
+ CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
+ }
+
+#ifndef NO_FP_API
+void CRYPTO_mem_leaks_fp(FILE *fp)
+ {
+ BIO *b;
+
+ if (mh == NULL) return;
+ if ((b=BIO_new(BIO_s_file())) == NULL)
+ return;
+ BIO_set_fp(b,fp,BIO_NOCLOSE);
+ CRYPTO_mem_leaks(b);
+ BIO_free(b);
+ }
+#endif
+#endif
+
diff --git a/lib/dns/sec/openssl/rand_lib.c b/lib/dns/sec/openssl/rand_lib.c
new file mode 100644
index 00000000..34c6d5b9
--- /dev/null
+++ b/lib/dns/sec/openssl/rand_lib.c
@@ -0,0 +1,98 @@
+/* crypto/rand/rand_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <time.h>
+#include <openssl/rand.h>
+
+#ifdef NO_RAND
+static RAND_METHOD *rand_meth=NULL;
+#else
+extern RAND_METHOD rand_ssleay_meth;
+static RAND_METHOD *rand_meth= &rand_ssleay_meth;
+#endif
+
+void RAND_set_rand_method(RAND_METHOD *meth)
+ {
+ rand_meth=meth;
+ }
+
+RAND_METHOD *RAND_get_rand_method(void)
+ {
+ return(rand_meth);
+ }
+
+void RAND_cleanup(void)
+ {
+ if (rand_meth != NULL)
+ rand_meth->cleanup();
+ }
+
+void RAND_seed(const void *buf, int num)
+ {
+ if (rand_meth != NULL)
+ rand_meth->seed(buf,num);
+ }
+
+void RAND_bytes(unsigned char *buf, int num)
+ {
+ if (rand_meth != NULL)
+ rand_meth->bytes(buf,num);
+ }
+
diff --git a/lib/dns/sec/openssl/sha1_one.c b/lib/dns/sec/openssl/sha1_one.c
new file mode 100644
index 00000000..861752ea
--- /dev/null
+++ b/lib/dns/sec/openssl/sha1_one.c
@@ -0,0 +1,76 @@
+/* crypto/sha/sha1_one.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/sha.h>
+
+#ifndef NO_SHA1
+unsigned char *SHA1(const unsigned char *d, unsigned long n, unsigned char *md)
+ {
+ SHA_CTX c;
+ static unsigned char m[SHA_DIGEST_LENGTH];
+
+ if (md == NULL) md=m;
+ SHA1_Init(&c);
+ SHA1_Update(&c,d,n);
+ SHA1_Final(md,&c);
+ memset(&c,0,sizeof(c));
+ return(md);
+ }
+#endif
diff --git a/lib/dns/sec/openssl/sha1dgst.c b/lib/dns/sec/openssl/sha1dgst.c
new file mode 100644
index 00000000..66e885dd
--- /dev/null
+++ b/lib/dns/sec/openssl/sha1dgst.c
@@ -0,0 +1,498 @@
+/* crypto/sha/sha1dgst.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#undef SHA_0
+#define SHA_1
+#include <openssl/sha.h>
+#include "sha_locl.h"
+#include <openssl/opensslv.h>
+
+#ifndef NO_SHA1
+char *SHA1_version="SHA1" OPENSSL_VERSION_PTEXT;
+
+/* Implemented from SHA-1 document - The Secure Hash Algorithm
+ */
+
+#define INIT_DATA_h0 0x67452301UL
+#define INIT_DATA_h1 0xefcdab89UL
+#define INIT_DATA_h2 0x98badcfeUL
+#define INIT_DATA_h3 0x10325476UL
+#define INIT_DATA_h4 0xc3d2e1f0UL
+
+#define K_00_19 0x5a827999UL
+#define K_20_39 0x6ed9eba1UL
+#define K_40_59 0x8f1bbcdcUL
+#define K_60_79 0xca62c1d6UL
+
+#ifdef SHA1_ASM
+ void sha1_block_x86(SHA_CTX *c, register SHA_LONG *p, int num);
+# define sha1_block(c,p,n) sha1_block_x86((c),(p),(n)*SHA_CBLOCK)
+#else
+ static void sha1_block(SHA_CTX *c, register SHA_LONG *p, int num);
+#endif
+
+#if !defined(B_ENDIAN) && defined(SHA1_ASM)
+# define M_c2nl c2l
+# define M_p_c2nl p_c2l
+# define M_c2nl_p c2l_p
+# define M_p_c2nl_p p_c2l_p
+# define M_nl2c l2c
+#else
+# define M_c2nl c2nl
+# define M_p_c2nl p_c2nl
+# define M_c2nl_p c2nl_p
+# define M_p_c2nl_p p_c2nl_p
+# define M_nl2c nl2c
+#endif
+
+void SHA1_Init(SHA_CTX *c)
+ {
+ c->h0=INIT_DATA_h0;
+ c->h1=INIT_DATA_h1;
+ c->h2=INIT_DATA_h2;
+ c->h3=INIT_DATA_h3;
+ c->h4=INIT_DATA_h4;
+ c->Nl=0;
+ c->Nh=0;
+ c->num=0;
+ }
+
+void SHA1_Update(SHA_CTX *c, register const unsigned char *data,
+ unsigned long len)
+ {
+ register SHA_LONG *p;
+ int ew,ec,sw,sc;
+ SHA_LONG l;
+
+ if (len == 0) return;
+
+ l=(c->Nl+(len<<3))&0xffffffffL;
+ if (l < c->Nl) /* overflow */
+ c->Nh++;
+ c->Nh+=(len>>29);
+ c->Nl=l;
+
+ if (c->num != 0)
+ {
+ p=c->data;
+ sw=c->num>>2;
+ sc=c->num&0x03;
+
+ if ((c->num+len) >= SHA_CBLOCK)
+ {
+ l= p[sw];
+ M_p_c2nl(data,l,sc);
+ p[sw++]=l;
+ for (; sw<SHA_LBLOCK; sw++)
+ {
+ M_c2nl(data,l);
+ p[sw]=l;
+ }
+ len-=(SHA_CBLOCK-c->num);
+
+ sha1_block(c,p,1);
+ c->num=0;
+ /* drop through and do the rest */
+ }
+ else
+ {
+ c->num+=(int)len;
+ if ((sc+len) < 4) /* ugly, add char's to a word */
+ {
+ l= p[sw];
+ M_p_c2nl_p(data,l,sc,len);
+ p[sw]=l;
+ }
+ else
+ {
+ ew=(c->num>>2);
+ ec=(c->num&0x03);
+ l= p[sw];
+ M_p_c2nl(data,l,sc);
+ p[sw++]=l;
+ for (; sw < ew; sw++)
+ { M_c2nl(data,l); p[sw]=l; }
+ if (ec)
+ {
+ M_c2nl_p(data,l,ec);
+ p[sw]=l;
+ }
+ }
+ return;
+ }
+ }
+ /* We can only do the following code for assember, the reason
+ * being that the sha1_block 'C' version changes the values
+ * in the 'data' array. The assember code avoids this and
+ * copies it to a local array. I should be able to do this for
+ * the C version as well....
+ */
+#if SHA_LONG_LOG2==2
+#if defined(B_ENDIAN) || defined(SHA1_ASM)
+ if ((((unsigned long)data)%sizeof(SHA_LONG)) == 0)
+ {
+ sw=len/SHA_CBLOCK;
+ if (sw)
+ {
+ sha1_block(c,(SHA_LONG *)data,sw);
+ sw*=SHA_CBLOCK;
+ data+=sw;
+ len-=sw;
+ }
+ }
+#endif
+#endif
+ /* we now can process the input data in blocks of SHA_CBLOCK
+ * chars and save the leftovers to c->data. */
+ p=c->data;
+ while (len >= SHA_CBLOCK)
+ {
+#if SHA_LONG_LOG2==2
+#if defined(B_ENDIAN) || defined(SHA1_ASM)
+#define SHA_NO_TAIL_CODE
+ /*
+ * Basically we get here only when data happens
+ * to be unaligned.
+ */
+ if (p != (SHA_LONG *)data)
+ memcpy(p,data,SHA_CBLOCK);
+ data+=SHA_CBLOCK;
+ sha1_block(c,p=c->data,1);
+ len-=SHA_CBLOCK;
+#elif defined(L_ENDIAN)
+#define BE_COPY(dst,src,i) { \
+ l = ((SHA_LONG *)src)[i]; \
+ Endian_Reverse32(l); \
+ dst[i] = l; \
+ }
+ if ((((unsigned long)data)%sizeof(SHA_LONG)) == 0)
+ {
+ for (sw=(SHA_LBLOCK/4); sw; sw--)
+ {
+ BE_COPY(p,data,0);
+ BE_COPY(p,data,1);
+ BE_COPY(p,data,2);
+ BE_COPY(p,data,3);
+ p+=4;
+ data += 4*sizeof(SHA_LONG);
+ }
+ sha1_block(c,p=c->data,1);
+ len-=SHA_CBLOCK;
+ continue;
+ }
+#endif
+#endif
+#ifndef SHA_NO_TAIL_CODE
+ /*
+ * In addition to "sizeof(SHA_LONG)!= 4" case the
+ * following code covers unaligned access cases on
+ * little-endian machines.
+ * <appro@fy.chalmers.se>
+ */
+ p=c->data;
+ for (sw=(SHA_LBLOCK/4); sw; sw--)
+ {
+ M_c2nl(data,l); p[0]=l;
+ M_c2nl(data,l); p[1]=l;
+ M_c2nl(data,l); p[2]=l;
+ M_c2nl(data,l); p[3]=l;
+ p+=4;
+ }
+ p=c->data;
+ sha1_block(c,p,1);
+ len-=SHA_CBLOCK;
+#endif
+ }
+ ec=(int)len;
+ c->num=ec;
+ ew=(ec>>2);
+ ec&=0x03;
+
+ for (sw=0; sw < ew; sw++)
+ { M_c2nl(data,l); p[sw]=l; }
+ M_c2nl_p(data,l,ec);
+ p[sw]=l;
+ }
+
+void SHA1_Transform(SHA_CTX *c, unsigned char *b)
+ {
+ SHA_LONG p[SHA_LBLOCK];
+
+#if SHA_LONG_LOG2==2
+#if defined(B_ENDIAN) || defined(SHA1_ASM)
+ memcpy(p,b,SHA_CBLOCK);
+ sha1_block(c,p,1);
+ return;
+#elif defined(L_ENDIAN)
+ if (((unsigned long)b%sizeof(SHA_LONG)) == 0)
+ {
+ SHA_LONG *q;
+ int i;
+
+ q=p;
+ for (i=(SHA_LBLOCK/4); i; i--)
+ {
+ unsigned long l;
+ BE_COPY(q,b,0); /* BE_COPY was defined above */
+ BE_COPY(q,b,1);
+ BE_COPY(q,b,2);
+ BE_COPY(q,b,3);
+ q+=4;
+ b+=4*sizeof(SHA_LONG);
+ }
+ sha1_block(c,p,1);
+ return;
+ }
+#endif
+#endif
+#ifndef SHA_NO_TAIL_CODE /* defined above, see comment */
+ {
+ SHA_LONG *q;
+ int i;
+
+ q=p;
+ for (i=(SHA_LBLOCK/4); i; i--)
+ {
+ SHA_LONG l;
+ c2nl(b,l); *(q++)=l;
+ c2nl(b,l); *(q++)=l;
+ c2nl(b,l); *(q++)=l;
+ c2nl(b,l); *(q++)=l;
+ }
+ sha1_block(c,p,1);
+ }
+#endif
+ }
+
+#ifndef SHA1_ASM
+static void sha1_block(SHA_CTX *c, register SHA_LONG *W, int num)
+ {
+ register SHA_LONG A,B,C,D,E,T;
+ SHA_LONG X[SHA_LBLOCK];
+
+ A=c->h0;
+ B=c->h1;
+ C=c->h2;
+ D=c->h3;
+ E=c->h4;
+
+ for (;;)
+ {
+ BODY_00_15( 0,A,B,C,D,E,T,W);
+ BODY_00_15( 1,T,A,B,C,D,E,W);
+ BODY_00_15( 2,E,T,A,B,C,D,W);
+ BODY_00_15( 3,D,E,T,A,B,C,W);
+ BODY_00_15( 4,C,D,E,T,A,B,W);
+ BODY_00_15( 5,B,C,D,E,T,A,W);
+ BODY_00_15( 6,A,B,C,D,E,T,W);
+ BODY_00_15( 7,T,A,B,C,D,E,W);
+ BODY_00_15( 8,E,T,A,B,C,D,W);
+ BODY_00_15( 9,D,E,T,A,B,C,W);
+ BODY_00_15(10,C,D,E,T,A,B,W);
+ BODY_00_15(11,B,C,D,E,T,A,W);
+ BODY_00_15(12,A,B,C,D,E,T,W);
+ BODY_00_15(13,T,A,B,C,D,E,W);
+ BODY_00_15(14,E,T,A,B,C,D,W);
+ BODY_00_15(15,D,E,T,A,B,C,W);
+ BODY_16_19(16,C,D,E,T,A,B,W,W,W,W);
+ BODY_16_19(17,B,C,D,E,T,A,W,W,W,W);
+ BODY_16_19(18,A,B,C,D,E,T,W,W,W,W);
+ BODY_16_19(19,T,A,B,C,D,E,W,W,W,X);
+
+ BODY_20_31(20,E,T,A,B,C,D,W,W,W,X);
+ BODY_20_31(21,D,E,T,A,B,C,W,W,W,X);
+ BODY_20_31(22,C,D,E,T,A,B,W,W,W,X);
+ BODY_20_31(23,B,C,D,E,T,A,W,W,W,X);
+ BODY_20_31(24,A,B,C,D,E,T,W,W,X,X);
+ BODY_20_31(25,T,A,B,C,D,E,W,W,X,X);
+ BODY_20_31(26,E,T,A,B,C,D,W,W,X,X);
+ BODY_20_31(27,D,E,T,A,B,C,W,W,X,X);
+ BODY_20_31(28,C,D,E,T,A,B,W,W,X,X);
+ BODY_20_31(29,B,C,D,E,T,A,W,W,X,X);
+ BODY_20_31(30,A,B,C,D,E,T,W,X,X,X);
+ BODY_20_31(31,T,A,B,C,D,E,W,X,X,X);
+ BODY_32_39(32,E,T,A,B,C,D,X);
+ BODY_32_39(33,D,E,T,A,B,C,X);
+ BODY_32_39(34,C,D,E,T,A,B,X);
+ BODY_32_39(35,B,C,D,E,T,A,X);
+ BODY_32_39(36,A,B,C,D,E,T,X);
+ BODY_32_39(37,T,A,B,C,D,E,X);
+ BODY_32_39(38,E,T,A,B,C,D,X);
+ BODY_32_39(39,D,E,T,A,B,C,X);
+
+ BODY_40_59(40,C,D,E,T,A,B,X);
+ BODY_40_59(41,B,C,D,E,T,A,X);
+ BODY_40_59(42,A,B,C,D,E,T,X);
+ BODY_40_59(43,T,A,B,C,D,E,X);
+ BODY_40_59(44,E,T,A,B,C,D,X);
+ BODY_40_59(45,D,E,T,A,B,C,X);
+ BODY_40_59(46,C,D,E,T,A,B,X);
+ BODY_40_59(47,B,C,D,E,T,A,X);
+ BODY_40_59(48,A,B,C,D,E,T,X);
+ BODY_40_59(49,T,A,B,C,D,E,X);
+ BODY_40_59(50,E,T,A,B,C,D,X);
+ BODY_40_59(51,D,E,T,A,B,C,X);
+ BODY_40_59(52,C,D,E,T,A,B,X);
+ BODY_40_59(53,B,C,D,E,T,A,X);
+ BODY_40_59(54,A,B,C,D,E,T,X);
+ BODY_40_59(55,T,A,B,C,D,E,X);
+ BODY_40_59(56,E,T,A,B,C,D,X);
+ BODY_40_59(57,D,E,T,A,B,C,X);
+ BODY_40_59(58,C,D,E,T,A,B,X);
+ BODY_40_59(59,B,C,D,E,T,A,X);
+
+ BODY_60_79(60,A,B,C,D,E,T,X);
+ BODY_60_79(61,T,A,B,C,D,E,X);
+ BODY_60_79(62,E,T,A,B,C,D,X);
+ BODY_60_79(63,D,E,T,A,B,C,X);
+ BODY_60_79(64,C,D,E,T,A,B,X);
+ BODY_60_79(65,B,C,D,E,T,A,X);
+ BODY_60_79(66,A,B,C,D,E,T,X);
+ BODY_60_79(67,T,A,B,C,D,E,X);
+ BODY_60_79(68,E,T,A,B,C,D,X);
+ BODY_60_79(69,D,E,T,A,B,C,X);
+ BODY_60_79(70,C,D,E,T,A,B,X);
+ BODY_60_79(71,B,C,D,E,T,A,X);
+ BODY_60_79(72,A,B,C,D,E,T,X);
+ BODY_60_79(73,T,A,B,C,D,E,X);
+ BODY_60_79(74,E,T,A,B,C,D,X);
+ BODY_60_79(75,D,E,T,A,B,C,X);
+ BODY_60_79(76,C,D,E,T,A,B,X);
+ BODY_60_79(77,B,C,D,E,T,A,X);
+ BODY_60_79(78,A,B,C,D,E,T,X);
+ BODY_60_79(79,T,A,B,C,D,E,X);
+
+ c->h0=(c->h0+E)&0xffffffffL;
+ c->h1=(c->h1+T)&0xffffffffL;
+ c->h2=(c->h2+A)&0xffffffffL;
+ c->h3=(c->h3+B)&0xffffffffL;
+ c->h4=(c->h4+C)&0xffffffffL;
+
+ if (--num <= 0) break;
+
+ A=c->h0;
+ B=c->h1;
+ C=c->h2;
+ D=c->h3;
+ E=c->h4;
+
+ W+=SHA_LBLOCK; /* Note! This can happen only when sizeof(SHA_LONG)
+ * is 4. Whenever it's not the actual case this
+ * function is never called with num larger than 1
+ * and we never advance down here.
+ * <appro@fy.chalmers.se>
+ */
+ }
+ }
+#endif
+
+void SHA1_Final(unsigned char *md, SHA_CTX *c)
+ {
+ register int i,j;
+ register SHA_LONG l;
+ register SHA_LONG *p;
+ static unsigned char end[4]={0x80,0x00,0x00,0x00};
+ unsigned char *cp=end;
+
+ /* c->num should definitly have room for at least one more byte. */
+ p=c->data;
+ j=c->num;
+ i=j>>2;
+#ifdef PURIFY
+ if ((j&0x03) == 0) p[i]=0;
+#endif
+ l=p[i];
+ M_p_c2nl(cp,l,j&0x03);
+ p[i]=l;
+ i++;
+ /* i is the next 'undefined word' */
+ if (c->num >= SHA_LAST_BLOCK)
+ {
+ for (; i<SHA_LBLOCK; i++)
+ p[i]=0;
+ sha1_block(c,p,1);
+ i=0;
+ }
+ for (; i<(SHA_LBLOCK-2); i++)
+ p[i]=0;
+ p[SHA_LBLOCK-2]=c->Nh;
+ p[SHA_LBLOCK-1]=c->Nl;
+#if SHA_LONG_LOG2==2
+#if !defined(B_ENDIAN) && defined(SHA1_ASM)
+ Endian_Reverse32(p[SHA_LBLOCK-2]);
+ Endian_Reverse32(p[SHA_LBLOCK-1]);
+#endif
+#endif
+ sha1_block(c,p,1);
+ cp=md;
+ l=c->h0; nl2c(l,cp);
+ l=c->h1; nl2c(l,cp);
+ l=c->h2; nl2c(l,cp);
+ l=c->h3; nl2c(l,cp);
+ l=c->h4; nl2c(l,cp);
+
+ c->num=0;
+ /* sha_block may be leaving some stuff on the stack
+ * but I'm not worried :-)
+ memset((void *)c,0,sizeof(SHA_CTX));
+ */
+ }
+#endif
+
diff --git a/lib/dns/sec/openssl/sha_locl.h b/lib/dns/sec/openssl/sha_locl.h
new file mode 100644
index 00000000..ac85029a
--- /dev/null
+++ b/lib/dns/sec/openssl/sha_locl.h
@@ -0,0 +1,288 @@
+/* crypto/sha/sha_locl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/opensslconf.h>
+
+#ifdef undef
+/* one or the other needs to be defined */
+#ifndef SHA_1 /* FIPE 180-1 */
+#define SHA_0 /* FIPS 180 */
+#endif
+#endif
+
+#undef c2nl
+#define c2nl(c,l) (l =(((unsigned long)(*((c)++)))<<24), \
+ l|=(((unsigned long)(*((c)++)))<<16), \
+ l|=(((unsigned long)(*((c)++)))<< 8), \
+ l|=(((unsigned long)(*((c)++))) ))
+
+#undef p_c2nl
+#define p_c2nl(c,l,n) { \
+ switch (n) { \
+ case 0: l =((unsigned long)(*((c)++)))<<24; \
+ case 1: l|=((unsigned long)(*((c)++)))<<16; \
+ case 2: l|=((unsigned long)(*((c)++)))<< 8; \
+ case 3: l|=((unsigned long)(*((c)++))); \
+ } \
+ }
+
+#undef c2nl_p
+/* NOTE the pointer is not incremented at the end of this */
+#define c2nl_p(c,l,n) { \
+ l=0; \
+ (c)+=n; \
+ switch (n) { \
+ case 3: l =((unsigned long)(*(--(c))))<< 8; \
+ case 2: l|=((unsigned long)(*(--(c))))<<16; \
+ case 1: l|=((unsigned long)(*(--(c))))<<24; \
+ } \
+ }
+
+#undef p_c2nl_p
+#define p_c2nl_p(c,l,sc,len) { \
+ switch (sc) \
+ { \
+ case 0: l =((unsigned long)(*((c)++)))<<24; \
+ if (--len == 0) break; \
+ case 1: l|=((unsigned long)(*((c)++)))<<16; \
+ if (--len == 0) break; \
+ case 2: l|=((unsigned long)(*((c)++)))<< 8; \
+ } \
+ }
+
+#undef nl2c
+#define nl2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l) )&0xff))
+
+#undef c2l
+#define c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \
+ l|=(((unsigned long)(*((c)++)))<< 8), \
+ l|=(((unsigned long)(*((c)++)))<<16), \
+ l|=(((unsigned long)(*((c)++)))<<24))
+
+#undef p_c2l
+#define p_c2l(c,l,n) { \
+ switch (n) { \
+ case 0: l =((unsigned long)(*((c)++))); \
+ case 1: l|=((unsigned long)(*((c)++)))<< 8; \
+ case 2: l|=((unsigned long)(*((c)++)))<<16; \
+ case 3: l|=((unsigned long)(*((c)++)))<<24; \
+ } \
+ }
+
+#undef c2l_p
+/* NOTE the pointer is not incremented at the end of this */
+#define c2l_p(c,l,n) { \
+ l=0; \
+ (c)+=n; \
+ switch (n) { \
+ case 3: l =((unsigned long)(*(--(c))))<<16; \
+ case 2: l|=((unsigned long)(*(--(c))))<< 8; \
+ case 1: l|=((unsigned long)(*(--(c)))); \
+ } \
+ }
+
+#undef p_c2l_p
+#define p_c2l_p(c,l,sc,len) { \
+ switch (sc) \
+ { \
+ case 0: l =((unsigned long)(*((c)++))); \
+ if (--len == 0) break; \
+ case 1: l|=((unsigned long)(*((c)++)))<< 8; \
+ if (--len == 0) break; \
+ case 2: l|=((unsigned long)(*((c)++)))<<16; \
+ } \
+ }
+
+#undef l2c
+#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>24)&0xff))
+
+#ifndef SHA_LONG_LOG2
+#define SHA_LONG_LOG2 2 /* default to 32 bits */
+#endif
+
+#undef ROTATE
+#undef Endian_Reverse32
+#if defined(WIN32)
+#define ROTATE(a,n) _lrotl(a,n)
+#elif defined(__GNUC__) && !defined(PEDANTIC)
+/* some inline assembler templates by <appro@fy.chalmers.se> */
+#if defined(__i386)
+#define ROTATE(a,n) ({ register unsigned int ret; \
+ asm ("roll %1,%0" \
+ : "=r"(ret) \
+ : "I"(n), "0"(a) \
+ : "cc"); \
+ ret; \
+ })
+#ifndef I386_ONLY
+#define Endian_Reverse32(a) \
+ { register unsigned int ltmp=(a); \
+ asm ("bswapl %0" \
+ : "=r"(ltmp) : "0"(ltmp)); \
+ (a)=ltmp; \
+ }
+#endif
+#elif defined(__powerpc)
+#define ROTATE(a,n) ({ register unsigned int ret; \
+ asm ("rlwinm %0,%1,%2,0,31" \
+ : "=r"(ret) \
+ : "r"(a), "I"(n)); \
+ ret; \
+ })
+/* Endian_Reverse32 is not needed for PowerPC */
+#endif
+#endif
+
+/* A nice byte order reversal from Wei Dai <weidai@eskimo.com> */
+#ifdef ROTATE
+#ifndef Endian_Reverse32
+/* 5 instructions with rotate instruction, else 9 */
+#define Endian_Reverse32(a) \
+ { \
+ unsigned long t=(a); \
+ (a)=((ROTATE(t,8)&0x00FF00FF)|(ROTATE((t&0x00FF00FF),24))); \
+ }
+#endif
+#else
+#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
+#ifndef Endian_Reverse32
+/* 6 instructions with rotate instruction, else 8 */
+#define Endian_Reverse32(a) \
+ { \
+ unsigned long t=(a); \
+ t=(((t>>8)&0x00FF00FF)|((t&0x00FF00FF)<<8)); \
+ (a)=ROTATE(t,16); \
+ }
+#endif
+/*
+ * Originally the middle line started with l=(((l&0xFF00FF00)>>8)|...
+ * It's rewritten as above for two reasons:
+ * - RISCs aren't good at long constants and have to explicitely
+ * compose 'em with several (well, usually 2) instructions in a
+ * register before performing the actual operation and (as you
+ * already realized:-) having same constant should inspire the
+ * compiler to permanently allocate the only register for it;
+ * - most modern CPUs have two ALUs, but usually only one has
+ * circuitry for shifts:-( this minor tweak inspires compiler
+ * to schedule shift instructions in a better way...
+ *
+ * <appro@fy.chalmers.se>
+ */
+#endif
+
+/* As pointed out by Wei Dai <weidai@eskimo.com>, F() below can be
+ * simplified to the code in F_00_19. Wei attributes these optimisations
+ * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
+ * #define F(x,y,z) (((x) & (y)) | ((~(x)) & (z)))
+ * I've just become aware of another tweak to be made, again from Wei Dai,
+ * in F_40_59, (x&a)|(y&a) -> (x|y)&a
+ */
+#define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
+#define F_20_39(b,c,d) ((b) ^ (c) ^ (d))
+#define F_40_59(b,c,d) (((b) & (c)) | (((b)|(c)) & (d)))
+#define F_60_79(b,c,d) F_20_39(b,c,d)
+
+#undef Xupdate
+#ifdef SHA_0
+#define Xupdate(a,i,ia,ib,ic,id) X[(i)&0x0f]=(a)=\
+ (ia[(i)&0x0f]^ib[((i)+2)&0x0f]^ic[((i)+8)&0x0f]^id[((i)+13)&0x0f]);
+#endif
+#ifdef SHA_1
+#define Xupdate(a,i,ia,ib,ic,id) (a)=\
+ (ia[(i)&0x0f]^ib[((i)+2)&0x0f]^ic[((i)+8)&0x0f]^id[((i)+13)&0x0f]);\
+ X[(i)&0x0f]=(a)=ROTATE((a),1);
+#endif
+
+#define BODY_00_15(i,a,b,c,d,e,f,xa) \
+ (f)=xa[i]+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
+#define BODY_16_19(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+ Xupdate(f,i,xa,xb,xc,xd); \
+ (f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
+#define BODY_20_31(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+ Xupdate(f,i,xa,xb,xc,xd); \
+ (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
+#define BODY_32_39(i,a,b,c,d,e,f,xa) \
+ Xupdate(f,i,xa,xa,xa,xa); \
+ (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
+#define BODY_40_59(i,a,b,c,d,e,f,xa) \
+ Xupdate(f,i,xa,xa,xa,xa); \
+ (f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
+#define BODY_60_79(i,a,b,c,d,e,f,xa) \
+ Xupdate(f,i,xa,xa,xa,xa); \
+ (f)=X[(i)&0x0f]+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
diff --git a/lib/dns/sec/openssl/stack.c b/lib/dns/sec/openssl/stack.c
new file mode 100644
index 00000000..bc137c43
--- /dev/null
+++ b/lib/dns/sec/openssl/stack.c
@@ -0,0 +1,303 @@
+/* crypto/stack/stack.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Code for stacks
+ * Author - Eric Young v 1.0
+ * 1.2 eay 12-Mar-97 - Modified sk_find so that it _DOES_ return the
+ * lowest index for the seached item.
+ *
+ * 1.1 eay - Take from netdb and added to SSLeay
+ *
+ * 1.0 eay - First version 29/07/92
+ */
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/stack.h>
+
+#undef MIN_NODES
+#define MIN_NODES 4
+
+const char *STACK_version="Stack" OPENSSL_VERSION_PTEXT;
+
+#define FP_ICC (int (*)(const void *,const void *))
+#include <errno.h>
+
+int (*sk_set_cmp_func(STACK *sk, int (*c)()))(void)
+ {
+ int (*old)()=sk->comp;
+
+ if (sk->comp != c)
+ sk->sorted=0;
+ sk->comp=c;
+
+ return old;
+ }
+
+STACK *sk_dup(STACK *sk)
+ {
+ STACK *ret;
+ char **s;
+
+ if ((ret=sk_new(sk->comp)) == NULL) goto err;
+ s=(char **)Realloc((char *)ret->data,
+ (unsigned int)sizeof(char *)*sk->num_alloc);
+ if (s == NULL) goto err;
+ ret->data=s;
+
+ ret->num=sk->num;
+ memcpy(ret->data,sk->data,sizeof(char *)*sk->num);
+ ret->sorted=sk->sorted;
+ ret->num_alloc=sk->num_alloc;
+ ret->comp=sk->comp;
+ return(ret);
+err:
+ return(NULL);
+ }
+
+STACK *sk_new(int (*c)())
+ {
+ STACK *ret;
+ int i;
+
+ if ((ret=(STACK *)Malloc(sizeof(STACK))) == NULL)
+ goto err0;
+ if ((ret->data=(char **)Malloc(sizeof(char *)*MIN_NODES)) == NULL)
+ goto err1;
+ for (i=0; i<MIN_NODES; i++)
+ ret->data[i]=NULL;
+ ret->comp=c;
+ ret->num_alloc=MIN_NODES;
+ ret->num=0;
+ ret->sorted=0;
+ return(ret);
+err1:
+ Free((char *)ret);
+err0:
+ return(NULL);
+ }
+
+int sk_insert(STACK *st, char *data, int loc)
+ {
+ char **s;
+
+ if(st == NULL) return 0;
+ if (st->num_alloc <= st->num+1)
+ {
+ s=(char **)Realloc((char *)st->data,
+ (unsigned int)sizeof(char *)*st->num_alloc*2);
+ if (s == NULL)
+ return(0);
+ st->data=s;
+ st->num_alloc*=2;
+ }
+ if ((loc >= (int)st->num) || (loc < 0))
+ st->data[st->num]=data;
+ else
+ {
+ int i;
+ char **f,**t;
+
+ f=(char **)st->data;
+ t=(char **)&(st->data[1]);
+ for (i=st->num; i>=loc; i--)
+ t[i]=f[i];
+
+#ifdef undef /* no memmove on sunos :-( */
+ memmove( (char *)&(st->data[loc+1]),
+ (char *)&(st->data[loc]),
+ sizeof(char *)*(st->num-loc));
+#endif
+ st->data[loc]=data;
+ }
+ st->num++;
+ st->sorted=0;
+ return(st->num);
+ }
+
+char *sk_delete_ptr(STACK *st, char *p)
+ {
+ int i;
+
+ for (i=0; i<st->num; i++)
+ if (st->data[i] == p)
+ return(sk_delete(st,i));
+ return(NULL);
+ }
+
+char *sk_delete(STACK *st, int loc)
+ {
+ char *ret;
+ int i,j;
+
+ if ((st == NULL) || (st->num == 0) || (loc < 0)
+ || (loc >= st->num)) return(NULL);
+
+ ret=st->data[loc];
+ if (loc != st->num-1)
+ {
+ j=st->num-1;
+ for (i=loc; i<j; i++)
+ st->data[i]=st->data[i+1];
+ /* In theory memcpy is not safe for this
+ * memcpy( &(st->data[loc]),
+ * &(st->data[loc+1]),
+ * sizeof(char *)*(st->num-loc-1));
+ */
+ }
+ st->num--;
+ return(ret);
+ }
+
+int sk_find(STACK *st, char *data)
+ {
+ char **r;
+ int i;
+ int (*comp_func)();
+ if(st == NULL) return -1;
+
+ if (st->comp == NULL)
+ {
+ for (i=0; i<st->num; i++)
+ if (st->data[i] == data)
+ return(i);
+ return(-1);
+ }
+ comp_func=(int (*)())st->comp;
+ if (!st->sorted)
+ {
+ qsort((char *)st->data,st->num,sizeof(char *),FP_ICC comp_func);
+ st->sorted=1;
+ }
+ if (data == NULL) return(-1);
+ r=(char **)bsearch(&data,(char *)st->data,
+ st->num,sizeof(char *),FP_ICC comp_func);
+ if (r == NULL) return(-1);
+ i=(int)(r-st->data);
+ for ( ; i>0; i--)
+ if ((*st->comp)(&(st->data[i-1]),&data) < 0)
+ break;
+ return(i);
+ }
+
+int sk_push(STACK *st, char *data)
+ {
+ return(sk_insert(st,data,st->num));
+ }
+
+int sk_unshift(STACK *st, char *data)
+ {
+ return(sk_insert(st,data,0));
+ }
+
+char *sk_shift(STACK *st)
+ {
+ if (st == NULL) return(NULL);
+ if (st->num <= 0) return(NULL);
+ return(sk_delete(st,0));
+ }
+
+char *sk_pop(STACK *st)
+ {
+ if (st == NULL) return(NULL);
+ if (st->num <= 0) return(NULL);
+ return(sk_delete(st,st->num-1));
+ }
+
+void sk_zero(STACK *st)
+ {
+ if (st == NULL) return;
+ if (st->num <= 0) return;
+ memset((char *)st->data,0,sizeof(st->data)*st->num);
+ st->num=0;
+ }
+
+void sk_pop_free(STACK *st, void (*func)(char *))
+ {
+ int i;
+
+ if (st == NULL) return;
+ for (i=0; i<st->num; i++)
+ if (st->data[i] != NULL)
+ func(st->data[i]);
+ sk_free(st);
+ }
+
+void sk_free(STACK *st)
+ {
+ if (st == NULL) return;
+ if (st->data != NULL) Free((char *)st->data);
+ Free((char *)st);
+ }
+
+int sk_num(STACK *st)
+{
+ if(st == NULL) return -1;
+ return st->num;
+}
+
+char *sk_value(STACK *st, int i)
+{
+ if(st == NULL) return NULL;
+ return st->data[i];
+}
+
+char *sk_set(STACK *st, int i, char *value)
+{
+ if(st == NULL) return NULL;
+ return (st->data[i] = value);
+}
diff --git a/lib/dns/sec/openssl/th-lock.c b/lib/dns/sec/openssl/th-lock.c
new file mode 100644
index 00000000..ed976db3
--- /dev/null
+++ b/lib/dns/sec/openssl/th-lock.c
@@ -0,0 +1,373 @@
+/* crypto/threads/th-lock.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#ifdef LINUX
+#include <typedefs.h>
+#endif
+#ifdef WIN32
+#include <windows.h>
+#endif
+#ifdef SOLARIS
+#include <synch.h>
+#include <thread.h>
+#endif
+#ifdef IRIX
+#include <ulocks.h>
+#include <sys/prctl.h>
+#endif
+#include <openssl/lhash.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/e_os.h>
+#include <openssl/err.h>
+
+int CRYPTO_thread_setup(void);
+void CRYPTO_thread_cleanup(void);
+
+#ifdef IRIX
+static void irix_locking_callback(int mode,int type,char *file,int line);
+static unsigned long irix_thread_id(void );
+#endif
+#ifdef SOLARIS
+static void solaris_locking_callback(int mode,int type,char *file,int line);
+static unsigned long solaris_thread_id(void );
+#endif
+#ifdef WIN32
+static void win32_locking_callback(int mode,int type,char *file,int line);
+#endif
+#ifdef PTHREADS
+static void pthreads_locking_callback(int mode,int type,char *file,int line);
+static unsigned long pthreads_thread_id(void );
+#endif
+
+/* usage:
+ * CRYPTO_thread_setup();
+ * applicaion code
+ * CRYPTO_thread_cleanup();
+ */
+
+#define THREAD_STACK_SIZE (16*1024)
+
+#ifdef WIN32
+
+static HANDLE lock_cs[CRYPTO_NUM_LOCKS];
+
+int CRYPTO_thread_setup(void)
+ {
+ int i;
+
+ for (i=0; i<CRYPTO_NUM_LOCKS; i++)
+ {
+ lock_cs[i]=CreateMutex(NULL,FALSE,NULL);
+ }
+
+ CRYPTO_set_locking_callback((void (*)(int,int,char *,int))win32_locking_callback);
+ /* id callback defined */
+ return(1);
+ }
+
+static void CRYPTO_thread_cleanup(void)
+ {
+ int i;
+
+ CRYPTO_set_locking_callback(NULL);
+ for (i=0; i<CRYPTO_NUM_LOCKS; i++)
+ CloseHandle(lock_cs[i]);
+ }
+
+void win32_locking_callback(int mode, int type, char *file, int line)
+ {
+ if (mode & CRYPTO_LOCK)
+ {
+ WaitForSingleObject(lock_cs[type],INFINITE);
+ }
+ else
+ {
+ ReleaseMutex(lock_cs[type]);
+ }
+ }
+
+#endif /* WIN32 */
+
+#ifdef SOLARIS
+
+#define USE_MUTEX
+
+static mutex_t lock_cs[CRYPTO_NUM_LOCKS];
+#ifdef USE_MUTEX
+static long lock_count[CRYPTO_NUM_LOCKS];
+#else
+static rwlock_t lock_cs[CRYPTO_NUM_LOCKS];
+#endif
+
+void CRYPTO_thread_setup(void)
+ {
+ int i;
+
+ for (i=0; i<CRYPTO_NUM_LOCKS; i++)
+ {
+ lock_count[i]=0;
+#ifdef USE_MUTEX
+ mutex_init(&(lock_cs[i]),USYNC_THREAD,NULL);
+#else
+ rwlock_init(&(lock_cs[i]),USYNC_THREAD,NULL);
+#endif
+ }
+
+ CRYPTO_set_id_callback((unsigned long (*)())solaris_thread_id);
+ CRYPTO_set_locking_callback((void (*)())solaris_locking_callback);
+ }
+
+void CRYPTO_thread_cleanup(void)
+ {
+ int i;
+
+ CRYPTO_set_locking_callback(NULL);
+ for (i=0; i<CRYPTO_NUM_LOCKS; i++)
+ {
+#ifdef USE_MUTEX
+ mutex_destroy(&(lock_cs[i]));
+#else
+ rwlock_destroy(&(lock_cs[i]));
+#endif
+ }
+ }
+
+void solaris_locking_callback(int mode, int type, char *file, int line)
+ {
+#if 0
+ fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
+ CRYPTO_thread_id(),
+ (mode&CRYPTO_LOCK)?"l":"u",
+ (type&CRYPTO_READ)?"r":"w",file,line);
+#endif
+
+#if 0
+ if (CRYPTO_LOCK_SSL_CERT == type)
+ fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
+ CRYPTO_thread_id(),
+ mode,file,line);
+#endif
+ if (mode & CRYPTO_LOCK)
+ {
+#ifdef USE_MUTEX
+ mutex_lock(&(lock_cs[type]));
+#else
+ if (mode & CRYPTO_READ)
+ rw_rdlock(&(lock_cs[type]));
+ else
+ rw_wrlock(&(lock_cs[type]));
+#endif
+ lock_count[type]++;
+ }
+ else
+ {
+#ifdef USE_MUTEX
+ mutex_unlock(&(lock_cs[type]));
+#else
+ rw_unlock(&(lock_cs[type]));
+#endif
+ }
+ }
+
+unsigned long solaris_thread_id(void)
+ {
+ unsigned long ret;
+
+ ret=(unsigned long)thr_self();
+ return(ret);
+ }
+#endif /* SOLARIS */
+
+#ifdef IRIX
+/* I don't think this works..... */
+
+static usptr_t *arena;
+static usema_t *lock_cs[CRYPTO_NUM_LOCKS];
+
+void CRYPTO_thread_setup(void)
+ {
+ int i;
+ char filename[20];
+
+ strcpy(filename,"/tmp/mttest.XXXXXX");
+ mktemp(filename);
+
+ usconfig(CONF_STHREADIOOFF);
+ usconfig(CONF_STHREADMALLOCOFF);
+ usconfig(CONF_INITUSERS,100);
+ usconfig(CONF_LOCKTYPE,US_DEBUGPLUS);
+ arena=usinit(filename);
+ unlink(filename);
+
+ for (i=0; i<CRYPTO_NUM_LOCKS; i++)
+ {
+ lock_cs[i]=usnewsema(arena,1);
+ }
+
+ CRYPTO_set_id_callback((unsigned long (*)())irix_thread_id);
+ CRYPTO_set_locking_callback((void (*)())irix_locking_callback);
+ }
+
+void CRYPTO_thread_cleanup(void)
+ {
+ int i;
+
+ CRYPTO_set_locking_callback(NULL);
+ for (i=0; i<CRYPTO_NUM_LOCKS; i++)
+ {
+ char buf[10];
+
+ sprintf(buf,"%2d:",i);
+ usdumpsema(lock_cs[i],stdout,buf);
+ usfreesema(lock_cs[i],arena);
+ }
+ }
+
+void irix_locking_callback(int mode, int type, char *file, int line)
+ {
+ if (mode & CRYPTO_LOCK)
+ {
+ uspsema(lock_cs[type]);
+ }
+ else
+ {
+ usvsema(lock_cs[type]);
+ }
+ }
+
+unsigned long irix_thread_id(void)
+ {
+ unsigned long ret;
+
+ ret=(unsigned long)getpid();
+ return(ret);
+ }
+#endif /* IRIX */
+
+/* Linux and a few others */
+#ifdef PTHREADS
+
+static pthread_mutex_t lock_cs[CRYPTO_NUM_LOCKS];
+static long lock_count[CRYPTO_NUM_LOCKS];
+
+void CRYPTO_thread_setup(void)
+ {
+ int i;
+
+ for (i=0; i<CRYPTO_NUM_LOCKS; i++)
+ {
+ lock_count[i]=0;
+ pthread_mutex_init(&(lock_cs[i]),NULL);
+ }
+
+ CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
+ CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
+ }
+
+void thread_cleanup(void)
+ {
+ int i;
+
+ CRYPTO_set_locking_callback(NULL);
+ for (i=0; i<CRYPTO_NUM_LOCKS; i++)
+ {
+ pthread_mutex_destroy(&(lock_cs[i]));
+ }
+ }
+
+void pthreads_locking_callback(int mode, int type, char *file,
+ int line)
+ {
+#if 0
+ fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
+ CRYPTO_thread_id(),
+ (mode&CRYPTO_LOCK)?"l":"u",
+ (type&CRYPTO_READ)?"r":"w",file,line);
+#endif
+#if 0
+ if (CRYPTO_LOCK_SSL_CERT == type)
+ fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
+ CRYPTO_thread_id(),
+ mode,file,line);
+#endif
+ if (mode & CRYPTO_LOCK)
+ {
+ pthread_mutex_lock(&(lock_cs[type]));
+ lock_count[type]++;
+ }
+ else
+ {
+ pthread_mutex_unlock(&(lock_cs[type]));
+ }
+ }
+
+unsigned long pthreads_thread_id(void)
+ {
+ unsigned long ret;
+
+ ret=(unsigned long)pthread_self();
+ return(ret);
+ }
+
+#endif /* PTHREADS */
+