]> asedeno.scripts.mit.edu Git - pssh.git/commitdiff
Greg Parker's 2005-06-23 release.
authorAlejandro R. Sedeño <asedeno@mit.edu>
Sun, 18 Mar 2007 17:47:33 +0000 (17:47 +0000)
committerAlejandro R. Sedeño <asedeno@mit.edu>
Sun, 18 Mar 2007 17:47:33 +0000 (17:47 +0000)
333 files changed:
CHANGELOG [new file with mode: 0644]
Makefile [new file with mode: 0644]
README [new file with mode: 0644]
README.code [new file with mode: 0644]
README.licenses [new file with mode: 0644]
README.publickeys [new file with mode: 0644]
arm/Makefile [new file with mode: 0644]
arm/crypto/fortuna/fortuna.c [new file with mode: 0644]
arm/crypto/fortuna/fortuna.h [new file with mode: 0644]
arm/crypto/fortuna/fortuna_acc.c [new file with mode: 0644]
arm/crypto/fortuna/fortuna_gen.c [new file with mode: 0644]
arm/crypto/fortuna/fortuna_locl.h [new file with mode: 0644]
arm/crypto/openssl/aes/CVS/Entries [new file with mode: 0644]
arm/crypto/openssl/aes/CVS/Repository [new file with mode: 0644]
arm/crypto/openssl/aes/CVS/Root [new file with mode: 0644]
arm/crypto/openssl/aes/CVS/Tag [new file with mode: 0644]
arm/crypto/openssl/aes/aes.h [new file with mode: 0644]
arm/crypto/openssl/aes/aes_armcalls.c [new file with mode: 0644]
arm/crypto/openssl/aes/aes_cbc.c [new file with mode: 0644]
arm/crypto/openssl/aes/aes_core.c [new file with mode: 0644]
arm/crypto/openssl/aes/aes_includes.h [new file with mode: 0644]
arm/crypto/openssl/aes/aes_internal.h [new file with mode: 0644]
arm/crypto/openssl/aes/aes_locl.h [new file with mode: 0644]
arm/crypto/openssl/aes/aes_tables.c [new file with mode: 0644]
arm/crypto/openssl/aes/aes_tables.h [new file with mode: 0644]
arm/crypto/openssl/bn/CVS/Entries [new file with mode: 0644]
arm/crypto/openssl/bn/CVS/Repository [new file with mode: 0644]
arm/crypto/openssl/bn/CVS/Root [new file with mode: 0644]
arm/crypto/openssl/bn/CVS/Tag [new file with mode: 0644]
arm/crypto/openssl/bn/bn_add.c [new file with mode: 0644]
arm/crypto/openssl/bn/bn_armcalls.c [new file with mode: 0644]
arm/crypto/openssl/bn/bn_asm.c [new file with mode: 0644]
arm/crypto/openssl/bn/bn_ctx.c [new file with mode: 0644]
arm/crypto/openssl/bn/bn_div.c [new file with mode: 0644]
arm/crypto/openssl/bn/bn_exp.c [new file with mode: 0644]
arm/crypto/openssl/bn/bn_gcd.c [new file with mode: 0644]
arm/crypto/openssl/bn/bn_includes.h [new file with mode: 0644]
arm/crypto/openssl/bn/bn_internal.h [new file with mode: 0644]
arm/crypto/openssl/bn/bn_lcl.h [new file with mode: 0644]
arm/crypto/openssl/bn/bn_lib.c [new file with mode: 0644]
arm/crypto/openssl/bn/bn_mod.c [new file with mode: 0644]
arm/crypto/openssl/bn/bn_mont.c [new file with mode: 0644]
arm/crypto/openssl/bn/bn_mul.c [new file with mode: 0644]
arm/crypto/openssl/bn/bn_print.c [new file with mode: 0644]
arm/crypto/openssl/bn/bn_rand.c [new file with mode: 0644]
arm/crypto/openssl/bn/bn_recp.c [new file with mode: 0644]
arm/crypto/openssl/bn/bn_shift.c [new file with mode: 0644]
arm/crypto/openssl/bn/bn_sqr.c [new file with mode: 0644]
arm/crypto/openssl/bn/bn_word.c [new file with mode: 0644]
arm/crypto/openssl/cryptlib.h [new file with mode: 0644]
arm/crypto/rand.c [new file with mode: 0644]
arm/crypto/rand.h [new file with mode: 0644]
arm/crypto/rand_armcalls.c [new file with mode: 0644]
arm/crypto/rand_time.S [new file with mode: 0644]
arm/crypto/rand_time.h [new file with mode: 0644]
arm/crypto/sha2/sha2.c [new file with mode: 0644]
arm/crypto/sha2/sha2.h [new file with mode: 0644]
arm/data/prefs.c [new file with mode: 0644]
arm/data/prefs.h [new file with mode: 0644]
arm/export-list [new file with mode: 0644]
arm/rsrc/rsrc.h [new file with mode: 0644]
arm/ssh/openssh/openbsd-compat/CVS/Entries [new file with mode: 0644]
arm/ssh/openssh/openbsd-compat/CVS/Repository [new file with mode: 0644]
arm/ssh/openssh/openbsd-compat/CVS/Root [new file with mode: 0644]
arm/ssh/openssh/openbsd-compat/CVS/Tag [new file with mode: 0644]
arm/ssh/openssh/openbsd-compat/bsd-snprintf.c [new file with mode: 0644]
arm/ssh/ssh.c [new file with mode: 0644]
arm/ssh/ssh.h [new file with mode: 0644]
arm/ssh/sshzlib.c [new file with mode: 0644]
arm/ssh/sshzlib.h [new file with mode: 0644]
arm/ssh/sshzlib_armcalls.c [new file with mode: 0644]
arm/util/PalmOS.c [new file with mode: 0644]
arm/util/assert.h [new file with mode: 0644]
arm/util/ctype.h [new file with mode: 0644]
arm/util/includes.h [new file with mode: 0644]
arm/util/pace.h [new file with mode: 0644]
arm/util/stdlib.c [new file with mode: 0644]
arm/util/stdlib.h [new file with mode: 0644]
arm/util/swap.h [new file with mode: 0644]
arm/util/xmalloc.c [new file with mode: 0644]
arm/util/xmalloc.h [new file with mode: 0644]
arm/vt100/misc.c [new file with mode: 0644]
arm/vt100/misc.h [new file with mode: 0644]
arm/vt100/palm/palmprint.c [new file with mode: 0644]
arm/vt100/palm/palmstuff.h [new file with mode: 0644]
arm/vt100/palm/palmucs.c [new file with mode: 0644]
arm/vt100/palm/palmwindow.c [new file with mode: 0644]
arm/vt100/putty.h [new file with mode: 0644]
arm/vt100/puttymem.h [new file with mode: 0644]
arm/vt100/puttyps.h [new file with mode: 0644]
arm/vt100/terminal.c [new file with mode: 0644]
arm/vt100/terminal.h [new file with mode: 0644]
arm/vt100/tree234.c [new file with mode: 0644]
arm/vt100/tree234.h [new file with mode: 0644]
arm/vt100/vt100.c [new file with mode: 0644]
arm/vt100/vt100.h [new file with mode: 0644]
arm/vt100/vt100_armcalls.c [new file with mode: 0644]
arm/vt100/wcwidth.c [new file with mode: 0644]
arm/vt100/wcwidth.h [new file with mode: 0644]
crypto/cryptorsrc.h [new file with mode: 0644]
crypto/openssl/aes/aes.h [new file with mode: 0644]
crypto/openssl/aes/aes_armstubs.c [new file with mode: 0644]
crypto/openssl/aes/aes_armstubs.h [new file with mode: 0644]
crypto/openssl/aes/aes_tables.rcp [new file with mode: 0644]
crypto/openssl/bn/bn.h [new file with mode: 0644]
crypto/openssl/bn/bn_armstubs.c [new file with mode: 0644]
crypto/openssl/bn/bn_armstubs.h [new file with mode: 0644]
crypto/openssl/cryptlib.h [new file with mode: 0644]
crypto/openssl/des/des.h [new file with mode: 0644]
crypto/openssl/des/des_enc.c [new file with mode: 0644]
crypto/openssl/des/des_locl.h [new file with mode: 0644]
crypto/openssl/des/des_tables.c [new file with mode: 0644]
crypto/openssl/des/des_tables.rcp [new file with mode: 0644]
crypto/openssl/des/ncbc_enc.c [new file with mode: 0644]
crypto/openssl/des/set_key.c [new file with mode: 0644]
crypto/openssl/dh/dh.h [new file with mode: 0644]
crypto/openssl/dh/dh_key.c [new file with mode: 0644]
crypto/openssl/dh/dh_lib.c [new file with mode: 0644]
crypto/openssl/dsa/dsa.h [new file with mode: 0644]
crypto/openssl/dsa/dsa_lib.c [new file with mode: 0644]
crypto/openssl/dsa/dsa_ossl.c [new file with mode: 0644]
crypto/openssl/dsa/dsa_sign.c [new file with mode: 0644]
crypto/openssl/dsa/dsa_vrf.c [new file with mode: 0644]
crypto/openssl/evp/digest.c [new file with mode: 0644]
crypto/openssl/evp/e_aes.c [new file with mode: 0644]
crypto/openssl/evp/e_des3.c [new file with mode: 0644]
crypto/openssl/evp/e_null.c [new file with mode: 0644]
crypto/openssl/evp/evp.h [new file with mode: 0644]
crypto/openssl/evp/evp_enc.c [new file with mode: 0644]
crypto/openssl/evp/evp_locl.h [new file with mode: 0644]
crypto/openssl/evp/m_md5.c [new file with mode: 0644]
crypto/openssl/evp/m_sha1.c [new file with mode: 0644]
crypto/openssl/hmac/hmac.c [new file with mode: 0644]
crypto/openssl/hmac/hmac.h [new file with mode: 0644]
crypto/openssl/md32_common.h [new file with mode: 0644]
crypto/openssl/md5/md5.h [new file with mode: 0644]
crypto/openssl/md5/md5_dgst.c [new file with mode: 0644]
crypto/openssl/md5/md5_locl.h [new file with mode: 0644]
crypto/openssl/md5/md5_one.c [new file with mode: 0644]
crypto/openssl/md5/md5test.c [new file with mode: 0644]
crypto/openssl/mem_clr.c [new file with mode: 0644]
crypto/openssl/objects/obj_mac.h [new file with mode: 0644]
crypto/openssl/objects/objects.h [new file with mode: 0644]
crypto/openssl/rsa/rsa.h [new file with mode: 0644]
crypto/openssl/rsa/rsa_eay.c [new file with mode: 0644]
crypto/openssl/rsa/rsa_lib.c [new file with mode: 0644]
crypto/openssl/rsa/rsa_none.c [new file with mode: 0644]
crypto/openssl/rsa/rsa_pk1.c [new file with mode: 0644]
crypto/openssl/sha/sha.h [new file with mode: 0644]
crypto/openssl/sha/sha1dgst.c [new file with mode: 0644]
crypto/openssl/sha/sha_locl.h [new file with mode: 0644]
crypto/rand.h [new file with mode: 0644]
crypto/rand_armstubs.c [new file with mode: 0644]
data/connectionlist.c [new file with mode: 0644]
data/connectionlist.h [new file with mode: 0644]
data/hostkeys.c [new file with mode: 0644]
data/hostkeys.h [new file with mode: 0644]
data/memolist.c [new file with mode: 0644]
data/memolist.h [new file with mode: 0644]
data/prefs.c [new file with mode: 0644]
data/prefs.h [new file with mode: 0644]
data/publickeys.c [new file with mode: 0644]
data/publickeys.h [new file with mode: 0644]
data/recordlist.c [new file with mode: 0644]
data/recordlist.h [new file with mode: 0644]
forms/DIA.c [new file with mode: 0644]
forms/DIA.h [new file with mode: 0644]
forms/about.c [new file with mode: 0644]
forms/about.h [new file with mode: 0644]
forms/connectionprefsform.c [new file with mode: 0644]
forms/connectionprefsform.h [new file with mode: 0644]
forms/detailsform.c [new file with mode: 0644]
forms/detailsform.h [new file with mode: 0644]
forms/displayprefsform.c [new file with mode: 0644]
forms/displayprefsform.h [new file with mode: 0644]
forms/hostkeydetailsform.c [new file with mode: 0644]
forms/hostkeydetailsform.h [new file with mode: 0644]
forms/hostkeysform.c [new file with mode: 0644]
forms/hostkeysform.h [new file with mode: 0644]
forms/kbdint0form.c [new file with mode: 0644]
forms/kbdint0form.h [new file with mode: 0644]
forms/kbdintform.c [new file with mode: 0644]
forms/kbdintform.h [new file with mode: 0644]
forms/keyboardprefsform.c [new file with mode: 0644]
forms/keyboardprefsform.h [new file with mode: 0644]
forms/loginform.c [new file with mode: 0644]
forms/loginform.h [new file with mode: 0644]
forms/mainform.c [new file with mode: 0644]
forms/mainform.h [new file with mode: 0644]
forms/memoform.c [new file with mode: 0644]
forms/memoform.h [new file with mode: 0644]
forms/passphraseform.c [new file with mode: 0644]
forms/passphraseform.h [new file with mode: 0644]
forms/passwordform.c [new file with mode: 0644]
forms/passwordform.h [new file with mode: 0644]
forms/publickeychoiceform.c [new file with mode: 0644]
forms/publickeychoiceform.h [new file with mode: 0644]
forms/publickeydetailsform.c [new file with mode: 0644]
forms/publickeydetailsform.h [new file with mode: 0644]
forms/publickeysform.c [new file with mode: 0644]
forms/publickeysform.h [new file with mode: 0644]
forms/resize.c [new file with mode: 0644]
forms/resize.h [new file with mode: 0644]
forms/resizeconsts.h [new file with mode: 0644]
forms/terminalform.c [new file with mode: 0644]
forms/terminalform.h [new file with mode: 0644]
main.c [new file with mode: 0644]
pssh.def [new file with mode: 0644]
rsrc/123buttons.bmp [new file with mode: 0644]
rsrc/abcbuttons.bmp [new file with mode: 0644]
rsrc/buttons.bmp [new file with mode: 0644]
rsrc/closebox.bmp [new file with mode: 0644]
rsrc/closeboxhi.bmp [new file with mode: 0644]
rsrc/closeboxselected.bmp [new file with mode: 0644]
rsrc/closeboxselectedhi.bmp [new file with mode: 0644]
rsrc/downarrow.bmp [new file with mode: 0644]
rsrc/downarrowhi.bmp [new file with mode: 0644]
rsrc/downarrowselected.bmp [new file with mode: 0644]
rsrc/downarrowselectedhi.bmp [new file with mode: 0644]
rsrc/etcbuttons.bmp [new file with mode: 0644]
rsrc/leftarrow.bmp [new file with mode: 0644]
rsrc/leftarrowhi.bmp [new file with mode: 0644]
rsrc/leftarrowselected.bmp [new file with mode: 0644]
rsrc/leftarrowselectedhi.bmp [new file with mode: 0644]
rsrc/linedown.bmp [new file with mode: 0644]
rsrc/linedowndisabled.bmp [new file with mode: 0644]
rsrc/linedowndisabledhi.bmp [new file with mode: 0644]
rsrc/linedownhi.bmp [new file with mode: 0644]
rsrc/linedownselected.bmp [new file with mode: 0644]
rsrc/linedownselectedhi.bmp [new file with mode: 0644]
rsrc/lineup.bmp [new file with mode: 0644]
rsrc/lineupdisabled.bmp [new file with mode: 0644]
rsrc/lineupdisabledhi.bmp [new file with mode: 0644]
rsrc/lineuphi.bmp [new file with mode: 0644]
rsrc/lineupselected.bmp [new file with mode: 0644]
rsrc/lineupselectedhi.bmp [new file with mode: 0644]
rsrc/med.font [new file with mode: 0644]
rsrc/medsingle.font [new file with mode: 0644]
rsrc/nano.font [new file with mode: 0644]
rsrc/nanosingle.font [new file with mode: 0644]
rsrc/pagedown.bmp [new file with mode: 0644]
rsrc/pagedowndisabled.bmp [new file with mode: 0644]
rsrc/pagedowndisabledhi.bmp [new file with mode: 0644]
rsrc/pagedownhi.bmp [new file with mode: 0644]
rsrc/pagedownselected.bmp [new file with mode: 0644]
rsrc/pagedownselectedhi.bmp [new file with mode: 0644]
rsrc/pageup.bmp [new file with mode: 0644]
rsrc/pageupdisabled.bmp [new file with mode: 0644]
rsrc/pageupdisabledhi.bmp [new file with mode: 0644]
rsrc/pageuphi.bmp [new file with mode: 0644]
rsrc/pageupselected.bmp [new file with mode: 0644]
rsrc/pageupselectedhi.bmp [new file with mode: 0644]
rsrc/passwordfont [new file with mode: 0644]
rsrc/pssh.rcp [new file with mode: 0755]
rsrc/pssh.rsrc [new file with mode: 0644]
rsrc/rightarrow.bmp [new file with mode: 0644]
rsrc/rightarrowhi.bmp [new file with mode: 0644]
rsrc/rightarrowselected.bmp [new file with mode: 0644]
rsrc/rightarrowselectedhi.bmp [new file with mode: 0644]
rsrc/rsrc.h [new file with mode: 0644]
rsrc/tcbuttons.bmp [new file with mode: 0644]
rsrc/uparrow.bmp [new file with mode: 0644]
rsrc/uparrowhi.bmp [new file with mode: 0644]
rsrc/uparrowselected.bmp [new file with mode: 0644]
rsrc/uparrowselectedhi.bmp [new file with mode: 0644]
ssh/connection.c [new file with mode: 0644]
ssh/connection.h [new file with mode: 0644]
ssh/keyfile.c [new file with mode: 0644]
ssh/keyfile.h [new file with mode: 0644]
ssh/keyimport.c [new file with mode: 0644]
ssh/keyimport.h [new file with mode: 0644]
ssh/openssh/bufaux.c [new file with mode: 0644]
ssh/openssh/bufaux.h [new file with mode: 0644]
ssh/openssh/buffer.c [new file with mode: 0644]
ssh/openssh/buffer.h [new file with mode: 0644]
ssh/openssh/cipher.c [new file with mode: 0644]
ssh/openssh/cipher.h [new file with mode: 0644]
ssh/openssh/dh.c [new file with mode: 0644]
ssh/openssh/dh.h [new file with mode: 0644]
ssh/openssh/getput.h [new file with mode: 0644]
ssh/openssh/kex.c [new file with mode: 0644]
ssh/openssh/kex.h [new file with mode: 0644]
ssh/openssh/kexdh.c [new file with mode: 0644]
ssh/openssh/key.c [new file with mode: 0644]
ssh/openssh/key.h [new file with mode: 0644]
ssh/openssh/mac.c [new file with mode: 0644]
ssh/openssh/mac.h [new file with mode: 0644]
ssh/openssh/match.c [new file with mode: 0644]
ssh/openssh/match.h [new file with mode: 0644]
ssh/openssh/openbsd-compat/base64.c [new file with mode: 0644]
ssh/openssh/openbsd-compat/base64.h [new file with mode: 0644]
ssh/openssh/openbsd-compat/bsd-snprintf.c [new file with mode: 0644]
ssh/openssh/ssh-dss.c [new file with mode: 0644]
ssh/openssh/ssh-rsa.c [new file with mode: 0644]
ssh/openssh/uuencode.c [new file with mode: 0644]
ssh/openssh/uuencode.h [new file with mode: 0644]
ssh/packetizer.c [new file with mode: 0644]
ssh/packetizer.h [new file with mode: 0644]
ssh/session.c [new file with mode: 0644]
ssh/session.h [new file with mode: 0644]
ssh/ssh.c [new file with mode: 0644]
ssh/ssh.h [new file with mode: 0644]
ssh/ssh2.h [new file with mode: 0644]
ssh/sshzlib.c [new file with mode: 0644]
ssh/sshzlib.h [new file with mode: 0644]
ssh/transport.c [new file with mode: 0644]
ssh/transport.h [new file with mode: 0644]
util/armstubs.c [new file with mode: 0644]
util/armstubs.h [new file with mode: 0644]
util/assert.h [new file with mode: 0644]
util/ctype.h [new file with mode: 0644]
util/formutils.c [new file with mode: 0644]
util/formutils.h [new file with mode: 0644]
util/includes.h [new file with mode: 0644]
util/limits.h [new file with mode: 0644]
util/oem/PalmChars.h [new file with mode: 0644]
util/oem/SonyChars.h [new file with mode: 0644]
util/oem/SonyErrorBase.h [new file with mode: 0644]
util/oem/SonyHRLib.h [new file with mode: 0644]
util/oem/SonyJogAssist.h [new file with mode: 0644]
util/oem/SonySilkLib.h [new file with mode: 0644]
util/oem/SonySystemFtr.h [new file with mode: 0644]
util/oem/SonySystemResources.h [new file with mode: 0644]
util/oem/SonyTypes.h [new file with mode: 0644]
util/pce.h [new file with mode: 0644]
util/queue.c [new file with mode: 0644]
util/queue.h [new file with mode: 0644]
util/stdlib.c [new file with mode: 0644]
util/stdlib.h [new file with mode: 0644]
util/xmalloc.c [new file with mode: 0644]
util/xmalloc.h [new file with mode: 0644]
vt100/vt100.c [new file with mode: 0644]
vt100/vt100.h [new file with mode: 0644]

diff --git a/CHANGELOG b/CHANGELOG
new file mode 100644 (file)
index 0000000..8c68320
--- /dev/null
+++ b/CHANGELOG
@@ -0,0 +1,283 @@
+pssh 2005-06-23:
+    Bug fixed:
+    * Fixed crash during connection when server sends a login banner.
+
+
+pssh 2005-06-03:
+    Bug fixed:
+    * Fixed crashes and incorrect drawing after using the pop-up clock.
+
+
+pssh 2005-05-18-TEST:
+    Bugs fixed:
+    * Rewrote screen resizing support.
+    * Fixed incorrect display of table selection.
+    * Fixed default focus in some forms.
+
+
+pssh 2005-05-06-TEST:
+    New features:
+    * Added options to hide the on-screen keyboard and Palm OS status bar.
+    * Added optional ` to ESC key remapping.
+
+    Bug fixed:
+    * Fixed zlib compression.
+
+
+pssh 2004-12-30:
+    Bugs fixed:
+    * Fixed crash during connect on Treo 650.
+    * Fixed up and down arrows on Treo 650.
+    * Fixed Mini Keyboard on Treo 650.
+
+    Known bug: 
+    * zlib is still disabled.
+
+
+pssh 2004-12-29:
+    New feature:
+    * ARM-based terminal emulation means typing and display performance 
+      is now faster than ever.
+
+    Bug fixed:
+    * Fixed sticky shift key in on-screen keyboard.
+
+    Known bug: 
+    * zlib is still disabled.
+
+
+pssh 2004-11-23-TEST:
+    Bugs fixed:
+    * Failed relocation of ARM code on devices with lots of RAM.
+    * Multiple crashes introduced in ARM conversion.
+
+    Known bug: 
+    * zlib is still disabled.
+
+
+pssh 2004-08-27-TEST:
+    Bug fixed:
+    * ARM-based terminal emulation means typing and display performance 
+      is now faster than ever.
+
+    Known bug:
+    * zlib is still disabled.
+
+
+pssh 2004-08-25:
+    Bug fixed:
+    * Fixed authentication when server requires multiple authentication 
+      types (e.g. both public-key and password).
+
+    Known bugs:
+    * zlib is still disabled.
+    * Typing performance is slower than version 2004-03-24 on some devices.
+
+
+pssh 2004-08-24-TEST:
+    Bug fixed:
+    * Fixed keyboard-interactive authentication when server sends multiple 
+      rounds of prompts.
+
+    Known bugs:
+    * zlib is still disabled.
+    * Typing performance is slower than version 2004-03-24 on some devices.
+
+
+pssh 2004-08-23-TEST:
+    New feature:
+    * First draft of keyboard-interactive authentication support.
+
+    Known bugs:
+    * zlib is still disabled.
+    * Typing performance is slower than version 2004-03-24 on some devices.
+
+
+pssh 2004-07-14:
+    Bugs fixed:
+    * Fixed "Fatal Error: out of memory" error when server sends large packets.
+    * Fixed "Fatal Error: alloc 65536 not supported" error when server sends 
+      large packets.
+
+    Known bugs:
+    * zlib is still disabled.
+    * Typing performance is slower than version 2004-03-24 on some devices.
+
+
+pssh 2004-06-06:
+    New features:
+    * Added preference for backspace behavior.
+    * Added ISO 8859-1 (Latin-1) characters to on-screen keyboards.
+    * Added function keys to on-screen keyboards.
+
+    Bug fixed:
+    * Reduced screen flashing when using on-screen keyboards.
+
+    Known bugs:
+    * zlib is still disabled.
+    * Typing performance is slower than version 2004-03-24 on some devices.
+
+
+pssh 2004-06-05:
+    Bugs fixed:
+    * Improved display of server banners.
+    * Connecting to some Cisco servers now works.
+
+    Known bugs:
+    * zlib is still disabled.
+    * Typing performance is slower on some devices.
+
+
+pssh 2004-05-04-TEST:
+    New features:
+    * Added shortcuts for Ctrl (/T) and ESC (/E)
+
+    Bugs fixed:
+    * Correct small font on low-res devices.
+
+    Known bugs:
+    * zlib is still disabled
+
+
+pssh 2004-05-02-TEST:
+    New features:
+    * Improved terminal emulation from PuTTY 0.54b. 
+    * Support for ISO 8859-1 (Latin 1) encoding.
+    * Support for VT100 Special Graphics Set including line-drawing characters.
+
+    Bugs fixed:
+    * Pasting more than 256 characters now works.
+    * Public key import works even if the memo doesn't start with a comment.
+    * Public key import now handles the presence of hidden memos correctly.
+    * The control key on an external keyboard should now be recognized.
+
+    Known bugs:
+    * zlib is still disabled
+
+
+pssh 2004-03-24:
+    New features:
+    * "T|C Keyboard" renamed "Mini Keyboard". It now adapts itself 
+      when running on a Treo 600.
+
+    Bugs fixed:
+    * Treo 600 rocker up and down now work as arrow keys.
+
+    Known bugs:
+    * zlib is still disabled
+
+
+pssh 2004-03-21-TEST:
+    Bugs fixed:
+    * pssh no longer crashes with "Buffer Not Empty" when the server 
+      sends a login banner.
+    * Timeout for DNS and connecting increased to 10 seconds. 
+    * Virtual Graffiti area no longer gets stuck after displaying About 
+      or Credits dialog.
+
+    Known bugs: 
+    * zlib is still disabled
+
+
+pssh 2004-03-17-TEST:
+    New features:
+    * Support for low-resolution screens like Treo 600 (160x160)
+    * Thumb wheel scrolls scrollback. 
+    * Thumb wheel as CTRL/ESC improved.
+
+    Bugs fixed:
+    * Updated screen resizing code to work better with Palm OS Cobalt. 
+      (pssh has not actually been tested on Palm OS Cobalt.)
+
+    Known bugs:
+    * zlib is still disabled
+
+
+pssh 2004-02-22:
+    New features:
+    * "Toggle title bar" option uses more of the screen 
+      for the terminal display
+    * Thumb wheel press acts as CTRL and ESC keys. 
+      (Press once for CTRL, twice for ESC)
+
+    Bugs fixed:
+    * fixed crash when resizing the terminal display
+    * fixed incorrectly drawn buttons on some Sony devices
+    * fixed incorrect drag-selection of terminal contents
+
+    Known bugs:
+    * zlib is still disabled
+
+
+pssh 2004-02-12:
+    Bugs fixed:
+    * fixed some terminal redraw problems
+    * fixed performance problems introduced in version 2004-02-05 
+    * disabled zlib data compression because of crash on quit
+
+
+pssh 2004-02-05:
+    New feature: 
+    * zlib data compression (requires SysZLib.prc from http://www.copera.com)
+
+    Bugs fixed:
+    * "esc" button now sends ESC immediately, rather than behaving like 
+      a modifer key. This works better for vi.
+    * pssh no longer re-establishes a timed-out network connection merely 
+      to  close an ssh session
+    * pssh no longer crashes when importing new public keys
+
+
+pssh 2004-01-24:
+    New features:
+    * Bell (beeps or flashes screen)
+    * Reconnects after auto-power-off
+    * New preferences: ciphers, authentication methods, scrollback size 
+      and behavior, bell type
+    
+    Bug fixed:
+    * changing font or screen size no longer leaves garbage pixels on screen
+
+
+pssh 2004-01-20:
+    Bug fixed:
+    * pssh no longer crashes during quit
+
+    Known bugs:
+    * changing font size or screen size can leave garbage pixels on screen
+
+
+pssh 2004-01-15:
+    New features:
+    * Public-key authentication with RSA and DSA keys
+    * Optional larger font size
+    * Customizable text colors
+
+    Bugs fixed:
+    * pssh now quits faster because of a bug fix in the random number generator
+    * On-screen keyboard state is now remembered
+    * "Tungsten C onscreen keyboard" is now usable on non-Tungsten-C devices
+    * Keyboard icons in Graffiti area now hide on-screen keyboard
+    * Shift key on on-screen keyboard now unshifts correctly
+        
+    Known bugs:
+    * pssh crashes during quit on some devices
+
+
+pssh 2004-01-03:
+    New feature:
+    * Support for larger screens like Tungsten T3 and Clie NX70V
+
+    Bug fixed:
+    * Arrow keys on Clie keyboard now work as expected
+
+    Known bugs:
+    * pssh crashes during quit on some devices
+
+
+pssh 2004-01-01:
+    New feature:
+    * First public release
+
+    Known bugs:
+    * pssh crashes during quit on some devices
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..657412a
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,213 @@
+# pssh makefile
+
+all: install
+
+
+.PHONY=bin rcp all install clean build armstuff
+.SUFFIXES=
+
+OPTIMIZATION = -Os
+WARNINGS = -W -Wall -Wundef -Wshadow -Wmissing-declarations -Wmissing-prototypes -Wpointer-arith -Wno-format -Wuninitialized
+
+# CFLAGS = -g
+# LDFLAGS = -g
+
+
+# Peal
+PEAL = ../peal
+PEAL_SRCS = util/peal.c
+PEAL_FILES = util/peal.c util/peal.h util/elf.h util/elf32.h util/elf_common.h
+util/peal.c: $(PEAL)/m68k/peal.c
+       cp $(PEAL)/m68k/peal.c util/peal.c
+util/peal.h: $(PEAL)/m68k/peal.h
+       cp $(PEAL)/m68k/peal.h util/peal.h
+util/elf.h: $(PEAL)/m68k/elf.h
+       cp $(PEAL)/m68k/elf.h util/elf.h
+util/elf32.h: $(PEAL)/m68k/elf32.h
+       cp $(PEAL)/m68k/elf32.h util/elf32.h
+util/elf_common.h: $(PEAL)/m68k/elf_common.h
+       cp $(PEAL)/m68k/elf_common.h util/elf_common.h
+
+
+# OpenSSL
+BN_SRCS = bn/bn_armstubs.c 
+AES_SRCS = aes/aes_armstubs.c
+DH_SRCS = dh/dh_key.c dh/dh_lib.c
+DES_SRCS = des/des_enc.c des/set_key.c des/des_tables.c
+DSA_SRCS = dsa/dsa_lib.c dsa/dsa_ossl.c dsa/dsa_sign.c dsa/dsa_vrf.c
+EVP_SRCS = evp/digest.c evp/e_des3.c evp/e_aes.c evp/e_null.c evp/evp_enc.c evp/m_md5.c evp/m_sha1.c 
+HMAC_SRCS = hmac/hmac.c 
+MD5_SRCS = md5/md5_dgst.c md5/md5_one.c
+RSA_SRCS = rsa/rsa_eay.c rsa/rsa_lib.c rsa/rsa_none.c rsa/rsa_pk1.c 
+SHA_SRCS = sha/sha1dgst.c
+
+OPENSSL_SRCS = $(addprefix openssl/, \
+       mem_clr.c \
+       $(AES_SRCS) $(BN_SRCS) $(DH_SRCS) $(DES_SRCS) $(DSA_SRCS) $(EVP_SRCS) \
+       $(HMAC_SRCS) $(MD5_SRCS) $(RSA_SRCS) $(SHA_SRCS) \
+)
+
+# crypto (OpenSSL and otherwise)
+CRYPTO_SRCS = $(addprefix crypto/, \
+       rand_armstubs.c $(OPENSSL_SRCS) \
+)
+
+# OpenSSH
+OPENSSH_SRCS = $(addprefix openssh/, \
+       bufaux.c buffer.c cipher.c dh.c kex.c kexdh.c key.c mac.c \
+       match.c ssh-dss.c ssh-rsa.c uuencode.c openbsd-compat/base64.c \
+       openbsd-compat/bsd-snprintf.c \
+)
+
+# ssh (OpenSSH and PuTTY and custom)
+SSH_SRCS = $(addprefix ssh/, \
+       connection.c keyfile.c keyimport.c packetizer.c session.c ssh.c transport.c sshzlib.c \
+       $(OPENSSH_SRCS) \
+)
+
+# util
+UTIL_SRCS = $(addprefix util/, \
+       armstubs.c formutils.c queue.c stdlib.c xmalloc.c \
+)
+
+# vt100 (PuTTY)
+VT100_SRCS = vt100/vt100.c
+
+# Palm forms
+FORM_SRCS = $(addprefix forms/, \
+       about.c connectionprefsform.c detailsform.c displayprefsform.c \
+       hostkeysform.c hostkeydetailsform.c kbdintform.c kbdint0form.c \
+       keyboardprefsform.c \
+       loginform.c mainform.c memoform.c passwordform.c passphraseform.c \
+       publickeysform.c publickeychoiceform.c publickeydetailsform.c \
+       terminalform.c DIA.c resize.c \
+)
+
+# Palm data
+DATA_SRCS = $(addprefix data/, \
+       connectionlist.c hostkeys.c memolist.c prefs.c publickeys.c \
+       recordlist.c \
+)
+
+# Everything 68K
+SRCS = main.c $(CRYPTO_SRCS) $(FORM_SRCS) $(DATA_SRCS) $(SSH_SRCS) \
+       $(UTIL_SRCS) $(VT100_SRCS) $(PEAL_SRCS)
+OBJECTS = $(addprefix build/,$(SRCS:.c=.o))
+
+# rsrc
+RSRC_HDRS = rsrc/rsrc.h crypto/cryptorsrc.h
+RSRC_SRCS = crypto/openssl/aes/aes_tables.rcp crypto/openssl/des/des_tables.rcp rsrc/pssh.rcp
+RSRC_OBJS = $(addprefix build/,$(RSRC_SRCS:.rcp=.ro))
+
+OBJDIRS = $(addprefix build/,$(sort $(dir $(SRCS) $(dir $(RSRC_SRCS)))))
+
+
+install: pssh.prc
+       -open pssh.prc
+
+pssh.prc: pssh.def pssh armstuff $(RSRC_OBJS)
+       build-prc -o pssh.prc pssh.def pssh arm/armc.ro $(RSRC_OBJS)
+
+pssh: $(PEAL_FILES) $(OBJDIRS) $(OBJECTS) pssh-sections.o pssh-sections.ld
+       m68k-palmos-gcc $(LDFLAGS) $(OBJECTS) pssh-sections.o pssh-sections.ld -lNetSocket -lPalmOSGlue -o pssh
+
+pssh-sections.o: pssh-sections.s
+       m68k-palmos-gcc -c pssh-sections.s
+
+pssh-sections.s pssh-sections.ld: pssh.def
+       m68k-palmos-multigen pssh.def
+
+armstuff: 
+       make -C arm
+
+# fixme need to handle ARM-endian resources better
+build/crypto/openssl/aes/aes_tables.ro : crypto/openssl/aes/aes_tables.rcp
+       pilrc -LE32 -ro -I crypto -I rsrc $< $@
+
+build/%.ro : %.rcp
+       pilrc -ro -I crypto -I rsrc $< $@
+
+$(OBJDIRS): 
+       mkdir -p $@
+
+
+# 68K C file targets
+
+define compile
+       m68k-palmos-gcc $(CFLAGS) $(OPTIMIZATION) $(WARNINGS) \
+          -I. -Iutil -Iutil/oem -Irsrc $(addprefix -I,$1) \
+          -c $2 -o $3
+endef
+
+build/crypto/openssl/aes/%.o  : crypto/openssl/aes/%.c
+       $(call compile, crypto crypto/openssl crypto/openssl/aes,  $<, $@ )
+
+build/crypto/openssl/bn/%.o   : crypto/openssl/bn/%.c
+       $(call compile, crypto crypto/openssl crypto/openssl/bn,   $<, $@ )
+
+build/crypto/openssl/des/%.o  : crypto/openssl/des/%.c
+       $(call compile, crypto crypto/openssl crypto/openssl/des,  $<, $@ )
+
+build/crypto/openssl/dh/%.o   : crypto/openssl/dh/%.c
+       $(call compile, crypto crypto/openssl crypto/openssl/dh,   $<, $@ )
+
+build/crypto/openssl/dsa/%.o  : crypto/openssl/dsa/%.c
+       $(call compile, crypto crypto/openssl crypto/openssl/dsa,  $<, $@ )
+
+build/crypto/openssl/evp/%.o  : crypto/openssl/evp/%.c
+       $(call compile, crypto crypto/openssl crypto/openssl/evp,  $<, $@ )
+
+build/crypto/openssl/hmac/%.o : crypto/openssl/hmac/%.c
+       $(call compile, crypto crypto/openssl crypto/openssl/hmac, $<, $@ )
+
+build/crypto/openssl/md5/%.o  : crypto/openssl/md5/%.c
+       $(call compile, crypto crypto/openssl crypto/openssl/md5,  $<, $@ )
+
+build/crypto/openssl/sha/%.o  : crypto/openssl/sha/%.c
+       $(call compile, crypto crypto/openssl crypto/openssl/sha,  $<, $@ )
+
+
+build/crypto/openssl/%.o  : crypto/openssl/%.c
+       $(call compile, crypto crypto/openssl,  $<, $@ )
+
+
+build/crypto/%.o : crypto/%.c
+       $(call compile, crypto, $<, $@)
+
+build/ssh/openssh/openbsd-compat/%.o  : ssh/openssh/openbsd-compat/%.c
+       $(call compile, ssh ssh/openssh ssh/openssh/openbsd-compat,  $<, $@ )
+
+build/ssh/openssh/%.o  : ssh/openssh/%.c
+       $(call compile, ssh ssh/openssh crypto,  $<, $@ )
+
+build/ssh/%.o  : ssh/%.c
+       $(call compile, ssh crypto,  $<, $@ )
+
+
+build/data/%.o  : data/%.c
+       $(call compile, data,  $<, $@ )
+
+
+build/forms/%.o  : forms/%.c
+       $(call compile, forms,  $<, $@ )
+
+
+build/util/%.o  : util/%.c
+       $(call compile, ,  $<, $@ )
+
+
+build/vt100/%.o  : vt100/%.c
+       $(call compile, vt100 vt100/palm,  $<, $@ )
+
+
+build/%.o  : %.c
+       $(call compile, ,  $<, $@ )
+
+
+clean: 
+       make -C arm clean
+       rm -rf build
+       rm -f $(PEAL_FILES)
+       rm -f *~ *.grc  *.bin *.o *.prc pssh pssh-sections.ld pssh-sections.s
+       rm -f $(addsuffix *~,rsrc/ crypto/openssl/objects/ $(sort $(dir $(SRCS))))
+       rm -f $(addsuffix .gdb_history,rsrc/ crypto/openssl/objects/ $(sort $(dir $(SRCS))))
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..6f3c99c
--- /dev/null
+++ b/README
@@ -0,0 +1,94 @@
+README
+
+pssh is a free, open-source SSH 2 client for Palm OS. 
+http://www.sealiesoftware.com/pssh/
+
+WARNING: pssh is substantially UNTESTED and probably INSECURE. 
+Do not use it for security-critical applications.
+
+
+COMPATIBILITY
+
+Requires:
+Palm OS 5.x.
+an ARM-compatible CPU
+a network connection
+
+pssh has only been tested on a Tungsten C. It may not work on other devices.
+pssh is EVEN MORE INSECURE on devices other than the Tungsten C because 
+it does not use device-specific random number sources. Contact the 
+author (gparker-pssh@sealiesoftware.com) if you are willing to test some code.
+
+
+CAPABILITIES
+
+Protocol: SSH 2
+Authentication: password, public-key (RSA and DSA), keyboard-interactive
+Host key authentication: RSA, DSA
+Ciphers: 3DES-CBC, AES128-CBC
+MAC: HMAC-SHA1
+Compression: none, zlib
+See README.publickeys for instructions for using public-key authentication
+
+Terminal emulation: VT100/VT220/xterm
+Configurable font colors and sizes
+On-screen keyboard
+Configurable scrollback length
+Support for high-resolution screens (320x320 and larger)
+
+
+NON-CAPABILITIES
+
+Protocol: SSH 1 will never be supported
+Ciphers: no other ciphers are currently planned
+Terminal emulation: improvements are expected in the future
+
+
+LICENSE
+
+pssh and its components are free software released under various 
+licenses, mostly BSD-like. See README.licenses for more details.
+pssh MAY NOT be distributed under the GNU GPL. This is a restriction 
+in the SSLeay license.
+
+pssh's source code is available at http://www.sealiesoftware.com/pssh/
+
+
+AUTHORS
+
+pssh is written by Greg Parker.
+http://www.sealiesoftware.com/pssh/
+
+pssh incorporates code from several sources: 
+
+Cryptographic algorithms (directories crypto/openssl and arm/aes)
+and bignum library (directory arm/bn)
+   Derived from OpenSSL 0.9.7c.
+   http://www.openssl.org/
+   Ported to Palm OS by Greg Parker.
+
+SHA256 algorithm (directory crypto/sha2)
+   Written by Aaron Gifford
+   http://www.aarongifford.com/computers/sha.html
+   Ported to Palm OS by Greg Parker.
+
+Fortuna random number generator (directory crypto/rand)
+   Algorithm by Niels Ferguson and Bruce Schneier
+   in "Practical Cryptography".
+   Implemented by Greg Parker.
+
+SSH 2 protocol (directory ssh/openssh)
+   Derived from OpenSSH 3.7.1p2.
+   http://www.openssh.org/
+   Ported to Palm OS by Greg Parker.
+   Substantial parts of pssh's SSH2 protocol support (directory ssh) 
+   were written by Greg Parker.
+
+Terminal emulator (directory vt100)
+   Derived from PuTTY 0.54b.
+   http://www.chiark.greenend.org.uk/~sgtatham/putty/
+   Ported to Palm OS by Greg Parker.
+
+Screen resizing (forms/resize.c and forms/DIA.c)
+   Written by Alex Pruss
+   http://www.sourceforge.net/projects/palmresize/
diff --git a/README.code b/README.code
new file mode 100644 (file)
index 0000000..b27e53f
--- /dev/null
@@ -0,0 +1,109 @@
+README.code
+Info for hackers of pssh.
+
+
+## Compilation ##
+
+pssh is built using prc-tools, PilRC 3.0, and Peal on Mac OS X. 
+pssh can probably be built on any platform supported by prc-tools. 
+It probably cannot be built with CodeWarrior without significant porting 
+work (multi-segment support, in particular).
+
+pssh uses prc-tools to compile code. 
+    http://prc-tools.sourceforge.net/
+    http://www.zenonez.com/prctoolsx/  (binaries for Mac OS X)
+
+pssh uses PilRC 3.0 or later to build resources. 
+    http://sourceforge.net/projects/pilrc/
+    http://zenonez.com/prctoolsx/PilRC-3.1.dmg.gz (binaries for Mac OS X)
+
+pssh requires Peal to link and load ARM code.
+    http://www.sealiesoftware.com/peal/
+
+pssh requires libc.a and libgcc.a built as Thumb code with ARM 
+interworking enabled. Current versions of prc-tools do not provide 
+them. Instructions for building them from prc-tools 2.3 are available 
+on request (gparker-pssh@sealiesoftware.com), or use:
+    http://www.sealiesoftware.com/pssh/dist/libc.a
+    http://www.sealiesoftware.com/pssh/dist/libgcc.a
+
+
+To build:
+
+1. Set up your directories as follows:
+
+   libc.a
+   libgcc.a
+   peal/
+       ...
+   pssh-source/
+       README.code
+       ...
+
+2. In directory peal/postlink, run `make` if you have not already.
+   This builds Peal's postlinker.
+
+3. In directory pssh-source, run `make`. This builds pssh's m68K 
+   code, ARM code, and resources, generating pssh.prc.
+
+If you see build messages like "warning: interworking not enabled", 
+"thumb call to arm", and "internal error: dangerous error", 
+then your libc.a or libgcc.a isn't set up right. pssh.prc will crash 
+if you try to run it.
+
+
+WARNING: pssh's Makefile does NOT handle all dependencies like 
+changed .h files. Use `make clean` as necessary.
+
+
+## Directories ##
+Note: some of these directories have components under the arm/ directory.
+
+crypto: Basic cryptographic algorithms
+crypto/openssl: Cryptography algorithms from OpenSSL
+crypto/rand: Fortuna random number generator
+crypto/sha2: SHA256 algorithm by Aaron Gifford
+
+data: Manipulation and display of data in Palm OS databases
+
+forms: Event handlers and other form code
+
+rsrc: Palm OS resource descriptions and font data
+rsrc/pssh.rsrc: Palm OS Constructor mockups of some forms (not actually used)
+
+ssh: SSH 2 protocol
+ssh/openssh: SSH 2 code from OpenSSH
+
+util: Miscellaneous utility code and headers
+util/oem: Headers from various SDKs like palmOne and Sony
+
+vt100: Terminal emulator from PuTTY
+
+
+## SSH 2 protocol code ##
+
+Palm OS programs are event-driven. OpenSSH's ssh client is not. 
+To prevent blocking in socket I/O, much of OpenSSH's protocol code 
+was rewritten as follows.
+
+ssh.c
+The highest-level wrapper around an SSH 2 session and its associated 
+terminal emulator. All manipulation from outside goes through here.
+
+packetizer.c
+SSH 2 binary packet protocol. Handles socket I/O, version check, 
+encryption, decryption, MAC check, padding. Sends unencrypted packet 
+payloads to the transport layer. 
+
+transport.c
+SSH 2 transport protocol. Handles algorithm negotiation and key exchange. 
+Sends other data to the connection layer.
+
+connection.c
+SSH 2 connection protocol. Handles authentication and stream data. 
+Sends stream data to the terminal emulator.
+
+The packetizer, transport, and connection layers are each a state machine 
+whose states are generally defined by blocking network operations. This 
+allows program control to return to the main event loop when waiting for 
+packets to arrive. 
diff --git a/README.licenses b/README.licenses
new file mode 100644 (file)
index 0000000..188f13a
--- /dev/null
@@ -0,0 +1,321 @@
+README.licenses
+Licenses for pssh's code
+
+pssh's code is derived from many sources. Each of the following licenses 
+covers some part of pssh's code. 
+
+Note that the SSLeay license expressly prohibits redistribution under the 
+GNU Public License (GPL). Therefore, pssh MAY NOT be redistributed under 
+the GPL without replacement of the SSLeay-licensed code.
+
+#############
+
+pssh License (Greg Parker)
+
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+
+#############
+
+OpenSSL License
+
+ * Copyright (c) 1998-2003 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.
+
+#############
+
+SSLeay License (Eric Young)
+
+ * 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.]
+
+#############
+
+SSH License (Tatu Ylonen)
+
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+
+#############
+
+OpenSSH License (Markus Friedl and Niels Provos)
+
+ * Copyright (c) 1999-2000 Niels Provos.  All rights reserved.
+ * Copyright (c) 2000-2003 Markus Friedl.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+
+#############
+
+base64 License (Internet Software Consortium and IBM)
+
+ * Copyright (c) 1996 by 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.
+
+
+ * Portions Copyright (c) 1995 by International Business Machines, Inc.
+ *
+ * International Business Machines, Inc. (hereinafter called IBM) grants
+ * permission under its copyrights to use, copy, modify, and distribute this
+ * Software with or without fee, provided that the above copyright notice and
+ * all paragraphs of this notice appear in all copies, and that the name of IBM
+ * not be used in connection with the marketing of any product incorporating
+ * the Software or modifications thereof, without specific, written prior
+ * permission.
+ *
+ * To the extent it has a right to do so, IBM grants an immunity from suit
+ * under its patents, if any, for the use, sale or manufacture of products to
+ * the extent that such products are used for performing Domain Name System
+ * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
+ * granted for any product per se or for any other function of any product.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+#############
+
+PuTTY Licence
+
+PuTTY is copyright 1997-2004 Simon Tatham.
+
+Portions copyright Robert de Bath, Joris van Rantwijk, Delian
+Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
+Justin Bradford, Ben Harris, and CORE SDI S.A.
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation files
+(the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#############
+
+SHA2 License (Aaron Gifford)
+
+ * Copyright (c) 2000-2001, Aaron D. Gifford
+ * 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. Neither the name of the copyright holder nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 CONTRIBUTOR(S) 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.
+
+#############
+
+PalmResize License (Alex Pruss)
+
+Copyright (c) 2004, Alexander R. Pruss
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without 
+modification, are permitted provided that the following conditions are met:
+
+    Redistributions of source code must retain the above copyright notice, 
+    this list of conditions and the following disclaimer.
+
+    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.
+
+    Neither the name of the PalmResize Project nor the names of its
+    contributors may be used to endorse or promote products derived from this
+    software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER 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.
diff --git a/README.publickeys b/README.publickeys
new file mode 100644 (file)
index 0000000..ccb9159
--- /dev/null
@@ -0,0 +1,97 @@
+README.publickeys
+How to use SSH 2 public-key authentication
+
+
+## Support ##
+
+pssh supports public-key authentication using RSA or DSA keys. 
+The private key data stored on the handheld may be encrypted 
+using a passphrase, or it may be passphrase-less. (See the 
+Security Note below.)
+
+pssh cannot generate keypairs itself. pssh cannot currently 
+change the passphrase of an existing key pair. 
+
+
+## Security Note ##
+
+Passphrase-less key pairs are more convenient (you don't have to 
+type any password when logging in), but they are MORE INSECURE than 
+passphrase-protected key pairs. Specifically, any person or program 
+with access to your handheld or its Backup data can easily steal your 
+private key and use it to connect as you. With passphrase-protected 
+keys, a stolen key pair is not useful unless the attacker also can 
+steal or guess your passphrase.
+
+
+## Authentication procedure ##
+
+When you connect to a server, pssh attempts to authenticate using 
+any available public keys before prompting for an ordinary password. 
+The procedure is as follows:
+1. pssh determines whether the server supports public-key authentication. 
+   If the server does not, public-key authentication is skipped.
+2. pssh attempts to authenticate using every passphrase-less key 
+   available. 
+3. pssh asks the server whether any of the available passphrase-
+   protected keys would be accepted for authentication.
+4. pssh asks you for the passphrase for a passphrase-protected 
+   key. If multiple passphrase-protected keys are acceptable on 
+   the server, pssh allows you to choose which one to use.
+5. If all public-key authentication attempts fail, pssh prompts you 
+   for an ordinary (non-public-key) password.
+
+It's possible that step #2 will cause trouble if you have many 
+passphrase-less keys and are attempting to connect to a paranoid 
+server that rejects the connection after a small number of failed 
+public-key authentication attempts. There is currently no workaround 
+for this; contact the author of pssh if you encounter this problem.
+
+
+## Key import ##
+
+pssh does not generate key pairs itself. Instead, key pairs must be 
+imported from outside. Currently pssh can import OpenSSH-formatted 
+private key files via Memo Pad memos. A memo containing a key must 
+start with a one-line name, followed by the OpenSSH private key data. 
+
+With OpenSSH on Unix, these key files can be generated by `ssh-keygen`. 
+PuTTY on Windows can generate keys and export them in OpenSSH format.
+
+Example Memo Pad memo (a passphrase-less RSA key):
+
+   This first line will be pssh's name for the key.
+   -----BEGIN RSA PRIVATE KEY-----
+   MIICWwIBAAKBgQCuWCQLxeyBlv1hu/rOWRYe8tBJ3HUQ8NEXbEgCm/4bmZaJ1WbS
+   0HTR3KXilKHp4rsBfWVkSNnn3oezo6ik6gCiR/5sijGSJnQti9yMu/lFZ3gVRO8A
+   ngus2CnQLmbGfZj/XnkP6f051hhyP0pO7kwZkaWWpuNTdHupFDVb50zNaQIBIwKB
+   gHeM5YRqdko7pm7nTOVEZvCmgDKlzJ3m9cbrKhBq92NiANOLBK3QxSIw5sdBWRVo
+   Rbfg9RGRCnMcP8ujbFPTqKioF46iMjw9AKbujDF8UrqAztIBOJKEunNHyE8QQovZ
+   linugtlkybgFLBIdEdFNG7ngtSfgui/SEFusdfkyngkSYgfygNUfsuKFNuynkfus
+   5j87FydxkPHqOe5UYXa4nhvUXvXnahw2E1uvQ4LRkLxek+0oOdTq4or5D5LNaVIM
+   zIiPXwJBAMFQZOPb+zL4Jsd4fqsWulR4XBzf62KNcFiu+ZiUkNdC1WjJH3MUWpov
+   OnfU26P9IIgOAoueyRf5E1hRZkvKADcCQQCyG0rslk/EAMXD0jXsIiZFD8yjA8NR
+   QtNhIRITkc+2+DYtSPaD9kVf9zPzT3wo+MdCjk7MBM7C3vY7TeydyG6ZAkAQkdzD
+   EtsEXmm5U3iSUme+GPHz2K3Gnmi3JPDSkGQvtUV+ApxLsUmYL+8RlebwzI3ChNul
+   kURvxORmp+QyYcWBAkEArW8tp3XMT9vHDncfiW8sxOp/IYhoyUef7QrSaR4DsitE
+   okRGOSIIpGRAPVOpZvVpAGuFdeYLiYC9I90TZSFx0Q==
+   -----END RSA PRIVATE KEY-----
+
+Example (a passphrase-protected DSA key):
+
+   me@ssh-server.example.com's key
+   -----BEGIN DSA PRIVATE KEY-----
+   Proc-Type: 4,ENCRYPTED
+   DEK-Info: DES-EDE3-CBC,D0FCEE0E84F8608C
+   
+   hYNAqkX7115lYiEpcBEE6i/gGKllDxapL/iNpx93Aj+fofksrlTRbbKEdLBOVyuf
+   2OMdzuQ56Wk96YE1gWHEdbK9QxyXL0rBQL5jMFJ1svKzRAgIo7VYPrSem+YjkC9u
+   GQex2zIwvbBh1CyQqtezQlxD2nmdPMEicvTbo0t14SoedXPUNI6wMsv/64mGbDfd
+   r0FYBXOyNn1yglNbkAOUMusrUfdzEa7oR1VG9pugXYzdDRx+bspJ9xm+4AZD2cwu
+   WsJN21U5ezJMQk763ImuFkyzw5TXKY1ZFUI22CWUrJpB4j87NScWUecFgfUGFYPn
+   nXonMAPNi65Kdr4ynx5GsNgxhoOWuWL+Qz0B2PPYS7dmJUdBmc6F71qquASsnpgu
+   sSLeLTm/GUt8gFVFc5WdURWQsIpt42dZx8/FXgVblZ2FSSuoOVEqgn9/ENh2Hz1S
+   Ft6fVnpSPyx11gqZlKYvGkHAyrf6Fr2+cnDBoK0AZ3wf8b5DYekEKmCKQFlAKBYs
+   YSeup9p1Qk3c9qxyOyWMM86/jqWbds3KZg7AfCJgUT/aAAaATHZKZWU2m/RINS/y
+   UoPPL7evby2FTjkW82Atrg==
+   -----END DSA PRIVATE KEY-----
diff --git a/arm/Makefile b/arm/Makefile
new file mode 100644 (file)
index 0000000..4cd439d
--- /dev/null
@@ -0,0 +1,146 @@
+# pssh ARM makefile
+
+all: armc.ro
+
+
+OPTIMIZATION = -Os
+
+WARNINGS = -W -Wall -Wmissing-declarations -Wmissing-prototypes -Wpointer-arith -Wno-multichar
+
+# libc and libgcc (must be either ARM with thumb-interwork, or Thumb)
+LIBC = ../../libc.a
+LIBGCC = ../../libgcc.a
+
+# Peal
+PEAL = ../../peal
+PEAL_SRCS = util/pealstub.c
+PEAL_FILES = util/pealstub.c util/pealstub.h
+util/pealstub.c: $(PEAL)/arm/pealstub.c
+       cp $(PEAL)/arm/pealstub.c util/pealstub.c
+util/pealstub.h: $(PEAL)/arm/pealstub.h
+       cp $(PEAL)/arm/pealstub.h util/pealstub.h
+
+# OpenSSL
+BN_SRCS = bn/bn_armcalls.c bn/bn_add.c bn/bn_asm.c bn/bn_ctx.c bn/bn_div.c bn/bn_exp.c bn/bn_gcd.c bn/bn_lib.c bn/bn_mod.c bn/bn_mont.c bn/bn_mul.c bn/bn_print.c bn/bn_rand.c bn/bn_recp.c bn/bn_shift.c bn/bn_sqr.c bn/bn_word.c
+AES_SRCS = aes/aes_armcalls.c aes/aes_cbc.c aes/aes_core.c aes/aes_tables.c
+
+OPENSSL_SRCS = $(addprefix openssl/, \
+       $(BN_SRCS) $(AES_SRCS) \
+)
+
+# Non-OpenSSL crypto (sha2, Fortuna)
+FORTUNA_SRCS = fortuna/fortuna.c fortuna/fortuna_acc.c fortuna/fortuna_gen.c
+SHA2_SRCS = sha2/sha2.c
+
+# crypto (OpenSSL and otherwise)
+CRYPTO_SRCS = $(addprefix crypto/, \
+       rand.c rand_armcalls.c $(FORTUNA_SRCS) $(OPENSSL_SRCS) $(SHA2_SRCS) \
+)
+
+# OpenSSH
+OPENSSH_SRCS = $(addprefix openssh/, \
+       openbsd-compat/bsd-snprintf.c \
+)
+
+# ssh (OpenSSH and putty and custom)
+SSH_SRCS = $(addprefix ssh/, \
+       ssh.c sshzlib.c sshzlib_armcalls.c $(OPENSSH_SRCS) \
+)
+
+# util
+UTIL_SRCS = $(addprefix util/, \
+       PalmOS.c stdlib.c xmalloc.c \
+)
+
+# vt100 (PuTTY)
+VT100_SRCS = $(addprefix vt100/, \
+       tree234.c wcwidth.c misc.c \
+       palm/palmprint.c palm/palmucs.c palm/palmwindow.c \
+       vt100.c vt100_armcalls.c terminal.c \
+)
+
+# Palm data
+DATA_SRCS = data/prefs.c
+
+# Everything ARM
+C_SRCS = $(VT100_SRCS) $(DATA_SRCS) $(UTIL_SRCS) $(CRYPTO_SRCS) $(SSH_SRCS) $(PEAL_SRCS)
+ASM_SRCS = crypto/rand_time.S
+SRCS = $(C_SRCS) $(ASM_SRCS)
+
+OBJECTS = $(addprefix build/,$(C_SRCS:.c=.o) $(ASM_SRCS:.S=.o))
+
+OBJDIRS = $(addprefix build/,$(sort $(dir $(SRCS) )))
+
+armc.ro: pssh-arm-prelink export-list
+       $(PEAL)/postlink/peal-postlink -K export-list -s 1000 -v -o armc.ro pssh-arm-prelink
+       $(PEAL)/postlink/peal-postlink -K export-list -v -o armc.unsplit pssh-arm-prelink
+
+$(OBJDIRS): 
+       mkdir -p $@
+
+pssh-arm-prelink: $(PEAL_FILES) $(OBJDIRS) $(OBJECTS) $(LIBC) $(LIBGCC)
+       arm-palmos-gcc -mthumb -nostartfiles -nostdlib  -Wl,--split-by-file=64000 -Wl,--emit-relocs $(OBJECTS) $(LIBC) $(LIBGCC) -o pssh-arm-prelink
+
+
+define compile
+       arm-palmos-gcc -fPIC -mthumb -msingle-pic-base $(OPTIMIZATION) $(WARNINGS) \
+          -I. -Iutil $(addprefix -I,$1) \
+          -c $2 -o $3
+endef
+
+
+
+build/crypto/sha2/%.o  : crypto/sha2/%.c
+       $(call compile, crypto crypto/sha2,  $<, $@ )
+
+build/crypto/fortuna/%.o  : crypto/fortuna/%.c
+       $(call compile, crypto crypto/fortuna,  $<, $@ )
+
+build/crypto/rand_time.o : crypto/rand_time.S
+       $(call compile, crypto, $<, $@)
+
+build/crypto/rand.o : crypto/rand.c
+       $(call compile, crypto, $<, $@)
+
+build/crypto/%.o : crypto/%.c
+       $(call compile, crypto, $<, $@)
+
+
+build/ssh/openssh/openbsd-compat/%.o  : ssh/openssh/openbsd-compat/%.c
+       $(call compile, ssh ssh/openssh ssh/openssh/openbsd-compat,  $<, $@ )
+
+build/ssh/openssh/%.o  : ssh/openssh/%.c
+       $(call compile, ssh ssh/openssh crypto,  $<, $@ )
+
+build/ssh/%.o  : ssh/%.c
+       $(call compile, ssh crypto vt100,  $<, $@ )
+
+
+build/data/%.o  : data/%.c
+       $(call compile, data,  $<, $@ )
+
+
+build/util/pealstub.o  : util/pealstub.c
+       $(call compile, ,  $<, $@ -mcallee-super-interworking)
+
+build/util/%.o  : util/%.c
+       $(call compile, ,  $<, $@ )
+
+
+build/vt100/%.o  : vt100/%.c
+       $(call compile, vt100 vt100/palm,  $<, $@ )
+
+
+build/%.o  : %.c
+       $(call compile, ,  $<, $@ )
+
+
+clean: 
+       rm -rf build
+       rm -f $(PEAL_FILES)
+       rm -f *~ *.grc  *.s *.i *.bin *.o *.ro *.prc pssh-arm pssh-arm-prelink armc.unsplit
+       rm -f $(addsuffix *~,$(sort $(dir $(SRCS))))
+       rm -f $(addsuffix .gdb_history,$(sort $(dir $(SRCS))))
+
+.PHONY=all clean
+.SUFFIXES=
diff --git a/arm/crypto/fortuna/fortuna.c b/arm/crypto/fortuna/fortuna.c
new file mode 100644 (file)
index 0000000..457c9eb
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+  fortuna_accumulator.c
+  Fortuna cryptographic PRNG
+  As seen in Ferguson and Schneier "Practical Cryptography"
+  Greg Parker     gparker@cs.stanford.edu     2003-11-16
+*/
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "assert.h"
+#include "fortuna.h"
+#include "fortuna_locl.h"
+
+
+typedef struct fortuna_t {
+    generator_t gen;
+    accumulator_t acc;
+    uint32_t reseedCount;
+    uint32_t lastReseedInTicks;
+    uint32_t minReseedDelayInTicks;
+} fortuna_t;
+
+
+fortuna_t *fortuna_create(void)
+{
+    fortuna_t *f;
+    assert(AES_BLOCK_SIZE * 2 == SHA256_DIGEST_LENGTH);
+    
+    f = nonarena_malloc(sizeof(fortuna_t));
+    if (!f) return NULL;
+
+    generator_init(&f->gen);
+    accumulator_init(&f->acc);
+
+    f->reseedCount = 0;
+    f->lastReseedInTicks = 0;
+    f->minReseedDelayInTicks = SysTicksPerSecond() / 10; // approx 0.1 sec
+
+    return f;
+}
+
+void fortuna_get_bytes(fortuna_t *f, uint8_t *outBytes, unsigned int byteCount)
+{
+    int reseeded = 0;
+    fortuna_log("fortuna: fortuna_get_bytes");
+
+    // Reseed periodically:
+    // * always reseed for the first readout
+    // * otherwise, reseed only if pool[0] has enough data 
+    //   and never more often than 0.1 seconds.
+    if (f->reseedCount == 0  ||  
+        (accumulator_pool_is_useful(&f->acc, 0)  &&  
+         TimGetTicks() >= f->lastReseedInTicks + f->minReseedDelayInTicks)) 
+    {
+        uint8_t newseed[POOL_COUNT * KEY_BYTES];
+        uint8_t *dst = newseed;
+        uint8_t i;
+        uint32_t mask;
+        f->reseedCount++;
+
+        // Include pool i every 2^i reseeds
+        // Include pool i if (mask & reseedCount) == 0
+        // First reseed (reseedCount == 1) uses only pool 0.
+        // Pool 0 is included every reseed.
+        mask = 0;
+        for (i = 0; i < POOL_COUNT; i++) {
+            if ((f->reseedCount & mask) != 0) break;
+            fortuna_log("fortuna: extracting pool %d", i);
+            accumulator_extract_pool(&f->acc, i, dst);
+            dst += KEY_BYTES;
+            mask = (mask << 1) | 1;
+        }
+
+        // Bytes [newseed..dst) are ready to be fed into the generator
+        fortuna_log("fortuna: reseeding");
+        generator_reseed(&f->gen, newseed, dst - newseed);
+        reseeded = 1;
+    }
+
+    fortuna_log("fortuna: generating %d bytes (r %d)", byteCount, reseeded);
+    generator_emit_bytes(&f->gen, outBytes, byteCount);
+    fortuna_log("fortuna: get_bytes done");
+}
+
+
+void fortuna_put_bytes(fortuna_t *f, uint8_t sourceID, uint8_t poolID, uint8_t *inBytes, unsigned int byteCount)
+{
+    accumulator_add_bytes(&f->acc, sourceID, poolID, inBytes, byteCount);
+}
diff --git a/arm/crypto/fortuna/fortuna.h b/arm/crypto/fortuna/fortuna.h
new file mode 100644 (file)
index 0000000..b608deb
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+  fortuna.c
+  Fortuna cryptographic PRNG
+  As seen in Ferguson and Schneier "Practical Cryptography"
+  Greg Parker     gparker@cs.stanford.edu     2003-11-16
+*/
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef FORTUNA_H
+#define FORTUNA_H
+
+#include "includes.h"
+
+struct fortuna_t;
+
+struct fortuna_t *fortuna_create(void);
+void fortuna_get_bytes(struct fortuna_t *f, uint8_t *outBytes, unsigned int byteCount);
+void fortuna_put_bytes(struct fortuna_t *f, uint8_t sourceID, uint8_t poolID, uint8_t *inBytes, unsigned int byteCount);
+
+
+#endif
diff --git a/arm/crypto/fortuna/fortuna_acc.c b/arm/crypto/fortuna/fortuna_acc.c
new file mode 100644 (file)
index 0000000..35d2ca0
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+  fortuna_accumulator.c
+  Fortuna cryptographic PRNG
+  As seen in Ferguson and Schneier "Practical Cryptography"
+  Greg Parker     gparker@cs.stanford.edu     2003-11-16
+*/
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+
+#include "fortuna.h"
+#include "fortuna_locl.h"
+
+
+void accumulator_init(accumulator_t *a)
+{
+    int i;
+    for (i = 0; i < POOL_COUNT; i++) {
+        pool_t *pool = &a->pools[i];
+        SHA256_Init(&pool->hash);
+        pool->bytesBeforeUseful = MIN_POOL_BYTES;
+    }
+}
+
+
+void accumulator_add_bytes(accumulator_t *a, uint8_t sourceID, 
+                           uint8_t poolID, uint8_t *data, uint8_t len)
+{
+    pool_t *pool = &a->pools[poolID % POOL_COUNT];
+    
+    // Record length of addition to this pool
+    if (pool->bytesBeforeUseful > 0) {
+        if (pool->bytesBeforeUseful > len) {
+            pool->bytesBeforeUseful -= len;
+        } else {
+            pool->bytesBeforeUseful = 0;
+        }
+    }
+
+    // Add to the pool: sourceID, len, data
+    SHA256_Update(&pool->hash, &sourceID, sizeof(sourceID));
+    SHA256_Update(&pool->hash, &len, sizeof(len));
+    SHA256_Update(&pool->hash, data, len);
+}
+
+
+int accumulator_pool_is_useful(accumulator_t *a, uint8_t poolID)
+{
+    return (0 == a->pools[poolID % POOL_COUNT].bytesBeforeUseful);
+}
+
+
+void accumulator_extract_pool(accumulator_t *a, uint8_t poolID, 
+                              uint8_t *outBytes)
+{
+    pool_t *pool = &a->pools[poolID % POOL_COUNT];
+    
+    // Finish current hash
+    SHA256_Final(outBytes, &pool->hash);
+    
+    // Re-hash final pool content into output
+    SHA256_Init(&pool->hash);
+    SHA256_Update(&pool->hash, outBytes, POOL_BYTES);
+    SHA256_Final(outBytes, &pool->hash);
+
+    // Start new hash for pool
+    SHA256_Init(&pool->hash);
+    pool->bytesBeforeUseful = MIN_POOL_BYTES;
+}
diff --git a/arm/crypto/fortuna/fortuna_gen.c b/arm/crypto/fortuna/fortuna_gen.c
new file mode 100644 (file)
index 0000000..33436a3
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+  fortuna.c
+  Fortuna cryptographic PRNG
+  As seen in Ferguson and Schneier "Practical Cryptography"
+  Greg Parker     gparker@cs.stanford.edu     2003-11-16
+*/
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "assert.h"
+#include "fortuna.h"
+#include "fortuna_locl.h"
+
+
+static void ctr_inc(uint8_t *ctr);
+static void generator_set_key(generator_t *g, uint8_t *newkey);
+static void generator_emit_blocks(generator_t *g, uint8_t *outData, unsigned int blockCount);
+
+
+static void ctr_inc(uint8_t *ctr)
+{
+    int carry = 0;
+    uint32_t *cp = (uint32_t *)ctr;
+
+    // Process in 4 32-byte chunks
+#define inc(c) \
+    if (c == 0xffffffffUL) { \
+        c = carry; \
+        carry = 1; \
+    } else { \
+        c += 1; \
+    } \
+
+    inc(cp[0]);
+    inc(cp[1]);
+    inc(cp[2]);
+    inc(cp[3]);
+}
+
+
+void generator_init(generator_t *g)
+{
+    memset(g, 0, sizeof(*g));
+}
+
+
+static void generator_set_key(generator_t *g, uint8_t *newkey)
+{
+    fortuna_log("gen_set_key");
+    memcpy(g->key, newkey, KEY_BYTES);
+    AES_set_encrypt_key(g->key, 128, &g->aes_key);
+}
+
+void generator_reseed(generator_t *g, uint8_t *data, unsigned int len)
+{
+    SHA256_CTX ctx;
+    uint8_t newkey[KEY_BYTES];
+
+    // Reseed: 
+    // g->key = SHA256(SHA256(g->key || data))
+    // g->ctr++
+
+    // First round: newkey = SHA256(g->key || data)
+    SHA256_Init(&ctx);
+    SHA256_Update(&ctx, g->key, KEY_BYTES);
+    SHA256_Update(&ctx, data, len);
+    SHA256_Final(newkey, &ctx);
+
+    // Second round: newkey = SHA256(newkey)
+    SHA256_Init(&ctx);
+    SHA256_Update(&ctx, newkey, KEY_BYTES);
+    SHA256_Final(newkey, &ctx);
+
+    // Install the new key
+    generator_set_key(g, newkey);
+
+    // Increment counter
+    ctr_inc(g->ctr);
+}
+
+
+// outData may overlap g->key
+// outData may NOT overlap g->ctr
+static void generator_emit_blocks(generator_t *g, 
+                                  uint8_t *outData, unsigned int blockCount)
+{
+    unsigned int i;
+    uint8_t *dst = outData;
+
+    // Repeatedly encrypt plaintext g->ctr with key g->key (aka g->aes_key), 
+    // incrementing the counter for each block
+
+    fortuna_log("gen_emit_blocks (%d)", blockCount);
+
+    for (i = 0; i < blockCount; i++) {
+        AES_encrypt(g->ctr, dst, &g->aes_key);
+        ctr_inc(g->ctr);
+        dst += BLOCK_BYTES;
+    }
+}
+
+
+void generator_emit_bytes(generator_t *g, uint8_t *outBytes, unsigned int byteCount)
+{
+    // round up to block boundary
+    unsigned int wholeBlockCount;
+    unsigned int incompleteBlockBytes;
+    uint8_t blockbuf[KEY_BYTES];
+    uint8_t *dst = outBytes;
+
+    fortuna_log("gen_emit_bytes (%d)", byteCount);
+
+    if (byteCount == 0) return;
+    
+    // F&S use 2^20 upper bound for cryptographic reasons, 
+    // though anything over a few KB is probably insane for pssh
+    assert(byteCount < 1048576); // 2^20
+
+    incompleteBlockBytes = byteCount % BLOCK_BYTES;
+    wholeBlockCount = byteCount / BLOCK_BYTES;
+
+    // Generate all whole blocks (i.e. everything but maybe the last)
+    generator_emit_blocks(g, dst, wholeBlockCount);
+    dst += wholeBlockCount * BLOCK_BYTES;
+
+    // Generate another block if we need a partial block at the end
+    if (incompleteBlockBytes > 0) {
+        generator_emit_blocks(g, blockbuf, 1);
+        memcpy(dst, blockbuf, incompleteBlockBytes);
+    }
+
+    // Generate two blocks for the new key
+    generator_emit_blocks(g, blockbuf, 2);
+    generator_set_key(g, blockbuf);
+}
+
+
+
+
+
+
diff --git a/arm/crypto/fortuna/fortuna_locl.h b/arm/crypto/fortuna/fortuna_locl.h
new file mode 100644 (file)
index 0000000..5207ad4
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+  fortuna.c
+  Fortuna cryptographic PRNG
+  As seen in Ferguson and Schneier "Practical Cryptography"
+  Greg Parker     gparker@cs.stanford.edu     2003-11-16
+*/
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef FORTUNA_LOCL_H
+#define FORTUNA_LOCL_H
+
+#include "includes.h"
+#include "crypto/openssl/aes/aes.h"
+#include "crypto/sha2/sha2.h"
+
+
+#define KEY_BYTES   (AES_BLOCK_SIZE*2) // Two AES blocks; one SHA256 digest
+#define CTR_BYTES   AES_BLOCK_SIZE
+#define BLOCK_BYTES AES_BLOCK_SIZE
+
+
+// accumulator
+
+#define POOL_BYTES SHA256_DIGEST_LENGTH
+#define POOL_COUNT 32
+#define MIN_POOL_BYTES 64
+
+typedef struct {
+    SHA256_CTX hash;
+    unsigned int bytesBeforeUseful;
+} pool_t;
+
+typedef struct {
+    pool_t pools[POOL_COUNT];
+} accumulator_t;
+
+void accumulator_init(accumulator_t *a);
+void accumulator_add_bytes(accumulator_t *a, uint8_t sourceID, uint8_t poolID, uint8_t *data, uint8_t len);
+int accumulator_pool_is_useful(accumulator_t *a, uint8_t poolID);
+void accumulator_extract_pool(accumulator_t *a, uint8_t poolID, uint8_t *outBytes);
+
+
+// generator
+
+typedef struct {
+    AES_KEY aes_key;
+    uint8_t key[KEY_BYTES];
+    uint8_t ctr[CTR_BYTES];
+} generator_t;
+
+void generator_init(generator_t *g);
+void generator_reseed(generator_t *g, uint8_t *data, unsigned int len);
+void generator_emit_bytes(generator_t *g, uint8_t *outBytes, unsigned int byteCount);
+
+#endif
diff --git a/arm/crypto/openssl/aes/CVS/Entries b/arm/crypto/openssl/aes/CVS/Entries
new file mode 100644 (file)
index 0000000..66f6e9a
--- /dev/null
@@ -0,0 +1,10 @@
+/aes.h/1.2/Wed Nov 24 21:59:33 2004//Tpssh-2005_06_23
+/aes_armcalls.c/1.2/Tue Jul 20 10:45:33 2004//Tpssh-2005_06_23
+/aes_cbc.c/1.1/Mon Jul 19 10:00:16 2004//Tpssh-2005_06_23
+/aes_core.c/1.2/Tue Sep 14 04:23:57 2004//Tpssh-2005_06_23
+/aes_includes.h/1.2/Tue Jul 20 10:45:33 2004//Tpssh-2005_06_23
+/aes_internal.h/1.3/Wed Aug 25 07:26:37 2004//Tpssh-2005_06_23
+/aes_locl.h/1.1/Mon Jul 19 10:00:16 2004//Tpssh-2005_06_23
+/aes_tables.c/1.1/Tue Sep 14 04:23:57 2004//Tpssh-2005_06_23
+/aes_tables.h/1.1/Tue Sep 14 04:23:57 2004//Tpssh-2005_06_23
+D
diff --git a/arm/crypto/openssl/aes/CVS/Repository b/arm/crypto/openssl/aes/CVS/Repository
new file mode 100644 (file)
index 0000000..8964951
--- /dev/null
@@ -0,0 +1 @@
+pssh-rep/pssh/arm/crypto/openssl/aes
diff --git a/arm/crypto/openssl/aes/CVS/Root b/arm/crypto/openssl/aes/CVS/Root
new file mode 100644 (file)
index 0000000..c78f222
--- /dev/null
@@ -0,0 +1 @@
+/Volumes/poindexter/repository
diff --git a/arm/crypto/openssl/aes/CVS/Tag b/arm/crypto/openssl/aes/CVS/Tag
new file mode 100644 (file)
index 0000000..5b46a87
--- /dev/null
@@ -0,0 +1 @@
+Npssh-2005_06_23
diff --git a/arm/crypto/openssl/aes/aes.h b/arm/crypto/openssl/aes/aes.h
new file mode 100644 (file)
index 0000000..1cfd557
--- /dev/null
@@ -0,0 +1,143 @@
+/* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 1998-2002 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.
+ * ====================================================================
+ *
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// changed some variables to use stdint types
+
+#ifndef HEADER_AES_H
+#define HEADER_AES_H
+
+#include "openssl/cryptlib.h"
+
+#ifdef OPENSSL_NO_AES
+#error AES is disabled.
+#endif
+
+#define AES_ENCRYPT    1
+#define AES_DECRYPT    0
+
+/* Because array size can't be a const in C, the following two are macros.
+   Both sizes are in bytes. */
+#define AES_MAXNR 14
+#define AES_BLOCK_SIZE 16
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* This should be a hidden type, but EVP requires that the size be known */
+// pssh: contents of AES_KEY are left in ARM-endian order. Do not use.
+struct aes_key_st {
+    uint32_t rd_key[4 *(AES_MAXNR + 1)];
+    uint32_t rounds;
+};
+typedef struct aes_key_st AES_KEY;
+
+const char *AES_options(void);
+
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+       AES_KEY *key);
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+       AES_KEY *key);
+
+void AES_encrypt(const unsigned char *in, unsigned char *out,
+       const AES_KEY *key);
+void AES_decrypt(const unsigned char *in, unsigned char *out,
+       const AES_KEY *key);
+
+void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
+       const AES_KEY *key, const int enc);
+void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+       const uint32_t length, const AES_KEY *key,
+       unsigned char *ivec, const int enc);
+void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+       const uint32_t length, const AES_KEY *key,
+       unsigned char *ivec, int *num, const int enc);
+void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+       const uint32_t length, const AES_KEY *key,
+       unsigned char *ivec, int *num);
+void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+       const uint32_t length, const AES_KEY *key,
+       unsigned char ivec[AES_BLOCK_SIZE],
+       unsigned char ecount_buf[AES_BLOCK_SIZE],
+       uint32_t *num);
+
+void AES_ctr128_inc(unsigned char *counter);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* !HEADER_AES_H */
diff --git a/arm/crypto/openssl/aes/aes_armcalls.c b/arm/crypto/openssl/aes/aes_armcalls.c
new file mode 100644 (file)
index 0000000..718f265
--- /dev/null
@@ -0,0 +1,68 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "aes_internal.h"
+#include "swap.h"
+
+uint32_t AES_set_encrypt_key_stub(uint32_t *param);
+uint32_t AES_set_decrypt_key_stub(uint32_t *param);
+uint32_t AES_cbc_encrypt_stub(uint32_t *param);
+uint32_t AES_encrypt_stub(uint32_t *param);
+
+uint32_t AES_set_encrypt_key_stub(uint32_t *param) {
+    unsigned char *userKey = (unsigned char *)read32(&param[0]);
+    int bits = (int)read32(&param[1]);
+    AES_KEY *key = (AES_KEY *)read32(&param[2]);
+
+    return (uint32_t) AES_set_encrypt_key(userKey, bits, key);
+}
+
+uint32_t AES_set_decrypt_key_stub(uint32_t *param) {
+    unsigned char *userKey = (unsigned char *)read32(&param[0]);
+    int bits = (int)read32(&param[1]);
+    AES_KEY *key = (AES_KEY *)read32(&param[2]);
+
+    return (uint32_t) AES_set_decrypt_key(userKey, bits, key);
+}
+
+uint32_t AES_cbc_encrypt_stub(uint32_t *param) {
+    unsigned char *in = (unsigned char *)read32(&param[0]);
+    unsigned char *out = (unsigned char *)read32(&param[1]);
+    uint32_t length = (uint32_t)read32(&param[2]);
+    AES_KEY *key = (AES_KEY *)read32(&param[3]);
+    unsigned char *ivec = (unsigned char *)read32(&param[4]);
+    int enc = (int)read32(&param[5]);
+
+    AES_cbc_encrypt(in, out, length, key, ivec, enc);
+    return 0;
+}
+
+uint32_t AES_encrypt_stub(uint32_t *param) {
+    unsigned char *in = (unsigned char *)read32(&param[0]);
+    unsigned char *out = (unsigned char *)read32(&param[1]);
+    AES_KEY *key = (AES_KEY *)read32(&param[2]);
+
+    AES_encrypt(in, out, key);
+    return 0;
+}
diff --git a/arm/crypto/openssl/aes/aes_cbc.c b/arm/crypto/openssl/aes/aes_cbc.c
new file mode 100644 (file)
index 0000000..2e014a3
--- /dev/null
@@ -0,0 +1,130 @@
+/* crypto/aes/aes_cbc.c -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 1998-2002 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.
+ * ====================================================================
+ *
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// changed some variables to use stdint types
+
+#include "aes_includes.h"
+
+void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                    const uint32_t length, const AES_KEY *key,
+                    unsigned char *ivec, const int enc) {
+
+       uint32_t n;
+       uint32_t len = length;
+       unsigned char tmp[AES_BLOCK_SIZE];
+
+       assert(in && out && key && ivec);
+       assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
+
+       if (AES_ENCRYPT == enc) {
+               while (len >= AES_BLOCK_SIZE) {
+                       for(n=0; n < AES_BLOCK_SIZE; ++n)
+                               tmp[n] = in[n] ^ ivec[n];
+                       AES_encrypt(tmp, out, key);
+                       memcpy(ivec, out, AES_BLOCK_SIZE);
+                       len -= AES_BLOCK_SIZE;
+                       in += AES_BLOCK_SIZE;
+                       out += AES_BLOCK_SIZE;
+               }
+               if (len) {
+                       for(n=0; n < len; ++n)
+                               tmp[n] = in[n] ^ ivec[n];
+                       for(n=len; n < AES_BLOCK_SIZE; ++n)
+                               tmp[n] = ivec[n];
+                       AES_encrypt(tmp, tmp, key);
+                       memcpy(out, tmp, AES_BLOCK_SIZE);
+                       memcpy(ivec, tmp, AES_BLOCK_SIZE);
+               }                       
+       } else {
+               while (len >= AES_BLOCK_SIZE) {
+                       memcpy(tmp, in, AES_BLOCK_SIZE);
+                       AES_decrypt(in, out, key);
+                       for(n=0; n < AES_BLOCK_SIZE; ++n)
+                               out[n] ^= ivec[n];
+                       memcpy(ivec, tmp, AES_BLOCK_SIZE);
+                       len -= AES_BLOCK_SIZE;
+                       in += AES_BLOCK_SIZE;
+                       out += AES_BLOCK_SIZE;
+               }
+               if (len) {
+                       memcpy(tmp, in, AES_BLOCK_SIZE);
+                       AES_decrypt(tmp, tmp, key);
+                       for(n=0; n < len; ++n)
+                               out[n] ^= ivec[n];
+                       memcpy(ivec, tmp, AES_BLOCK_SIZE);
+               }                       
+       }
+}
diff --git a/arm/crypto/openssl/aes/aes_core.c b/arm/crypto/openssl/aes/aes_core.c
new file mode 100644 (file)
index 0000000..1f255f1
--- /dev/null
@@ -0,0 +1,621 @@
+/* crypto/aes/aes_core.c -*- mode:C; c-file-style: "eay" -*- */
+/**
+ * rijndael-alg-fst.c
+ *
+ * @version 3.0 (December 2000)
+ *
+ * Optimised ANSI C code for the Rijndael cipher (now AES)
+ *
+ * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ * @author Paulo Barreto <paulo.barreto@terra.com.br>
+ *
+ * This code is hereby placed in the public domain.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS 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.
+ */
+
+/* Note: rewritten a little bit to provide error control and an OpenSSL-
+   compatible API */
+
+// GrP pssh:
+// changed includes
+// disabled AES-192 and -256 (PSSH_NO_BIG_AES)
+// moved AES tables to aes_tables.c and aes_tables.rcp
+
+#include "aes_includes.h"
+#include "aes_tables.h"
+
+// set by aes_lock_tables() and aes_unlock_tables()
+const u32 *Te0 = NULL;
+const u32 *Te1 = NULL;
+const u32 *Te2 = NULL;
+const u32 *Te3 = NULL;
+const u32 *Te4 = NULL;
+const u32 *Td0 = NULL;
+const u32 *Td1 = NULL;
+const u32 *Td2 = NULL;
+const u32 *Td3 = NULL;
+const u32 *Td4 = NULL;
+
+static const u32 rcon[] = {
+       0x01000000, 0x02000000, 0x04000000, 0x08000000,
+       0x10000000, 0x20000000, 0x40000000, 0x80000000,
+       0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+};
+
+/**
+ * Expand the cipher key into the encryption key schedule.
+ */
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+                       AES_KEY *key) {
+
+       u32 *rk;
+       int i = 0;
+       u32 temp;
+
+       if (!userKey || !key)
+               return -1;
+       if (bits != 128
+#ifndef PSSH_NO_BIG_AES
+            && bits != 192 && bits != 256
+#endif
+            )
+               return -2;
+
+       rk = key->rd_key;
+
+       if (bits==128)
+               key->rounds = 10;
+#ifndef PSSH_NO_BIG_AES
+       else if (bits==192)
+               key->rounds = 12;
+       else
+               key->rounds = 14;
+#endif
+
+       aes_lock_tables();
+       assert(Te0 && Te1 && Te2 && Te3 && Te4 && 
+               Td0 && Td1 && Td2 && Td3 && Td4);
+
+       rk[0] = GETU32(userKey     );
+       rk[1] = GETU32(userKey +  4);
+       rk[2] = GETU32(userKey +  8);
+       rk[3] = GETU32(userKey + 12);
+       if (bits == 128) {
+               while (1) {
+                       temp  = rk[3];
+                       rk[4] = rk[0] ^
+                               (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+                               (Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
+                               (Te4[(temp      ) & 0xff] & 0x0000ff00) ^
+                               (Te4[(temp >> 24)       ] & 0x000000ff) ^
+                               rcon[i];
+                       rk[5] = rk[1] ^ rk[4];
+                       rk[6] = rk[2] ^ rk[5];
+                       rk[7] = rk[3] ^ rk[6];
+                       if (++i == 10) {
+                               aes_unlock_tables();
+                               return 0;
+                       }
+                       rk += 4;
+               }
+       }
+#ifndef PSSH_NO_BIG_AES
+       rk[4] = GETU32(userKey + 16);
+       rk[5] = GETU32(userKey + 20);
+       if (bits == 192) {
+               while (1) {
+                       temp = rk[ 5];
+                       rk[ 6] = rk[ 0] ^
+                               (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+                               (Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
+                               (Te4[(temp      ) & 0xff] & 0x0000ff00) ^
+                               (Te4[(temp >> 24)       ] & 0x000000ff) ^
+                               rcon[i];
+                       rk[ 7] = rk[ 1] ^ rk[ 6];
+                       rk[ 8] = rk[ 2] ^ rk[ 7];
+                       rk[ 9] = rk[ 3] ^ rk[ 8];
+                       if (++i == 8) {
+                               aes_unlock_tables();
+                               return 0;
+                       }
+                       rk[10] = rk[ 4] ^ rk[ 9];
+                       rk[11] = rk[ 5] ^ rk[10];
+                       rk += 6;
+               }
+       }
+       rk[6] = GETU32(userKey + 24);
+       rk[7] = GETU32(userKey + 28);
+       if (bits == 256) {
+               while (1) {
+                       temp = rk[ 7];
+                       rk[ 8] = rk[ 0] ^
+                               (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+                               (Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
+                               (Te4[(temp      ) & 0xff] & 0x0000ff00) ^
+                               (Te4[(temp >> 24)       ] & 0x000000ff) ^
+                               rcon[i];
+                       rk[ 9] = rk[ 1] ^ rk[ 8];
+                       rk[10] = rk[ 2] ^ rk[ 9];
+                       rk[11] = rk[ 3] ^ rk[10];
+                       if (++i == 7) {
+                               aes_unlock_tables();
+                               return 0;
+                       }
+                       temp = rk[11];
+                       rk[12] = rk[ 4] ^
+                               (Te4[(temp >> 24)       ] & 0xff000000) ^
+                               (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
+                               (Te4[(temp >>  8) & 0xff] & 0x0000ff00) ^
+                               (Te4[(temp      ) & 0xff] & 0x000000ff);
+                       rk[13] = rk[ 5] ^ rk[12];
+                       rk[14] = rk[ 6] ^ rk[13];
+                       rk[15] = rk[ 7] ^ rk[14];
+
+                       rk += 8;
+               }
+       }
+       aes_unlock_tables();
+       return 0;
+#endif
+}
+
+/**
+ * Expand the cipher key into the decryption key schedule.
+ */
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+                       AES_KEY *key) {
+
+        u32 *rk;
+       int i, j, status;
+       u32 temp;
+
+       /* first, start with an encryption schedule */
+       status = AES_set_encrypt_key(userKey, bits, key);
+       if (status < 0)
+               return status;
+
+       aes_lock_tables();
+       assert(Te0 && Te1 && Te2 && Te3 && Te4 && 
+               Td0 && Td1 && Td2 && Td3 && Td4);
+
+       rk = key->rd_key;
+
+       /* invert the order of the round keys: */
+       for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
+               temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
+               temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
+               temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
+               temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
+       }
+       /* apply the inverse MixColumn transform to all round keys but the first and the last: */
+       for (i = 1; i < (key->rounds); i++) {
+               rk += 4;
+               rk[0] =
+                       Td0[Te4[(rk[0] >> 24)       ] & 0xff] ^
+                       Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
+                       Td2[Te4[(rk[0] >>  8) & 0xff] & 0xff] ^
+                       Td3[Te4[(rk[0]      ) & 0xff] & 0xff];
+               rk[1] =
+                       Td0[Te4[(rk[1] >> 24)       ] & 0xff] ^
+                       Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
+                       Td2[Te4[(rk[1] >>  8) & 0xff] & 0xff] ^
+                       Td3[Te4[(rk[1]      ) & 0xff] & 0xff];
+               rk[2] =
+                       Td0[Te4[(rk[2] >> 24)       ] & 0xff] ^
+                       Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
+                       Td2[Te4[(rk[2] >>  8) & 0xff] & 0xff] ^
+                       Td3[Te4[(rk[2]      ) & 0xff] & 0xff];
+               rk[3] =
+                       Td0[Te4[(rk[3] >> 24)       ] & 0xff] ^
+                       Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
+                       Td2[Te4[(rk[3] >>  8) & 0xff] & 0xff] ^
+                       Td3[Te4[(rk[3]      ) & 0xff] & 0xff];
+       }
+       aes_unlock_tables();
+       return 0;
+}
+
+/*
+ * Encrypt a single block
+ * in and out can overlap
+ */
+void AES_encrypt(const unsigned char *in, unsigned char *out,
+                const AES_KEY *key) {
+
+       const u32 *rk;
+       u32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+       int r;
+#endif /* ?FULL_UNROLL */
+
+       assert(in && out && key);
+       rk = key->rd_key;
+
+       aes_lock_tables();
+       assert(Te0 && Te1 && Te2 && Te3 && Te4 && 
+               Td0 && Td1 && Td2 && Td3 && Td4);
+
+       /*
+        * map byte array block to cipher state
+        * and add initial round key:
+        */
+       s0 = GETU32(in     ) ^ rk[0];
+       s1 = GETU32(in +  4) ^ rk[1];
+       s2 = GETU32(in +  8) ^ rk[2];
+       s3 = GETU32(in + 12) ^ rk[3];
+#ifdef FULL_UNROLL
+       /* round 1: */
+       t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
+       t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
+       t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
+       t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
+       /* round 2: */
+       s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
+       s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
+       s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
+       s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
+       /* round 3: */
+       t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
+       t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
+       t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
+       t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
+       /* round 4: */
+       s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
+       s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
+       s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
+       s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
+       /* round 5: */
+       t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
+       t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
+       t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
+       t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
+       /* round 6: */
+       s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
+       s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
+       s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
+       s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
+       /* round 7: */
+       t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
+       t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
+       t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
+       t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
+       /* round 8: */
+       s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
+       s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
+       s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
+       s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
+       /* round 9: */
+       t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
+       t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
+       t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
+       t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
+    if (key->rounds > 10) {
+        /* round 10: */
+        s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
+        s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
+        s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
+        s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
+        /* round 11: */
+        t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
+        t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
+        t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
+        t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
+        if (key->rounds > 12) {
+            /* round 12: */
+            s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
+            s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
+            s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
+            s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
+            /* round 13: */
+            t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
+            t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
+            t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
+            t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
+        }
+    }
+    rk += key->rounds << 2;
+#else  /* !FULL_UNROLL */
+    /*
+     * Nr - 1 full rounds:
+     */
+    r = key->rounds >> 1;
+    for (;;) {
+        t0 =
+            Te0[(s0 >> 24)       ] ^
+            Te1[(s1 >> 16) & 0xff] ^
+            Te2[(s2 >>  8) & 0xff] ^
+            Te3[(s3      ) & 0xff] ^
+            rk[4];
+        t1 =
+            Te0[(s1 >> 24)       ] ^
+            Te1[(s2 >> 16) & 0xff] ^
+            Te2[(s3 >>  8) & 0xff] ^
+            Te3[(s0      ) & 0xff] ^
+            rk[5];
+        t2 =
+            Te0[(s2 >> 24)       ] ^
+            Te1[(s3 >> 16) & 0xff] ^
+            Te2[(s0 >>  8) & 0xff] ^
+            Te3[(s1      ) & 0xff] ^
+            rk[6];
+        t3 =
+            Te0[(s3 >> 24)       ] ^
+            Te1[(s0 >> 16) & 0xff] ^
+            Te2[(s1 >>  8) & 0xff] ^
+            Te3[(s2      ) & 0xff] ^
+            rk[7];
+
+        rk += 8;
+        if (--r == 0) {
+            break;
+        }
+
+        s0 =
+            Te0[(t0 >> 24)       ] ^
+            Te1[(t1 >> 16) & 0xff] ^
+            Te2[(t2 >>  8) & 0xff] ^
+            Te3[(t3      ) & 0xff] ^
+            rk[0];
+        s1 =
+            Te0[(t1 >> 24)       ] ^
+            Te1[(t2 >> 16) & 0xff] ^
+            Te2[(t3 >>  8) & 0xff] ^
+            Te3[(t0      ) & 0xff] ^
+            rk[1];
+        s2 =
+            Te0[(t2 >> 24)       ] ^
+            Te1[(t3 >> 16) & 0xff] ^
+            Te2[(t0 >>  8) & 0xff] ^
+            Te3[(t1      ) & 0xff] ^
+            rk[2];
+        s3 =
+            Te0[(t3 >> 24)       ] ^
+            Te1[(t0 >> 16) & 0xff] ^
+            Te2[(t1 >>  8) & 0xff] ^
+            Te3[(t2      ) & 0xff] ^
+            rk[3];
+    }
+#endif /* ?FULL_UNROLL */
+    /*
+        * apply last round and
+        * map cipher state to byte array block:
+        */
+       s0 =
+               (Te4[(t0 >> 24)       ] & 0xff000000) ^
+               (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+               (Te4[(t2 >>  8) & 0xff] & 0x0000ff00) ^
+               (Te4[(t3      ) & 0xff] & 0x000000ff) ^
+               rk[0];
+       PUTU32(out     , s0);
+       s1 =
+               (Te4[(t1 >> 24)       ] & 0xff000000) ^
+               (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+               (Te4[(t3 >>  8) & 0xff] & 0x0000ff00) ^
+               (Te4[(t0      ) & 0xff] & 0x000000ff) ^
+               rk[1];
+       PUTU32(out +  4, s1);
+       s2 =
+               (Te4[(t2 >> 24)       ] & 0xff000000) ^
+               (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+               (Te4[(t0 >>  8) & 0xff] & 0x0000ff00) ^
+               (Te4[(t1      ) & 0xff] & 0x000000ff) ^
+               rk[2];
+       PUTU32(out +  8, s2);
+       s3 =
+               (Te4[(t3 >> 24)       ] & 0xff000000) ^
+               (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+               (Te4[(t1 >>  8) & 0xff] & 0x0000ff00) ^
+               (Te4[(t2      ) & 0xff] & 0x000000ff) ^
+               rk[3];
+       PUTU32(out + 12, s3);
+       aes_unlock_tables();
+}
+
+/*
+ * Decrypt a single block
+ * in and out can overlap
+ */
+void AES_decrypt(const unsigned char *in, unsigned char *out,
+                const AES_KEY *key) {
+
+       const u32 *rk;
+       u32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+       int r;
+#endif /* ?FULL_UNROLL */
+
+       assert(in && out && key);
+       rk = key->rd_key;
+
+       aes_lock_tables();
+       assert(Te0 && Te1 && Te2 && Te3 && Te4 && 
+               Td0 && Td1 && Td2 && Td3 && Td4);
+
+       /*
+        * map byte array block to cipher state
+        * and add initial round key:
+        */
+    s0 = GETU32(in     ) ^ rk[0];
+    s1 = GETU32(in +  4) ^ rk[1];
+    s2 = GETU32(in +  8) ^ rk[2];
+    s3 = GETU32(in + 12) ^ rk[3];
+#ifdef FULL_UNROLL
+    /* round 1: */
+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
+    /* round 2: */
+    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
+    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
+    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
+    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
+    /* round 3: */
+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
+    /* round 4: */
+    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
+    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
+    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
+    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
+    /* round 5: */
+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
+    /* round 6: */
+    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
+    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
+    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
+    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
+    /* round 7: */
+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
+    /* round 8: */
+    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
+    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
+    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
+    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
+    /* round 9: */
+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
+    if (key->rounds > 10) {
+        /* round 10: */
+        s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
+        s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
+        s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
+        s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
+        /* round 11: */
+        t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
+        t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
+        t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
+        t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
+        if (key->rounds > 12) {
+            /* round 12: */
+            s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
+            s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
+            s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
+            s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
+            /* round 13: */
+            t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
+            t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
+            t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
+            t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
+        }
+    }
+       rk += key->rounds << 2;
+#else  /* !FULL_UNROLL */
+    /*
+     * Nr - 1 full rounds:
+     */
+    r = key->rounds >> 1;
+    for (;;) {
+        t0 =
+            Td0[(s0 >> 24)       ] ^
+            Td1[(s3 >> 16) & 0xff] ^
+            Td2[(s2 >>  8) & 0xff] ^
+            Td3[(s1      ) & 0xff] ^
+            rk[4];
+        t1 =
+            Td0[(s1 >> 24)       ] ^
+            Td1[(s0 >> 16) & 0xff] ^
+            Td2[(s3 >>  8) & 0xff] ^
+            Td3[(s2      ) & 0xff] ^
+            rk[5];
+        t2 =
+            Td0[(s2 >> 24)       ] ^
+            Td1[(s1 >> 16) & 0xff] ^
+            Td2[(s0 >>  8) & 0xff] ^
+            Td3[(s3      ) & 0xff] ^
+            rk[6];
+        t3 =
+            Td0[(s3 >> 24)       ] ^
+            Td1[(s2 >> 16) & 0xff] ^
+            Td2[(s1 >>  8) & 0xff] ^
+            Td3[(s0      ) & 0xff] ^
+            rk[7];
+
+        rk += 8;
+        if (--r == 0) {
+            break;
+        }
+
+        s0 =
+            Td0[(t0 >> 24)       ] ^
+            Td1[(t3 >> 16) & 0xff] ^
+            Td2[(t2 >>  8) & 0xff] ^
+            Td3[(t1      ) & 0xff] ^
+            rk[0];
+        s1 =
+            Td0[(t1 >> 24)       ] ^
+            Td1[(t0 >> 16) & 0xff] ^
+            Td2[(t3 >>  8) & 0xff] ^
+            Td3[(t2      ) & 0xff] ^
+            rk[1];
+        s2 =
+            Td0[(t2 >> 24)       ] ^
+            Td1[(t1 >> 16) & 0xff] ^
+            Td2[(t0 >>  8) & 0xff] ^
+            Td3[(t3      ) & 0xff] ^
+            rk[2];
+        s3 =
+            Td0[(t3 >> 24)       ] ^
+            Td1[(t2 >> 16) & 0xff] ^
+            Td2[(t1 >>  8) & 0xff] ^
+            Td3[(t0      ) & 0xff] ^
+            rk[3];
+    }
+#endif /* ?FULL_UNROLL */
+    /*
+        * apply last round and
+        * map cipher state to byte array block:
+        */
+       s0 =
+               (Td4[(t0 >> 24)       ] & 0xff000000) ^
+               (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+               (Td4[(t2 >>  8) & 0xff] & 0x0000ff00) ^
+               (Td4[(t1      ) & 0xff] & 0x000000ff) ^
+               rk[0];
+       PUTU32(out     , s0);
+       s1 =
+               (Td4[(t1 >> 24)       ] & 0xff000000) ^
+               (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+               (Td4[(t3 >>  8) & 0xff] & 0x0000ff00) ^
+               (Td4[(t2      ) & 0xff] & 0x000000ff) ^
+               rk[1];
+       PUTU32(out +  4, s1);
+       s2 =
+               (Td4[(t2 >> 24)       ] & 0xff000000) ^
+               (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+               (Td4[(t0 >>  8) & 0xff] & 0x0000ff00) ^
+               (Td4[(t3      ) & 0xff] & 0x000000ff) ^
+               rk[2];
+       PUTU32(out +  8, s2);
+       s3 =
+               (Td4[(t3 >> 24)       ] & 0xff000000) ^
+               (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+               (Td4[(t1 >>  8) & 0xff] & 0x0000ff00) ^
+               (Td4[(t0      ) & 0xff] & 0x000000ff) ^
+               rk[3];
+       PUTU32(out + 12, s3);
+       aes_unlock_tables();
+}
+
diff --git a/arm/crypto/openssl/aes/aes_includes.h b/arm/crypto/openssl/aes/aes_includes.h
new file mode 100644 (file)
index 0000000..d53263d
--- /dev/null
@@ -0,0 +1,33 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef AES_INCLUDES_H
+#define AES_INCLUDES_H
+
+#include "includes.h"
+#include "assert.h"
+#include "aes_internal.h"
+#include "aes_locl.h"
+
+#endif
diff --git a/arm/crypto/openssl/aes/aes_internal.h b/arm/crypto/openssl/aes/aes_internal.h
new file mode 100644 (file)
index 0000000..0a983e2
--- /dev/null
@@ -0,0 +1,150 @@
+/* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 1998-2002 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.
+ * ====================================================================
+ *
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// ARM-native version of aes.h
+// changed includes
+// changed some variables to use stdint types
+// added globals to all functions
+
+#ifndef HEADER_AES_H
+#define HEADER_AES_H
+
+#include "includes.h"
+
+#ifdef OPENSSL_NO_AES
+#error AES is disabled.
+#endif
+
+#define AES_ENCRYPT    1
+#define AES_DECRYPT    0
+
+/* Because array size can't be a const in C, the following two are macros.
+   Both sizes are in bytes. */
+#define AES_MAXNR 14
+#define AES_BLOCK_SIZE 16
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* This should be a hidden type, but EVP requires that the size be known */
+struct aes_key_st {
+    uint32_t rd_key[4 *(AES_MAXNR + 1)];
+    uint32_t rounds;
+};
+typedef struct aes_key_st AES_KEY;
+
+const char *AES_options(void);
+
+int AES_set_encrypt_key(
+       const unsigned char *userKey, const int bits,
+       AES_KEY *key); 
+int AES_set_decrypt_key(
+       const unsigned char *userKey, const int bits,
+       AES_KEY *key);
+void AES_encrypt(
+       const unsigned char *in, unsigned char *out, const AES_KEY *key);
+void AES_decrypt(
+       const unsigned char *in, unsigned char *out, const AES_KEY *key);
+
+void AES_ecb_encrypt(
+       const unsigned char *in, unsigned char *out,
+       const AES_KEY *key, const int enc);
+void AES_cbc_encrypt(
+       const unsigned char *in, unsigned char *out,
+       const uint32_t length, const AES_KEY *key,
+       unsigned char *ivec, const int enc);
+void AES_cfb128_encrypt(
+       const unsigned char *in, unsigned char *out,
+       const uint32_t length, const AES_KEY *key,
+       unsigned char *ivec, int *num, const int enc);
+void AES_ofb128_encrypt(
+       const unsigned char *in, unsigned char *out,
+       const uint32_t length, const AES_KEY *key,
+       unsigned char *ivec, int *num);
+void AES_ctr128_encrypt(
+       const unsigned char *in, unsigned char *out,
+       const uint32_t length, const AES_KEY *key,
+       unsigned char ivec[AES_BLOCK_SIZE],
+       unsigned char ecount_buf[AES_BLOCK_SIZE],
+       uint32_t *num);
+
+void AES_ctr128_inc(unsigned char *counter);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* !HEADER_AES_H */
diff --git a/arm/crypto/openssl/aes/aes_locl.h b/arm/crypto/openssl/aes/aes_locl.h
new file mode 100644 (file)
index 0000000..58352e0
--- /dev/null
@@ -0,0 +1,110 @@
+/* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 1998-2002 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.
+ * ====================================================================
+ *
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// changed typedefs to use stdint types
+// moved AES tables to aes_tables.c and aes_tables.rcp
+// use FULL_UNROLL (fixme non-unrolled fails on ARM)
+
+#ifndef HEADER_AES_LOCL_H
+#define HEADER_AES_LOCL_H
+
+#include <stdint.h>
+
+#ifdef OPENSSL_NO_AES
+#error AES is disabled.
+#endif
+
+#if defined(_MSC_VER) && !defined(OPENSSL_SYS_WINCE)
+# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+# define GETU32(p) SWAP(*((u32 *)(p)))
+# define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
+#else
+# define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] <<  8) ^ ((u32)(pt)[3]))
+# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >>  8); (ct)[3] = (u8)(st); }
+#endif
+
+typedef uint32_t u32;
+typedef uint16_t u16;
+typedef uint8_t u8;
+
+#define MAXKC   (256/32)
+#define MAXKB   (256/8)
+#define MAXNR   14
+
+/* This controls loop-unrolling in aes_core.c */
+#define FULL_UNROLL
+
+#endif /* !HEADER_AES_LOCL_H */
diff --git a/arm/crypto/openssl/aes/aes_tables.c b/arm/crypto/openssl/aes/aes_tables.c
new file mode 100644 (file)
index 0000000..e6304d2
--- /dev/null
@@ -0,0 +1,127 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "aes_includes.h"
+#include "aes_tables.h"
+
+// fixme copied from cryptorsrc.h
+#define AES_Te0_id 9010
+#define AES_Te1_id 9011
+#define AES_Te2_id 9012
+#define AES_Te3_id 9013
+#define AES_Te4_id 9014
+#define AES_Td0_id 9015
+#define AES_Td1_id 9016
+#define AES_Td2_id 9017
+#define AES_Td3_id 9018
+#define AES_Td4_id 9019
+
+// resource handles
+static MemHandle Te0_h = NULL;
+static MemHandle Te1_h = NULL;
+static MemHandle Te2_h = NULL;
+static MemHandle Te3_h = NULL;
+static MemHandle Te4_h = NULL;
+static MemHandle Td0_h = NULL;
+static MemHandle Td1_h = NULL;
+static MemHandle Td2_h = NULL;
+static MemHandle Td3_h = NULL;
+static MemHandle Td4_h = NULL;
+
+// from aes_core.c
+extern const u32 *Te0;
+extern const u32 *Te1;
+extern const u32 *Te2;
+extern const u32 *Te3;
+extern const u32 *Te4;
+extern const u32 *Td0;
+extern const u32 *Td1;
+extern const u32 *Td2;
+extern const u32 *Td3;
+extern const u32 *Td4;
+
+void aes_init_tables(void)
+{
+    // fixme error handling
+
+    // grab data from resources
+    Te0_h = DmGetResource('adwd', AES_Te0_id);
+    Te1_h = DmGetResource('adwd', AES_Te1_id);
+    Te2_h = DmGetResource('adwd', AES_Te2_id);
+    Te3_h = DmGetResource('adwd', AES_Te3_id);
+    Te4_h = DmGetResource('adwd', AES_Te4_id);
+    Td0_h = DmGetResource('adwd', AES_Td0_id);
+    Td1_h = DmGetResource('adwd', AES_Td1_id);
+    Td2_h = DmGetResource('adwd', AES_Td2_id);
+    Td3_h = DmGetResource('adwd', AES_Td3_id);
+    Td4_h = DmGetResource('adwd', AES_Td4_id);
+
+    // adwd resource is prefixed with 4-byte word count
+    // AES tables should be 256 words long, plus the count word
+
+    // verify handle sizes
+    assert(MemHandleSize(Te0_h) == 4*(1+256));
+    assert(MemHandleSize(Te1_h) == 4*(1+256));
+    assert(MemHandleSize(Te2_h) == 4*(1+256));
+    assert(MemHandleSize(Te3_h) == 4*(1+256));
+    assert(MemHandleSize(Te4_h) == 4*(1+256));
+    assert(MemHandleSize(Td0_h) == 4*(1+256));
+    assert(MemHandleSize(Td1_h) == 4*(1+256));
+    assert(MemHandleSize(Td2_h) == 4*(1+256));
+    assert(MemHandleSize(Td3_h) == 4*(1+256));
+    assert(MemHandleSize(Td4_h) == 4*(1+256));
+}
+
+
+void aes_lock_tables(void)
+{
+    if (!Te0_h) aes_init_tables();
+
+    // lock and skip 4-byte word count
+    Te0 = 1 + (const u32 *)MemHandleLock(Te0_h);
+    Te1 = 1 + (const u32 *)MemHandleLock(Te1_h);
+    Te2 = 1 + (const u32 *)MemHandleLock(Te2_h);
+    Te3 = 1 + (const u32 *)MemHandleLock(Te3_h);
+    Te4 = 1 + (const u32 *)MemHandleLock(Te4_h);
+    Td0 = 1 + (const u32 *)MemHandleLock(Td0_h);
+    Td1 = 1 + (const u32 *)MemHandleLock(Td1_h);
+    Td2 = 1 + (const u32 *)MemHandleLock(Td2_h);
+    Td3 = 1 + (const u32 *)MemHandleLock(Td3_h);
+    Td4 = 1 + (const u32 *)MemHandleLock(Td4_h);
+}
+
+
+void aes_unlock_tables(void)
+{
+    MemHandleUnlock(Te0_h); Te0 = NULL;
+    MemHandleUnlock(Te1_h); Te1 = NULL;
+    MemHandleUnlock(Te2_h); Te2 = NULL;
+    MemHandleUnlock(Te3_h); Te3 = NULL;
+    MemHandleUnlock(Te4_h); Te4 = NULL;
+    MemHandleUnlock(Td0_h); Td0 = NULL;
+    MemHandleUnlock(Td1_h); Td1 = NULL;
+    MemHandleUnlock(Td2_h); Td2 = NULL;
+    MemHandleUnlock(Td3_h); Td3 = NULL;
+    MemHandleUnlock(Td4_h); Td4 = NULL;
+}
diff --git a/arm/crypto/openssl/aes/aes_tables.h b/arm/crypto/openssl/aes/aes_tables.h
new file mode 100644 (file)
index 0000000..71c53d1
--- /dev/null
@@ -0,0 +1,32 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef AES_TABLES_H
+#define AES_TABLES_H
+
+void aes_init_tables(void);
+void aes_lock_tables(void);
+void aes_unlock_tables(void);
+
+#endif
diff --git a/arm/crypto/openssl/bn/CVS/Entries b/arm/crypto/openssl/bn/CVS/Entries
new file mode 100644 (file)
index 0000000..e4871e5
--- /dev/null
@@ -0,0 +1,21 @@
+/bn_add.c/1.1/Mon Jul 19 10:00:16 2004//Tpssh-2005_06_23
+/bn_armcalls.c/1.3/Wed Nov 24 21:59:35 2004//Tpssh-2005_06_23
+/bn_asm.c/1.1/Mon Jul 19 10:00:16 2004//Tpssh-2005_06_23
+/bn_ctx.c/1.1/Mon Jul 19 10:00:16 2004//Tpssh-2005_06_23
+/bn_div.c/1.1/Mon Jul 19 10:00:16 2004//Tpssh-2005_06_23
+/bn_exp.c/1.1/Mon Jul 19 10:00:16 2004//Tpssh-2005_06_23
+/bn_gcd.c/1.1/Mon Jul 19 10:00:16 2004//Tpssh-2005_06_23
+/bn_includes.h/1.2/Tue Jul 20 10:45:33 2004//Tpssh-2005_06_23
+/bn_internal.h/1.2/Wed Nov 24 21:59:35 2004//Tpssh-2005_06_23
+/bn_lcl.h/1.2/Wed Nov 24 21:59:35 2004//Tpssh-2005_06_23
+/bn_lib.c/1.1/Mon Jul 19 10:00:16 2004//Tpssh-2005_06_23
+/bn_mod.c/1.1/Mon Jul 19 10:00:16 2004//Tpssh-2005_06_23
+/bn_mont.c/1.1/Mon Jul 19 10:00:16 2004//Tpssh-2005_06_23
+/bn_mul.c/1.1/Mon Jul 19 10:00:16 2004//Tpssh-2005_06_23
+/bn_print.c/1.1/Mon Jul 19 10:00:16 2004//Tpssh-2005_06_23
+/bn_rand.c/1.2/Tue Jul 20 10:45:33 2004//Tpssh-2005_06_23
+/bn_recp.c/1.1/Mon Jul 19 10:00:16 2004//Tpssh-2005_06_23
+/bn_shift.c/1.1/Mon Jul 19 10:00:16 2004//Tpssh-2005_06_23
+/bn_sqr.c/1.1/Mon Jul 19 10:00:16 2004//Tpssh-2005_06_23
+/bn_word.c/1.1/Mon Jul 19 10:00:16 2004//Tpssh-2005_06_23
+D
diff --git a/arm/crypto/openssl/bn/CVS/Repository b/arm/crypto/openssl/bn/CVS/Repository
new file mode 100644 (file)
index 0000000..1737da7
--- /dev/null
@@ -0,0 +1 @@
+pssh-rep/pssh/arm/crypto/openssl/bn
diff --git a/arm/crypto/openssl/bn/CVS/Root b/arm/crypto/openssl/bn/CVS/Root
new file mode 100644 (file)
index 0000000..c78f222
--- /dev/null
@@ -0,0 +1 @@
+/Volumes/poindexter/repository
diff --git a/arm/crypto/openssl/bn/CVS/Tag b/arm/crypto/openssl/bn/CVS/Tag
new file mode 100644 (file)
index 0000000..5b46a87
--- /dev/null
@@ -0,0 +1 @@
+Npssh-2005_06_23
diff --git a/arm/crypto/openssl/bn/bn_add.c b/arm/crypto/openssl/bn/bn_add.c
new file mode 100644 (file)
index 0000000..c3fbd35
--- /dev/null
@@ -0,0 +1,333 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+
+#include "bn_lcl.h"
+
+/* r can == a or b */
+int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+       {
+       const BIGNUM *tmp;
+       int a_neg = a->neg;
+
+       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 (!BN_uadd(r,a,b)) return(0);
+       if (a_neg) /* both are neg */
+               r->neg=1;
+       else
+               r->neg=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));*/
+       r->neg = 0;
+       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;
+       r->neg=0;
+       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/arm/crypto/openssl/bn/bn_armcalls.c b/arm/crypto/openssl/bn/bn_armcalls.c
new file mode 100644 (file)
index 0000000..fa935ee
--- /dev/null
@@ -0,0 +1,255 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "bn_includes.h"
+#include "bn_internal.h"
+#include "pealstub.h"
+#include "swap.h"
+
+uint32_t BN_is_negative_stub(uint32_t *param);
+uint32_t BN_CTX_new_stub(uint32_t *param);
+uint32_t BN_CTX_free_stub(uint32_t *param);
+uint32_t BN_CTX_start_stub(uint32_t *param);
+uint32_t BN_CTX_get_stub(uint32_t *param);
+uint32_t BN_CTX_end_stub(uint32_t *param);
+uint32_t BN_rand_stub(uint32_t *param);
+uint32_t BN_num_bits_stub(uint32_t *param);
+uint32_t BN_new_stub(uint32_t *param);
+uint32_t BN_clear_free_stub(uint32_t *param);
+uint32_t BN_bin2bn_stub(uint32_t *param);
+uint32_t BN_bn2bin_stub(uint32_t *param);
+uint32_t BN_cmp_stub(uint32_t *param);
+uint32_t BN_free_stub(uint32_t *param);
+uint32_t BN_is_bit_set_stub(uint32_t *param);
+uint32_t BN_mod_exp_mont_stub(uint32_t *param);
+uint32_t BN_mod_exp_mont_word_stub(uint32_t *param);
+uint32_t BN_bn2hex_stub(uint32_t *param);
+uint32_t BN_hex2bn_stub(uint32_t *param);
+uint32_t BN_MONT_CTX_new_stub(uint32_t *param);
+uint32_t BN_MONT_CTX_free_stub(uint32_t *param);
+uint32_t BN_MONT_CTX_set_stub(uint32_t *param);
+uint32_t BN_is_zero_stub(uint32_t *param);
+uint32_t BN_mod_mul_stub(uint32_t *param);
+uint32_t BN_ucmp_stub(uint32_t *param);
+uint32_t BN_mod_inverse_stub(uint32_t *param);
+uint32_t BN_div_stub(uint32_t *param);
+uint32_t BN_add_stub(uint32_t *param);
+uint32_t BN_sub_stub(uint32_t *param);
+uint32_t BN_rand_range_stub(uint32_t *param);
+
+
+uint32_t BN_is_negative_stub(uint32_t *param) {
+    BIGNUM *a = (BIGNUM *)read32(&param[0]);
+    return (uint32_t) BN_is_negative(a);
+}
+
+uint32_t BN_CTX_new_stub(uint32_t *param) {
+    return (uint32_t) BN_CTX_new();
+}
+
+uint32_t BN_CTX_free_stub(uint32_t *param) {
+    BN_CTX *ctx = (BN_CTX *)read32(&param[0]);
+    BN_CTX_free(ctx);
+    return 0;
+}
+
+uint32_t BN_CTX_start_stub(uint32_t *param) {
+    BN_CTX *ctx = (BN_CTX *)read32(&param[0]);
+    BN_CTX_start(ctx);
+    return 0;
+}
+
+uint32_t BN_CTX_get_stub(uint32_t *param) {
+    BN_CTX *ctx = (BN_CTX *)read32(&param[0]);
+    return (uint32_t) BN_CTX_get(ctx);
+}
+
+uint32_t BN_CTX_end_stub(uint32_t *param) {
+    BN_CTX *ctx = (BN_CTX *)read32(&param[0]);
+    BN_CTX_end(ctx);
+    return 0;
+}
+
+uint32_t BN_rand_stub(uint32_t *param) {
+    BIGNUM *rnd = (BIGNUM *)read32(&param[0]);
+    int bits = (int)read32(&param[1]);
+    int top = (int)read32(&param[2]);
+    int bottom = (int)read32(&param[3]);
+    return (uint32_t) BN_rand(rnd, bits, top, bottom);
+}
+
+uint32_t BN_num_bits_stub(uint32_t *param) {
+    BIGNUM *a = (BIGNUM *)read32(&param[0]);
+    return (uint32_t) BN_num_bits(a);
+}
+
+uint32_t BN_new_stub(uint32_t *param) {
+    return (uint32_t) BN_new();
+}
+
+uint32_t BN_clear_free_stub(uint32_t *param) {
+    BIGNUM *a = (BIGNUM *)read32(&param[0]);
+    BN_clear_free(a);
+    return 0;
+}
+
+uint32_t BN_bin2bn_stub(uint32_t *param) {
+    unsigned char *s = (unsigned char *)read32(&param[0]);
+    int len = (int)read32(&param[1]);
+    BIGNUM *ret = (BIGNUM *)read32(&param[2]);
+    return (uint32_t) BN_bin2bn(s, len, ret);
+}
+
+uint32_t BN_bn2bin_stub(uint32_t *param) {
+    BIGNUM *a = (BIGNUM *)read32(&param[0]);
+    unsigned char *to = (unsigned char *)read32(&param[1]);
+    return (uint32_t) BN_bn2bin(a, to);
+}
+
+uint32_t BN_cmp_stub(uint32_t *param) {
+    BIGNUM *a = (BIGNUM *)read32(&param[0]);
+    BIGNUM *b = (BIGNUM *)read32(&param[1]);
+    return (uint32_t) BN_cmp(a, b);
+}
+
+uint32_t BN_free_stub(uint32_t *param) {
+    BIGNUM *a = (BIGNUM *)read32(&param[0]);
+    BN_free(a);
+    return 0;
+}
+
+uint32_t BN_is_bit_set_stub(uint32_t *param) {
+    BIGNUM *a = (BIGNUM *)read32(&param[0]);
+    int n = (int)read32(&param[1]);
+    return (uint32_t) BN_is_bit_set(a, n);
+}
+
+uint32_t BN_mod_exp_mont_stub(uint32_t *param) {
+    BIGNUM *r = (BIGNUM *)read32(&param[0]);
+    BIGNUM *a = (BIGNUM *)read32(&param[1]);
+    BIGNUM *p = (BIGNUM *)read32(&param[2]);
+    BIGNUM *m = (BIGNUM *)read32(&param[3]);
+    BN_CTX *ctx = (BN_CTX *)read32(&param[4]);
+    BN_MONT_CTX *m_ctx = (BN_MONT_CTX *)read32(&param[5]);
+    return (uint32_t) BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
+}
+
+uint32_t BN_mod_exp_mont_word_stub(uint32_t *param) {
+    BIGNUM *r = (BIGNUM *)read32(&param[0]);
+    BN_ULONG a = (BN_ULONG)read32(&param[1]);
+    BIGNUM *p = (BIGNUM *)read32(&param[2]);
+    BIGNUM *m = (BIGNUM *)read32(&param[3]);
+    BN_CTX *ctx = (BN_CTX *)read32(&param[4]);
+    BN_MONT_CTX *m_ctx = (BN_MONT_CTX *)read32(&param[5]);
+    return (uint32_t) BN_mod_exp_mont_word(r, a, p, m, ctx, m_ctx);
+}
+
+uint32_t BN_bn2hex_stub(uint32_t *param) {
+    BIGNUM *a = (BIGNUM *)read32(&param[0]);
+    return (uint32_t) BN_bn2hex(a);
+}
+
+uint32_t BN_hex2bn_stub(uint32_t *param) {
+    BIGNUM **a = (BIGNUM **)read32(&param[0]);
+    char *str = (char *)read32(&param[1]);
+    swap32P(a);
+    uint32_t result = (uint32_t) BN_hex2bn(a, str);
+    swap32P(a);
+    return result;
+}
+
+uint32_t BN_MONT_CTX_new_stub(uint32_t *param) {
+    return (uint32_t) BN_MONT_CTX_new();
+}
+
+uint32_t BN_MONT_CTX_free_stub(uint32_t *param) {
+    BN_MONT_CTX *ctx = (BN_MONT_CTX *)read32(&param[0]);
+    BN_MONT_CTX_free(ctx);
+    return 0;
+}
+
+uint32_t BN_MONT_CTX_set_stub(uint32_t *param) {
+    BN_MONT_CTX *mont = (BN_MONT_CTX *)read32(&param[0]);
+    BIGNUM *mod = (BIGNUM *)read32(&param[1]);
+    BN_CTX *ctx = (BN_CTX *)read32(&param[2]);
+    return BN_MONT_CTX_set(mont, mod, ctx);
+}
+
+uint32_t BN_is_zero_stub(uint32_t *param) {
+    BIGNUM *a = (BIGNUM *)read32(&param[0]);
+    return (uint32_t) BN_is_zero(a);
+}
+
+uint32_t BN_mod_mul_stub(uint32_t *param) {
+    BIGNUM *r = (BIGNUM *)read32(&param[0]);
+    BIGNUM *a = (BIGNUM *)read32(&param[1]);
+    BIGNUM *b = (BIGNUM *)read32(&param[2]);
+    BIGNUM *m = (BIGNUM *)read32(&param[3]);
+    BN_CTX *ctx = (BN_CTX *)read32(&param[4]);
+    return (uint32_t) BN_mod_mul(r, a, b, m, ctx);
+}
+
+uint32_t BN_ucmp_stub(uint32_t *param) {
+    BIGNUM *a = (BIGNUM *)read32(&param[0]);
+    BIGNUM *b = (BIGNUM *)read32(&param[1]);
+    return (uint32_t) BN_ucmp(a, b);
+}
+
+uint32_t BN_mod_inverse_stub(uint32_t *param) {
+    BIGNUM *r = (BIGNUM *)read32(&param[0]);
+    BIGNUM *a = (BIGNUM *)read32(&param[1]);
+    BIGNUM *n = (BIGNUM *)read32(&param[2]);
+    BN_CTX *ctx = (BN_CTX *)read32(&param[3]);
+    return (uint32_t) BN_mod_inverse(r, a, n, ctx);
+}
+
+uint32_t BN_div_stub(uint32_t *param) {
+    BIGNUM *dv = (BIGNUM *)read32(&param[0]);
+    BIGNUM *rem = (BIGNUM *)read32(&param[1]);
+    BIGNUM *m = (BIGNUM *)read32(&param[2]);
+    BIGNUM *d = (BIGNUM *)read32(&param[3]);
+    BN_CTX *ctx = (BN_CTX *)read32(&param[4]);
+    return (uint32_t) BN_div(dv, rem, m, d, ctx);
+}
+
+uint32_t BN_add_stub(uint32_t *param) {
+    BIGNUM *r = (BIGNUM *)read32(&param[0]);
+    BIGNUM *a = (BIGNUM *)read32(&param[1]);
+    BIGNUM *b = (BIGNUM *)read32(&param[2]);
+    return (uint32_t) BN_add(r, a, b);
+}
+
+uint32_t BN_sub_stub(uint32_t *param) {
+    BIGNUM *r = (BIGNUM *)read32(&param[0]);
+    BIGNUM *a = (BIGNUM *)read32(&param[1]);
+    BIGNUM *b = (BIGNUM *)read32(&param[2]);
+    return (uint32_t) BN_sub(r, a, b);
+}
+
+uint32_t BN_rand_range_stub(uint32_t *param) {
+    BIGNUM *r = (BIGNUM *)read32(&param[0]);
+    BIGNUM *range = (BIGNUM *)read32(&param[1]);
+    return (uint32_t) BN_rand_range(r, range);
+}
+
diff --git a/arm/crypto/openssl/bn/bn_asm.c b/arm/crypto/openssl/bn/bn_asm.c
new file mode 100644 (file)
index 0000000..2e665da
--- /dev/null
@@ -0,0 +1,851 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// added 'const' to bn_sqr_comba4 and bn_sqr_comba8 to match bn_lcl.h
+
+#include "bn_lcl.h"
+
+#if defined(BN_LLONG) || defined(BN_UMULT_HIGH)
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
+       {
+       BN_ULONG c1=0;
+
+       assert(num >= 0);
+       if (num <= 0) return(c1);
+
+       while (num&~3)
+               {
+               mul_add(rp[0],ap[0],w,c1);
+               mul_add(rp[1],ap[1],w,c1);
+               mul_add(rp[2],ap[2],w,c1);
+               mul_add(rp[3],ap[3],w,c1);
+               ap+=4; rp+=4; num-=4;
+               }
+       if (num)
+               {
+               mul_add(rp[0],ap[0],w,c1); if (--num==0) return c1;
+               mul_add(rp[1],ap[1],w,c1); if (--num==0) return c1;
+               mul_add(rp[2],ap[2],w,c1); return c1;
+               }
+       
+       return(c1);
+       } 
+
+BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
+       {
+       BN_ULONG c1=0;
+
+       assert(num >= 0);
+       if (num <= 0) return(c1);
+
+       while (num&~3)
+               {
+               mul(rp[0],ap[0],w,c1);
+               mul(rp[1],ap[1],w,c1);
+               mul(rp[2],ap[2],w,c1);
+               mul(rp[3],ap[3],w,c1);
+               ap+=4; rp+=4; num-=4;
+               }
+       if (num)
+               {
+               mul(rp[0],ap[0],w,c1); if (--num == 0) return c1;
+               mul(rp[1],ap[1],w,c1); if (--num == 0) return c1;
+               mul(rp[2],ap[2],w,c1);
+               }
+       return(c1);
+       } 
+
+void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
+        {
+       assert(n >= 0);
+       if (n <= 0) return;
+       while (n&~3)
+               {
+               sqr(r[0],r[1],a[0]);
+               sqr(r[2],r[3],a[1]);
+               sqr(r[4],r[5],a[2]);
+               sqr(r[6],r[7],a[3]);
+               a+=4; r+=8; n-=4;
+               }
+       if (n)
+               {
+               sqr(r[0],r[1],a[0]); if (--n == 0) return;
+               sqr(r[2],r[3],a[1]); if (--n == 0) return;
+               sqr(r[4],r[5],a[2]);
+               }
+       }
+
+#else /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
+       {
+       BN_ULONG c=0;
+       BN_ULONG bl,bh;
+
+       assert(num >= 0);
+       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, const BN_ULONG *ap, int num, BN_ULONG w)
+       {
+       BN_ULONG carry=0;
+       BN_ULONG bl,bh;
+
+       assert(num >= 0);
+       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, const BN_ULONG *a, int n)
+        {
+       assert(n >= 0);
+       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 /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
+
+#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);
+       assert((i == BN_BITS2) || (h > (BN_ULONG)1<<i));
+
+       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 /* !defined(BN_LLONG) && defined(BN_DIV2W) */
+
+#ifdef BN_LLONG
+BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
+        {
+       BN_ULLONG ll=0;
+
+       assert(n >= 0);
+       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_LLONG */
+BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
+        {
+       BN_ULONG c,l,t;
+
+       assert(n >= 0);
+       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_LLONG */
+
+BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
+        {
+       BN_ULONG t1,t2;
+       int c=0;
+
+       assert(n >= 0);
+       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
+
+/* mul_add_c(a,b,c0,c1,c2)  -- c+=a*b for three word number c=(c2,c1,c0) */
+/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */
+/* sqr_add_c(a,i,c0,c1,c2)  -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
+/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
+
+#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)
+
+#elif defined(BN_UMULT_HIGH)
+
+#define mul_add_c(a,b,c0,c1,c2)        {       \
+       BN_ULONG ta=(a),tb=(b);         \
+       t1 = ta * tb;                   \
+       t2 = BN_UMULT_HIGH(ta,tb);      \
+       c0 += t1; t2 += (c0<t1)?1:0;    \
+       c1 += t2; c2 += (c1<t2)?1:0;    \
+       }
+
+#define mul_add_c2(a,b,c0,c1,c2) {     \
+       BN_ULONG ta=(a),tb=(b),t0;      \
+       t1 = BN_UMULT_HIGH(ta,tb);      \
+       t0 = ta * tb;                   \
+       t2 = t1+t1; c2 += (t2<t1)?1:0;  \
+       t1 = t0+t0; t2 += (t1<t0)?1:0;  \
+       c0 += t1; t2 += (c0<t1)?1:0;    \
+       c1 += t2; c2 += (c1<t2)?1:0;    \
+       }
+
+#define sqr_add_c(a,i,c0,c1,c2)        {       \
+       BN_ULONG ta=(a)[i];             \
+       t1 = ta * ta;                   \
+       t2 = BN_UMULT_HIGH(ta,ta);      \
+       c0 += t1; t2 += (c0<t1)?1:0;    \
+       c1 += t2; c2 += (c1<t2)?1:0;    \
+       }
+
+#define sqr_add_c2(a,i,j,c0,c1,c2)     \
+       mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+
+#else /* !BN_LLONG */
+#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 /* !BN_LLONG */
+
+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, const 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, const 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 /* !BN_MUL_COMBA */
+
+/* hmm... is it faster just to do a multiply? */
+#undef bn_sqr_comba4
+void bn_sqr_comba4(BN_ULONG *r, const 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, const 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_MUL_COMBA */
diff --git a/arm/crypto/openssl/bn/bn_ctx.c b/arm/crypto/openssl/bn/bn_ctx.c
new file mode 100644 (file)
index 0000000..9c8c995
--- /dev/null
@@ -0,0 +1,175 @@
+/* crypto/bn/bn_ctx.c */
+/* Written by Ulf Moeller for the OpenSSL project. */
+/* ====================================================================
+ * Copyright (c) 1998-2000 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).
+ *
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// changed OPENSSL_malloc to arena_malloc
+// changed OPENSSL_free to arena_free
+
+
+#include "bn_lcl.h"
+
+
+BN_CTX *BN_CTX_new(void)
+       {
+       BN_CTX *ret;
+
+       ret=(BN_CTX *)arena_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)
+       {
+#if 0 /* explicit version */
+       int i;
+       ctx->tos = 0;
+       ctx->flags = 0;
+       ctx->depth = 0;
+       ctx->too_many = 0;
+       for (i = 0; i < BN_CTX_NUM; i++)
+               BN_init(&(ctx->bn[i]));
+#else
+       memset(ctx, 0, sizeof *ctx);
+#endif
+       }
+
+void BN_CTX_free(BN_CTX *ctx)
+       {
+       int i;
+
+       if (ctx == NULL) return;
+       assert(ctx->depth == 0);
+
+       for (i=0; i < BN_CTX_NUM; i++)
+               BN_clear_free(&(ctx->bn[i]));
+       if (ctx->flags & BN_FLG_MALLOCED)
+               arena_free(ctx);
+       }
+
+void BN_CTX_start(BN_CTX *ctx)
+       {
+       if (ctx->depth < BN_CTX_NUM_POS)
+               ctx->pos[ctx->depth] = ctx->tos;
+       ctx->depth++;
+       }
+
+
+BIGNUM *BN_CTX_get(BN_CTX *ctx)
+       {
+       /* Note: If BN_CTX_get is ever changed to allocate BIGNUMs dynamically,
+        * make sure that if BN_CTX_get fails once it will return NULL again
+        * until BN_CTX_end is called.  (This is so that callers have to check
+        * only the last return value.)
+        */
+       if (ctx->depth > BN_CTX_NUM_POS || ctx->tos >= BN_CTX_NUM)
+               {
+               if (!ctx->too_many)
+                       {
+                       BNerr(BN_F_BN_CTX_GET,BN_R_TOO_MANY_TEMPORARY_VARIABLES);
+                       /* disable error code until BN_CTX_end is called: */
+                       ctx->too_many = 1;
+                       }
+               return NULL;
+               }
+       return (&(ctx->bn[ctx->tos++]));
+       }
+
+void BN_CTX_end(BN_CTX *ctx)
+       {
+       if (ctx == NULL) return;
+       assert(ctx->depth > 0);
+       if (ctx->depth == 0)
+               /* should never happen, but we can tolerate it if not in
+                * debug mode (could be a 'goto err' in the calling function
+                * before BN_CTX_start was reached) */
+               BN_CTX_start(ctx);
+
+       ctx->too_many = 0;
+       ctx->depth--;
+       if (ctx->depth < BN_CTX_NUM_POS)
+               ctx->tos = ctx->pos[ctx->depth];
+       }
diff --git a/arm/crypto/openssl/bn/bn_div.c b/arm/crypto/openssl/bn/bn_div.c
new file mode 100644 (file)
index 0000000..e873bec
--- /dev/null
@@ -0,0 +1,412 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// use "the old slow way" for BN_div (fixme fast way crashes on ARM)
+// added p68K to BN_init call
+
+#include "bn_lcl.h"
+
+
+/* The old slow way */
+#if 1
+int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
+          BN_CTX *ctx)
+       {
+       int i,nm,nd;
+       int ret = 0;
+       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);
+               }
+
+       BN_CTX_start(ctx);
+       D = BN_CTX_get(ctx);
+       if (dv == NULL) dv = BN_CTX_get(ctx);
+       if (rem == NULL) rem = BN_CTX_get(ctx);
+       if (D == NULL || dv == NULL || rem == NULL)
+               goto end;
+
+       nd=BN_num_bits(d);
+       nm=BN_num_bits(m);
+       if (BN_copy(D,d) == NULL) goto end;
+       if (BN_copy(rem,m) == NULL) goto end;
+
+       /* 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)) goto end;
+       for (i=nm-nd; i>=0; i--)
+               {
+               if (!BN_lshift1(dv,dv)) goto end;
+               if (BN_ucmp(rem,D) >= 0)
+                       {
+                       dv->d[0]|=1;
+                       if (!BN_usub(rem,rem,D)) goto end;
+                       }
+/* CAN IMPROVE (and have now :=) */
+               if (!BN_rshift1(D,D)) goto end;
+               }
+       rem->neg=BN_is_zero(rem)?0:m->neg;
+       dv->neg=m->neg^d->neg;
+       ret = 1;
+ end:
+       BN_CTX_end(ctx);
+       return(ret);
+       }
+
+#else
+
+#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) \
+    && !defined(PEDANTIC) && !defined(BN_DIV3W)
+# if defined(__GNUC__) && __GNUC__>=2
+#  if defined(__i386) || 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 REMAINDER_IS_ALREADY_CALCULATED
+#  elif defined(__x86_64) && defined(SIXTY_FOUR_BIT_LONG)
+   /*
+    * Same story here, but it's 128-bit by 64-bit division. Wow!
+    *                                  <appro@fy.chalmers.se>
+    */
+#  define bn_div_words(n0,n1,d0)               \
+       ({  asm volatile (                      \
+               "divq   %4"                     \
+               : "=a"(q), "=d"(rem)            \
+               : "a"(n1), "d"(n0), "g"(d0)     \
+               : "cc");                        \
+           q;                                  \
+       })
+#  define REMAINDER_IS_ALREADY_CALCULATED
+#  endif /* __<cpu> */
+# endif /* __GNUC__ */
+#endif /* OPENSSL_NO_ASM */
+
+
+/* BN_div computes  dv := num / divisor,  rounding towards zero, and sets up
+ * rm  such that  dv*divisor + rm = num  holds.
+ * Thus:
+ *     dv->neg == num->neg ^ divisor->neg  (unless the result is zero)
+ *     rm->neg == num->neg                 (unless the remainder is zero)
+ * If 'dv' or 'rm' is NULL, the respective value is not returned.
+ */
+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);
+               }
+
+       BN_CTX_start(ctx);
+       tmp=BN_CTX_get(ctx);
+       snum=BN_CTX_get(ctx);
+       sdiv=BN_CTX_get(ctx);
+       if (dv == NULL)
+               res=BN_CTX_get(ctx);
+       else    res=dv;
+       if (sdiv == NULL || res == NULL) goto err;
+       tmp->neg=0;
+
+       /* First we normalise the numbers */
+       norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2);
+       if (!(BN_lshift(sdiv,divisor,norm_shift))) goto err;
+       sdiv->neg=0;
+       norm_shift+=BN_BITS2;
+       if (!(BN_lshift(snum,num,norm_shift))) goto err;
+       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.dmax= snum->dmax+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--;
+       if (res->top == 0)
+               res->neg = 0;
+       resp--;
+
+       for (i=0; i<loop-1; i++)
+               {
+               BN_ULONG q,l0;
+#if defined(BN_DIV3W) && !defined(OPENSSL_NO_ASM)
+               BN_ULONG bn_div_3_words(BN_ULONG*,BN_ULONG,BN_ULONG);
+               q=bn_div_3_words(wnump,d1,d0);
+#else
+               BN_ULONG n0,n1,rem=0;
+
+               n0=wnump[0];
+               n1=wnump[-1];
+               if (n0 == d0)
+                       q=BN_MASK2;
+               else                    /* n0 < d0 */
+                       {
+#ifdef BN_LLONG
+                       BN_ULLONG t2;
+
+#if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words)
+                       q=(BN_ULONG)(((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0);
+#else
+                       q=bn_div_words(n0,n1,d0);
+#ifdef BN_DEBUG_LEVITTE
+                       fprintf(stderr,"DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
+X) -> 0x%08X\n",
+                               n0, n1, d0, q);
+#endif
+#endif
+
+#ifndef REMAINDER_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_LLONG */
+                       BN_ULONG t2l,t2h,ql,qh;
+
+                       q=bn_div_words(n0,n1,d0);
+#ifdef BN_DEBUG_LEVITTE
+                       fprintf(stderr,"DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
+X) -> 0x%08X\n",
+                               n0, n1, d0, q);
+#endif
+#ifndef REMAINDER_IS_ALREADY_CALCULATED
+                       rem=(n1-q*d0)&BN_MASK2;
+#endif
+
+#if defined(BN_UMULT_LOHI)
+                       BN_UMULT_LOHI(t2l,t2h,d1,q);
+#elif defined(BN_UMULT_HIGH)
+                       t2l = d1 * q;
+                       t2h = BN_UMULT_HIGH(d1,q);
+#else
+                       t2l=LBITS(d1); t2h=HBITS(d1);
+                       ql =LBITS(q);  qh =HBITS(q);
+                       mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */
+#endif
+
+                       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 /* !BN_LLONG */
+                       }
+#endif /* !BN_DIV3W */
+
+               l0=bn_mul_words(tmp->d,sdiv->d,div_n,q);
+               wnum.d--; wnum.top++;
+               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;
+               if (!BN_sub(&wnum,&wnum,tmp)) goto err;
+
+               snum->top=snum->top+wnum.top-j;
+
+               if (wnum.neg)
+                       {
+                       q--;
+                       j=wnum.top;
+                       if (!BN_add(&wnum,&wnum,sdiv)) goto err;
+                       snum->top+=wnum.top-j;
+                       }
+               *(resp--)=q;
+               wnump--;
+               }
+       if (rm != NULL)
+               {
+               /* Keep a copy of the neg flag in num because if rm==num
+                * BN_rshift() will overwrite it.
+                */
+               int neg = num->neg;
+               BN_rshift(rm,snum,norm_shift);
+               if (!BN_is_zero(rm))
+                       rm->neg = neg;
+               }
+       BN_CTX_end(ctx);
+       return(1);
+err:
+       BN_CTX_end(ctx);
+       return(0);
+       }
+
+#endif
diff --git a/arm/crypto/openssl/bn/bn_exp.c b/arm/crypto/openssl/bn/bn_exp.c
new file mode 100644 (file)
index 0000000..4196a55
--- /dev/null
@@ -0,0 +1,774 @@
+/* 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.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 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).
+ *
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// changed BN_value_one() call to local variable to avoid global data
+
+#include "bn_lcl.h"
+
+#define TABLE_SIZE     32
+
+/* this one works - simple but works */
+int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+       {
+       int i,bits,ret=0;
+       BIGNUM *v,*rr;
+
+       BN_CTX_start(ctx);
+       if ((r == a) || (r == p))
+               rr = BN_CTX_get(ctx);
+       else
+               rr = r;
+       if ((v = BN_CTX_get(ctx)) == NULL) goto err;
+
+       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:
+       if (r != rr) BN_copy(r,rr);
+       BN_CTX_end(ctx);
+       return(ret);
+       }
+
+
+int BN_mod_exp(BIGNUM *r, const 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);
+
+       /* For even modulus  m = 2^k*m_odd,  it might make sense to compute
+        * a^p mod m_odd  and  a^p mod 2^k  separately (with Montgomery
+        * exponentiation for the odd part), using appropriate exponent
+        * reductions, and combine the results using the CRT.
+        *
+        * For now, we use Montgomery only if the modulus is odd; otherwise,
+        * exponentiation using the reciprocal-based quick remaindering
+        * algorithm is used.
+        *
+        * (Timing obtained with expspeed.c [computations  a^p mod m
+        * where  a, p, m  are of the same length: 256, 512, 1024, 2048,
+        * 4096, 8192 bits], compared to the running time of the
+        * standard algorithm:
+        *
+        *   BN_mod_exp_mont   33 .. 40 %  [AMD K6-2, Linux, debug configuration]
+         *                     55 .. 77 %  [UltraSparc processor, but
+        *                                  debug-solaris-sparcv8-gcc conf.]
+        * 
+        *   BN_mod_exp_recp   50 .. 70 %  [AMD K6-2, Linux, debug configuration]
+        *                     62 .. 118 % [UltraSparc, debug-solaris-sparcv8-gcc]
+        *
+        * On the Sparc, BN_mod_exp_recp was faster than BN_mod_exp_mont
+        * at 2048 and more bits, but at 512 and 1024 bits, it was
+        * slower even than the standard algorithm!
+        *
+        * "Real" timings [linux-elf, solaris-sparcv9-gcc configurations]
+        * should be obtained when the new Montgomery reduction code
+        * has been integrated into OpenSSL.)
+        */
+
+#define MONT_MUL_MOD
+#define MONT_EXP_WORD
+#define RECP_MUL_MOD
+
+#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))
+               {
+#  ifdef MONT_EXP_WORD
+               if (a->top == 1 && !a->neg)
+                       {
+                       BN_ULONG A = a->d[0];
+                       ret=BN_mod_exp_mont_word(r,A,p,m,ctx,NULL);
+                       }
+               else
+#  endif
+                       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);
+       }
+
+
+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;
+
+       bits=BN_num_bits(p);
+
+       if (bits == 0)
+               {
+               ret = BN_one(r);
+               return ret;
+               }
+
+       BN_CTX_start(ctx);
+       if ((aa = BN_CTX_get(ctx)) == NULL) goto err;
+
+       BN_RECP_CTX_init(&recp);
+       if (m->neg)
+               {
+               /* ignore sign of 'm' */
+               if (!BN_copy(aa, m)) goto err;
+               aa->neg = 0;
+               if (BN_RECP_CTX_set(&recp,aa,ctx) <= 0) goto err;
+               }
+       else
+               {
+               if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err;
+               }
+
+       BN_init(&(val[0]));
+       ts=1;
+
+       if (!BN_nnmod(&(val[0]),a,m,ctx)) goto err;             /* 1 */
+       if (BN_is_zero(&(val[0])))
+               {
+               ret = BN_zero(r);
+               goto err;
+               }
+
+       window = BN_window_bits_for_exponent_size(bits);
+       if (window > 1)
+               {
+               if (!BN_mod_mul_reciprocal(aa,&(val[0]),&(val[0]),&recp,ctx))
+                       goto err;                               /* 2 */
+               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:
+       BN_CTX_end(ctx);
+       for (i=0; i<ts; i++)
+               BN_clear_free(&(val[i]));
+       BN_RECP_CTX_free(&recp);
+       return(ret);
+       }
+
+
+int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
+                   const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
+       {
+       BN_ULONG BN_data_one=1L;
+       BIGNUM BN_const_one={&BN_data_one,1,1,0,0};
+       int i,j,bits,ret=0,wstart,wend,window,wvalue;
+       int start=1,ts=0;
+       BIGNUM *d,*r;
+       const 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);
+               }
+       bits=BN_num_bits(p);
+       if (bits == 0)
+               {
+               ret = BN_one(rr);
+               return ret;
+               }
+
+       BN_CTX_start(ctx);
+       d = BN_CTX_get(ctx);
+       r = BN_CTX_get(ctx);
+       if (d == NULL || r == NULL) goto err;
+
+       /* 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]);
+       ts=1;
+       if (a->neg || BN_ucmp(a,m) >= 0)
+               {
+               if (!BN_nnmod(&(val[0]),a,m,ctx))
+                       goto err;
+               aa= &(val[0]);
+               }
+       else
+               aa=a;
+       if (BN_is_zero(aa))
+               {
+               ret = BN_zero(rr);
+               goto err;
+               }
+       if (!BN_to_montgomery(&(val[0]),aa,mont,ctx)) goto err; /* 1 */
+
+       window = BN_window_bits_for_exponent_size(bits);
+       if (window > 1)
+               {
+               if (!BN_mod_mul_montgomery(d,&(val[0]),&(val[0]),mont,ctx)) goto err; /* 2 */
+               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_const_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;
+               }
+       if (!BN_from_montgomery(rr,r,mont,ctx)) goto err;
+       ret=1;
+err:
+       if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
+       BN_CTX_end(ctx);
+       for (i=0; i<ts; i++)
+               BN_clear_free(&(val[i]));
+       return(ret);
+       }
+
+int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
+                         const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
+       {
+       BN_MONT_CTX *mont = NULL;
+       int b, bits, ret=0;
+       int r_is_one;
+       BN_ULONG w, next_w;
+       BIGNUM *d, *r, *t;
+       BIGNUM *swap_tmp;
+#define BN_MOD_MUL_WORD(r, w, m) \
+               (BN_mul_word(r, (w)) && \
+               (/* BN_ucmp(r, (m)) < 0 ? 1 :*/  \
+                       (BN_mod(t, r, m, ctx) && (swap_tmp = r, r = t, t = swap_tmp, 1))))
+               /* BN_MOD_MUL_WORD is only used with 'w' large,
+                * so the BN_ucmp test is probably more overhead
+                * than always using BN_mod (which uses BN_copy if
+                * a similar test returns true). */
+               /* We can use BN_mod and do not need BN_nnmod because our
+                * accumulator is never negative (the result of BN_mod does
+                * not depend on the sign of the modulus).
+                */
+#define BN_TO_MONTGOMERY_WORD(r, w, mont) \
+               (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx))
+
+       bn_check_top(p);
+       bn_check_top(m);
+
+       if (m->top == 0 || !(m->d[0] & 1))
+               {
+               BNerr(BN_F_BN_MOD_EXP_MONT_WORD,BN_R_CALLED_WITH_EVEN_MODULUS);
+               return(0);
+               }
+       if (m->top == 1)
+               a %= m->d[0]; /* make sure that 'a' is reduced */
+
+       bits = BN_num_bits(p);
+       if (bits == 0)
+               {
+               ret = BN_one(rr);
+               return ret;
+               }
+       if (a == 0)
+               {
+               ret = BN_zero(rr);
+               return ret;
+               }
+
+       BN_CTX_start(ctx);
+       d = BN_CTX_get(ctx);
+       r = BN_CTX_get(ctx);
+       t = BN_CTX_get(ctx);
+       if (d == NULL || r == NULL || t == NULL) goto err;
+
+       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;
+               }
+
+       r_is_one = 1; /* except for Montgomery factor */
+
+       /* bits-1 >= 0 */
+
+       /* The result is accumulated in the product r*w. */
+       w = a; /* bit 'bits-1' of 'p' is always set */
+       for (b = bits-2; b >= 0; b--)
+               {
+               /* First, square r*w. */
+               next_w = w*w;
+               if ((next_w/w) != w) /* overflow */
+                       {
+                       if (r_is_one)
+                               {
+                               if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) goto err;
+                               r_is_one = 0;
+                               }
+                       else
+                               {
+                               if (!BN_MOD_MUL_WORD(r, w, m)) goto err;
+                               }
+                       next_w = 1;
+                       }
+               w = next_w;
+               if (!r_is_one)
+                       {
+                       if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) goto err;
+                       }
+
+               /* Second, multiply r*w by 'a' if exponent bit is set. */
+               if (BN_is_bit_set(p, b))
+                       {
+                       next_w = w*a;
+                       if ((next_w/a) != w) /* overflow */
+                               {
+                               if (r_is_one)
+                                       {
+                                       if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) goto err;
+                                       r_is_one = 0;
+                                       }
+                               else
+                                       {
+                                       if (!BN_MOD_MUL_WORD(r, w, m)) goto err;
+                                       }
+                               next_w = a;
+                               }
+                       w = next_w;
+                       }
+               }
+
+       /* Finally, set r:=r*w. */
+       if (w != 1)
+               {
+               if (r_is_one)
+                       {
+                       if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) goto err;
+                       r_is_one = 0;
+                       }
+               else
+                       {
+                       if (!BN_MOD_MUL_WORD(r, w, m)) goto err;
+                       }
+               }
+
+       if (r_is_one) /* can happen only if a == 1*/
+               {
+               if (!BN_one(rr)) goto err;
+               }
+       else
+               {
+               if (!BN_from_montgomery(rr, r, mont, ctx)) goto err;
+               }
+       ret = 1;
+err:
+       if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
+       BN_CTX_end(ctx);
+       return(ret);
+       }
+
+
+/* The old fallback, simple version :-) */
+int BN_mod_exp_simple(BIGNUM *r,
+       const BIGNUM *a, const BIGNUM *p, const 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];
+
+       bits=BN_num_bits(p);
+
+       if (bits == 0)
+               {
+               ret = BN_one(r);
+               return ret;
+               }
+
+       BN_CTX_start(ctx);
+       if ((d = BN_CTX_get(ctx)) == NULL) goto err;
+
+       BN_init(&(val[0]));
+       ts=1;
+       if (!BN_nnmod(&(val[0]),a,m,ctx)) goto err;             /* 1 */
+       if (BN_is_zero(&(val[0])))
+               {
+               ret = BN_zero(r);
+               goto err;
+               }
+
+       window = BN_window_bits_for_exponent_size(bits);
+       if (window > 1)
+               {
+               if (!BN_mod_mul(d,&(val[0]),&(val[0]),m,ctx))
+                       goto err;                               /* 2 */
+               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:
+       BN_CTX_end(ctx);
+       for (i=0; i<ts; i++)
+               BN_clear_free(&(val[i]));
+       return(ret);
+       }
+
diff --git a/arm/crypto/openssl/bn/bn_gcd.c b/arm/crypto/openssl/bn/bn_gcd.c
new file mode 100644 (file)
index 0000000..7f2e5df
--- /dev/null
@@ -0,0 +1,515 @@
+/* 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.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 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).
+ *
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+
+#include "bn_lcl.h"
+
+static BIGNUM *euclid(BIGNUM *a, BIGNUM *b);
+
+int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
+       {
+       BIGNUM *a,*b,*t;
+       int ret=0;
+
+       bn_check_top(in_a);
+       bn_check_top(in_b);
+
+       BN_CTX_start(ctx);
+       a = BN_CTX_get(ctx);
+       b = BN_CTX_get(ctx);
+       if (a == NULL || b == NULL) goto err;
+
+       if (BN_copy(a,in_a) == NULL) goto err;
+       if (BN_copy(b,in_b) == NULL) goto err;
+       a->neg = 0;
+       b->neg = 0;
+
+       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:
+       BN_CTX_end(ctx);
+       return(ret);
+       }
+
+static BIGNUM *euclid(BIGNUM *a, BIGNUM *b)
+       {
+       BIGNUM *t;
+       int shifts=0;
+
+       bn_check_top(a);
+       bn_check_top(b);
+
+       /* 0 <= b <= a */
+       while (!BN_is_zero(b))
+               {
+               /* 0 < b <= a */
+
+               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++;
+                               }
+                       }
+               /* 0 <= b <= a */
+               }
+
+       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,
+       const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
+       {
+       BIGNUM *A,*B,*X,*Y,*M,*D,*T,*R=NULL;
+       BIGNUM *ret=NULL;
+       int sign;
+
+       bn_check_top(a);
+       bn_check_top(n);
+
+       BN_CTX_start(ctx);
+       A = BN_CTX_get(ctx);
+       B = BN_CTX_get(ctx);
+       X = BN_CTX_get(ctx);
+       D = BN_CTX_get(ctx);
+       M = BN_CTX_get(ctx);
+       Y = BN_CTX_get(ctx);
+       T = BN_CTX_get(ctx);
+       if (T == NULL) goto err;
+
+       if (in == NULL)
+               R=BN_new();
+       else
+               R=in;
+       if (R == NULL) goto err;
+
+       BN_one(X);
+       BN_zero(Y);
+       if (BN_copy(B,a) == NULL) goto err;
+       if (BN_copy(A,n) == NULL) goto err;
+       A->neg = 0;
+       if (B->neg || (BN_ucmp(B, A) >= 0))
+               {
+               if (!BN_nnmod(B, B, A, ctx)) goto err;
+               }
+       sign = -1;
+       /* From  B = a mod |n|,  A = |n|  it follows that
+        *
+        *      0 <= B < A,
+        *     -sign*X*a  ==  B   (mod |n|),
+        *      sign*Y*a  ==  A   (mod |n|).
+        */
+
+       if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048)))
+               {
+               /* Binary inversion algorithm; requires odd modulus.
+                * This is faster than the general algorithm if the modulus
+                * is sufficiently small (about 400 .. 500 bits on 32-bit
+                * sytems, but much more on 64-bit systems) */
+               int shift;
+               
+               while (!BN_is_zero(B))
+                       {
+                       /*
+                        *      0 < B < |n|,
+                        *      0 < A <= |n|,
+                        * (1) -sign*X*a  ==  B   (mod |n|),
+                        * (2)  sign*Y*a  ==  A   (mod |n|)
+                        */
+
+                       /* Now divide  B  by the maximum possible power of two in the integers,
+                        * and divide  X  by the same value mod |n|.
+                        * When we're done, (1) still holds. */
+                       shift = 0;
+                       while (!BN_is_bit_set(B, shift)) /* note that 0 < B */
+                               {
+                               shift++;
+                               
+                               if (BN_is_odd(X))
+                                       {
+                                       if (!BN_uadd(X, X, n)) goto err;
+                                       }
+                               /* now X is even, so we can easily divide it by two */
+                               if (!BN_rshift1(X, X)) goto err;
+                               }
+                       if (shift > 0)
+                               {
+                               if (!BN_rshift(B, B, shift)) goto err;
+                               }
+
+
+                       /* Same for  A  and  Y.  Afterwards, (2) still holds. */
+                       shift = 0;
+                       while (!BN_is_bit_set(A, shift)) /* note that 0 < A */
+                               {
+                               shift++;
+                               
+                               if (BN_is_odd(Y))
+                                       {
+                                       if (!BN_uadd(Y, Y, n)) goto err;
+                                       }
+                               /* now Y is even */
+                               if (!BN_rshift1(Y, Y)) goto err;
+                               }
+                       if (shift > 0)
+                               {
+                               if (!BN_rshift(A, A, shift)) goto err;
+                               }
+
+                       
+                       /* We still have (1) and (2).
+                        * Both  A  and  B  are odd.
+                        * The following computations ensure that
+                        *
+                        *     0 <= B < |n|,
+                        *      0 < A < |n|,
+                        * (1) -sign*X*a  ==  B   (mod |n|),
+                        * (2)  sign*Y*a  ==  A   (mod |n|),
+                        *
+                        * and that either  A  or  B  is even in the next iteration.
+                        */
+                       if (BN_ucmp(B, A) >= 0)
+                               {
+                               /* -sign*(X + Y)*a == B - A  (mod |n|) */
+                               if (!BN_uadd(X, X, Y)) goto err;
+                               /* NB: we could use BN_mod_add_quick(X, X, Y, n), but that
+                                * actually makes the algorithm slower */
+                               if (!BN_usub(B, B, A)) goto err;
+                               }
+                       else
+                               {
+                               /*  sign*(X + Y)*a == A - B  (mod |n|) */
+                               if (!BN_uadd(Y, Y, X)) goto err;
+                               /* as above, BN_mod_add_quick(Y, Y, X, n) would slow things down */
+                               if (!BN_usub(A, A, B)) goto err;
+                               }
+                       }
+               }
+       else
+               {
+               /* general inversion algorithm */
+
+               while (!BN_is_zero(B))
+                       {
+                       BIGNUM *tmp;
+                       
+                       /*
+                        *      0 < B < A,
+                        * (*) -sign*X*a  ==  B   (mod |n|),
+                        *      sign*Y*a  ==  A   (mod |n|)
+                        */
+                       
+                       /* (D, M) := (A/B, A%B) ... */
+                       if (BN_num_bits(A) == BN_num_bits(B))
+                               {
+                               if (!BN_one(D)) goto err;
+                               if (!BN_sub(M,A,B)) goto err;
+                               }
+                       else if (BN_num_bits(A) == BN_num_bits(B) + 1)
+                               {
+                               /* A/B is 1, 2, or 3 */
+                               if (!BN_lshift1(T,B)) goto err;
+                               if (BN_ucmp(A,T) < 0)
+                                       {
+                                       /* A < 2*B, so D=1 */
+                                       if (!BN_one(D)) goto err;
+                                       if (!BN_sub(M,A,B)) goto err;
+                                       }
+                               else
+                                       {
+                                       /* A >= 2*B, so D=2 or D=3 */
+                                       if (!BN_sub(M,A,T)) goto err;
+                                       if (!BN_add(D,T,B)) goto err; /* use D (:= 3*B) as temp */
+                                       if (BN_ucmp(A,D) < 0)
+                                               {
+                                               /* A < 3*B, so D=2 */
+                                               if (!BN_set_word(D,2)) goto err;
+                                               /* M (= A - 2*B) already has the correct value */
+                                               }
+                                       else
+                                               {
+                                               /* only D=3 remains */
+                                               if (!BN_set_word(D,3)) goto err;
+                                               /* currently  M = A - 2*B,  but we need  M = A - 3*B */
+                                               if (!BN_sub(M,M,B)) goto err;
+                                               }
+                                       }
+                               }
+                       else
+                               {
+                               if (!BN_div(D,M,A,B,ctx)) goto err;
+                               }
+                       
+                       /* Now
+                        *      A = D*B + M;
+                        * thus we have
+                        * (**)  sign*Y*a  ==  D*B + M   (mod |n|).
+                        */
+                       
+                       tmp=A; /* keep the BIGNUM object, the value does not matter */
+                       
+                       /* (A, B) := (B, A mod B) ... */
+                       A=B;
+                       B=M;
+                       /* ... so we have  0 <= B < A  again */
+                       
+                       /* Since the former  M  is now  B  and the former  B  is now  A,
+                        * (**) translates into
+                        *       sign*Y*a  ==  D*A + B    (mod |n|),
+                        * i.e.
+                        *       sign*Y*a - D*A  ==  B    (mod |n|).
+                        * Similarly, (*) translates into
+                        *      -sign*X*a  ==  A          (mod |n|).
+                        *
+                        * Thus,
+                        *   sign*Y*a + D*sign*X*a  ==  B  (mod |n|),
+                        * i.e.
+                        *        sign*(Y + D*X)*a  ==  B  (mod |n|).
+                        *
+                        * So if we set  (X, Y, sign) := (Y + D*X, X, -sign),  we arrive back at
+                        *      -sign*X*a  ==  B   (mod |n|),
+                        *       sign*Y*a  ==  A   (mod |n|).
+                        * Note that  X  and  Y  stay non-negative all the time.
+                        */
+                       
+                       /* most of the time D is very small, so we can optimize tmp := D*X+Y */
+                       if (BN_is_one(D))
+                               {
+                               if (!BN_add(tmp,X,Y)) goto err;
+                               }
+                       else
+                               {
+                               if (BN_is_word(D,2))
+                                       {
+                                       if (!BN_lshift1(tmp,X)) goto err;
+                                       }
+                               else if (BN_is_word(D,4))
+                                       {
+                                       if (!BN_lshift(tmp,X,2)) goto err;
+                                       }
+                               else if (D->top == 1)
+                                       {
+                                       if (!BN_copy(tmp,X)) goto err;
+                                       if (!BN_mul_word(tmp,D->d[0])) goto err;
+                                       }
+                               else
+                                       {
+                                       if (!BN_mul(tmp,D,X,ctx)) goto err;
+                                       }
+                               if (!BN_add(tmp,tmp,Y)) goto err;
+                               }
+                       
+                       M=Y; /* keep the BIGNUM object, the value does not matter */
+                       Y=X;
+                       X=tmp;
+                       sign = -sign;
+                       }
+               }
+               
+       /*
+        * The while loop (Euclid's algorithm) ends when
+        *      A == gcd(a,n);
+        * we have
+        *       sign*Y*a  ==  A  (mod |n|),
+        * where  Y  is non-negative.
+        */
+
+       if (sign < 0)
+               {
+               if (!BN_sub(Y,n,Y)) goto err;
+               }
+       /* Now  Y*a  ==  A  (mod |n|).  */
+       
+
+       if (BN_is_one(A))
+               {
+               /* Y*a == 1  (mod |n|) */
+               if (!Y->neg && BN_ucmp(Y,n) < 0)
+                       {
+                       if (!BN_copy(R,Y)) goto err;
+                       }
+               else
+                       {
+                       if (!BN_nnmod(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);
+       BN_CTX_end(ctx);
+       return(ret);
+       }
diff --git a/arm/crypto/openssl/bn/bn_includes.h b/arm/crypto/openssl/bn/bn_includes.h
new file mode 100644 (file)
index 0000000..79b582c
--- /dev/null
@@ -0,0 +1,36 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef INCLUDES_ARM_H
+#define INCLUDES_ARM_H
+
+#include "includes.h"
+
+#define BNerr(a,b) do { } while (0)
+
+#define asserttop(c) do { if (!(c)) assert_failed(__LINE__); } while (0)
+
+#define OPENSSL_cleanse(a,b) do { } while(0)
+
+#endif
diff --git a/arm/crypto/openssl/bn/bn_internal.h b/arm/crypto/openssl/bn/bn_internal.h
new file mode 100644 (file)
index 0000000..0cfd16b
--- /dev/null
@@ -0,0 +1,474 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// BN-internal version of bn.h
+// defines: no FP, no BIO, 32-bit, long long divide OK, 
+// defines: no MUL_COMBA or SQR_COMBA for code size (fixme revisit for ARM?)
+// use stdint types
+// remove 64-bit and 16-bit and 8-bit definitions
+// removed some prototypes
+// added some prototypes
+
+
+#ifndef HEADER_BN_INTERNAL_H
+#define HEADER_BN_INTERNAL_H
+
+#include "bn_includes.h"
+
+#define OPENSSL_NO_FP_API
+#define OPENSSL_NO_BIO
+#define THIRTY_TWO_BIT
+#define BN_DIV2W
+
+// #define BN_MUL_COMBA
+// #define BN_SQR_COMBA
+#define BN_RECURSION
+
+/* 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 normal cc.  This would
+ * be a common occurrence 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 assembler code. */
+#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || \
+    defined(OPENSSL_SYS_WIN32) || defined(linux)
+# ifndef BN_DIV2W
+#  define BN_DIV2W
+# endif
+#endif
+
+#ifdef THIRTY_TWO_BIT
+#define BN_ULLONG uint64_t
+#define BN_LLONG  int64_t
+#define BN_ULONG  uint32_t
+#define BN_LONG   int32_t
+#define BN_BITS                64
+#define BN_BYTES       4
+#define BN_BITS2       32
+#define BN_BITS4       16
+#ifdef OPENSSL_SYS_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
+
+#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 dmax;       /* Size of the d array. */
+       int neg;        /* one if the number is negative */
+       int flags;
+       } BIGNUM;
+
+/* Used for temp variables (declaration hidden in bn_lcl.h) */
+typedef struct bignum_ctx BN_CTX;
+
+typedef struct bn_blinding_st
+       {
+       int init;
+       BIGNUM *A;
+       BIGNUM *Ai;
+       BIGNUM *mod; /* just a reference */
+       unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b;
+                                 * used only by crypto/rsa/rsa_eay.c, rsa_lib.c */
+       } BN_BLINDING;
+
+/* Used for montgomery multiplication */
+typedef struct bn_mont_ctx_st
+       {
+       int ri;        /* number of bits in R */
+       BIGNUM RR;     /* used to convert to montgomery form */
+       BIGNUM N;      /* The modulus */
+       BIGNUM Ni;     /* R*(1/R mod N) - N*Ni = 1
+                       * (Ni is only stored for bignum algorithm) */
+       BN_ULONG n0;   /* least significant word of Ni */
+       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_prime_checks 0 /* default: select number of iterations
+                            based on the size of the number */
+
+/* number of Miller-Rabin iterations for an error rate  of less than 2^-80
+ * for random 'b'-bit input, b >= 100 (taken from table 4.4 in the Handbook
+ * of Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996];
+ * original paper: Damgaard, Landrock, Pomerance: Average case error estimates
+ * for the strong probable prime test. -- Math. Comp. 61 (1993) 177-194) */
+#define BN_prime_checks_for_size(b) ((b) >= 1300 ?  2 : \
+                                (b) >=  850 ?  3 : \
+                                (b) >=  650 ?  4 : \
+                                (b) >=  550 ?  5 : \
+                                (b) >=  450 ?  6 : \
+                                (b) >=  400 ?  7 : \
+                                (b) >=  350 ?  8 : \
+                                (b) >=  300 ?  9 : \
+                                (b) >=  250 ? 12 : \
+                                (b) >=  200 ? 15 : \
+                                (b) >=  150 ? 18 : \
+                                /* b >= 100 */ 27)
+
+#define BN_num_bytes(a)        ((BN_num_bits(a)+7)/8)
+
+/* Note that BN_abs_is_word does not work reliably for w == 0 */
+#define BN_abs_is_word(a,w) (((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w)))
+#define BN_is_zero(a)       (((a)->top == 0) || BN_abs_is_word(a,0))
+#define BN_is_one(a)        (BN_abs_is_word((a),1) && !(a)->neg)
+#define BN_is_word(a,w)     ((w) ? BN_abs_is_word((a),(w)) && !(a)->neg : \
+                                   BN_is_zero((a)))
+#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) */
+
+void BN_set_negative(BIGNUM *a, int neg);
+int BN_is_negative(const BIGNUM *a);
+BN_CTX *BN_CTX_new(void);
+void   BN_CTX_init(BN_CTX *c);
+void   BN_CTX_free(BN_CTX *c);
+void   BN_CTX_start(BN_CTX *ctx);
+BIGNUM *BN_CTX_get(BN_CTX *ctx);
+void   BN_CTX_end(BN_CTX *ctx);
+int     BN_rand(BIGNUM *rnd, int bits, int top,int bottom);
+int     BN_pseudo_rand(BIGNUM *rnd, int bits, int top,int bottom);
+int    BN_rand_range(BIGNUM *rnd, BIGNUM *range);
+int    BN_pseudo_rand_range(BIGNUM *rnd, BIGNUM *range);
+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);
+void   BN_swap(BIGNUM *a, 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(const 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, const BIGNUM *a, const BIGNUM *b);
+int    BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+int    BN_sqr(BIGNUM *r, const BIGNUM *a,BN_CTX *ctx);
+
+int    BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
+       BN_CTX *ctx);
+#define BN_mod(rem,m,d,ctx) BN_div(NULL,(rem),(m),(d),(ctx))
+int    BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
+int    BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
+int    BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m);
+int    BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
+int    BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m);
+int    BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+       const BIGNUM *m, BN_CTX *ctx);
+int    BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+int    BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+int    BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m);
+int    BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ctx);
+int    BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m);
+
+BN_ULONG BN_mod_word(const 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(const 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, const BIGNUM *a);
+int    BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,BN_CTX *ctx);
+
+int    BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+       const BIGNUM *m,BN_CTX *ctx);
+int    BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int    BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
+       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int    BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1,
+       const BIGNUM *a2, const BIGNUM *p2,const BIGNUM *m,
+       BN_CTX *ctx,BN_MONT_CTX *m_ctx);
+int    BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+       const BIGNUM *m,BN_CTX *ctx);
+
+int    BN_mask_bits(BIGNUM *a,int n);
+#ifndef OPENSSL_NO_FP_API
+int    BN_print_fp(FILE *fp, const BIGNUM *a);
+#endif
+#ifdef HEADER_BIO_H
+int    BN_print(BIO *fp, const BIGNUM *a);
+#else
+int    BN_print(void *fp, const BIGNUM *a);
+#endif
+int    BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx);
+int    BN_rshift(BIGNUM *r, const BIGNUM *a, int n);
+int    BN_rshift1(BIGNUM *r, const BIGNUM *a);
+void   BN_clear(BIGNUM *a);
+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);
+int    BN_hex2bn(BIGNUM **a, const char *str);
+int    BN_gcd(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx);
+int    BN_kronecker(const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx); /* returns -2 for error */
+BIGNUM *BN_mod_inverse(BIGNUM *ret,
+       const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
+BIGNUM *BN_mod_sqrt(BIGNUM *ret,
+       const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
+BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe,
+       const BIGNUM *add, const BIGNUM *rem,
+       void (*callback)(int,int,void *),void *cb_arg);
+int    BN_is_prime(const BIGNUM *p,int nchecks,
+       void (*callback)(int,int,void *),
+       BN_CTX *ctx,void *cb_arg);
+int    BN_is_prime_fasttest(const BIGNUM *p,int nchecks,
+       void (*callback)(int,int,void *),BN_CTX *ctx,void *cb_arg,
+       int do_trial_division);
+
+BN_MONT_CTX *BN_MONT_CTX_new(void);
+void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
+int BN_mod_mul_montgomery(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,
+       BN_MONT_CTX *mont, BN_CTX *ctx);
+#define BN_to_montgomery(r,a,mont,ctx) BN_mod_mul_montgomery(\
+       (r),(a),&((mont)->RR),(mont),(ctx))
+int BN_from_montgomery(BIGNUM *r,const 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 *mod,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, const BIGNUM *x, const 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, const BIGNUM *m,
+       BN_RECP_CTX *recp, BN_CTX *ctx);
+
+/* library internal functions */
+
+#define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\
+       (a):bn_expand2((a),(bits)/BN_BITS2+1))
+#define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words)))
+BIGNUM *bn_expand2(BIGNUM *a, int words);
+BIGNUM *bn_dup_expand(const BIGNUM *a, int words);
+
+#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; \
+               } \
+       }
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
+BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
+void     bn_sqr_words(BN_ULONG *rp, const 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, const BN_ULONG *ap, const BN_ULONG *bp,int num);
+BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num);
+
+#ifdef BN_DEBUG
+void bn_dump1(FILE *o, const char *a, const BN_ULONG *b,int n);
+# define bn_print(a) {fprintf(stderr, #a "="); BN_print_fp(stderr,a); \
+   fprintf(stderr,"\n");}
+# define bn_dump(a,n) bn_dump1(stderr,#a,a,n);
+#else
+# define bn_print(a)
+# define bn_dump(a,b)
+#endif
+
+int BN_bntest_rand(BIGNUM *rnd, int bits, int top,int bottom);
+
+/* 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.
+ */
+void ERR_load_BN_strings(void);
+
+/* 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_GET                                         116
+#define BN_F_BN_CTX_NEW                                         106
+#define BN_F_BN_DIV                                     107
+#define BN_F_BN_EXPAND2                                         108
+#define BN_F_BN_EXPAND_INTERNAL                                 120
+#define BN_F_BN_MOD_EXP2_MONT                           118
+#define BN_F_BN_MOD_EXP_MONT                            109
+#define BN_F_BN_MOD_EXP_MONT_WORD                       117
+#define BN_F_BN_MOD_INVERSE                             110
+#define BN_F_BN_MOD_LSHIFT_QUICK                        119
+#define BN_F_BN_MOD_MUL_RECIPROCAL                      111
+#define BN_F_BN_MOD_SQRT                                121
+#define BN_F_BN_MPI2BN                                  112
+#define BN_F_BN_NEW                                     113
+#define BN_F_BN_RAND                                    114
+#define BN_F_BN_RAND_RANGE                              122
+#define BN_F_BN_USUB                                    115
+
+/* Reason codes. */
+#define BN_R_ARG2_LT_ARG3                               100
+#define BN_R_BAD_RECIPROCAL                             101
+#define BN_R_BIGNUM_TOO_LONG                            114
+#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_INPUT_NOT_REDUCED                          110
+#define BN_R_INVALID_LENGTH                             106
+#define BN_R_INVALID_RANGE                              115
+#define BN_R_NOT_A_SQUARE                               111
+#define BN_R_NOT_INITIALIZED                            107
+#define BN_R_NO_INVERSE                                         108
+#define BN_R_P_IS_NOT_PRIME                             112
+#define BN_R_TOO_MANY_ITERATIONS                        113
+#define BN_R_TOO_MANY_TEMPORARY_VARIABLES               109
+
+#endif
diff --git a/arm/crypto/openssl/bn/bn_lcl.h b/arm/crypto/openssl/bn/bn_lcl.h
new file mode 100644 (file)
index 0000000..a42ab43
--- /dev/null
@@ -0,0 +1,480 @@
+/* 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.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 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).
+ *
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// redefined bn_check_top
+// added correct prototypes for bn_mul_recursive and bn_mul_part_recursive
+
+#ifndef HEADER_BN_LCL_H
+#define HEADER_BN_LCL_H
+
+#include "bn_internal.h"
+
+/* Used for temp variables */
+#define BN_CTX_NUM     32
+#define BN_CTX_NUM_POS 12
+struct bignum_ctx
+       {
+       int tos;
+       BIGNUM bn[BN_CTX_NUM];
+       int flags;
+       int depth;
+       int pos[BN_CTX_NUM_POS];
+       int too_many;
+       } /* BN_CTX */;
+
+
+/*
+ * BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions
+ *
+ *
+ * For window size 'w' (w >= 2) and a random 'b' bits exponent,
+ * the number of multiplications is a constant plus on average
+ *
+ *    2^(w-1) + (b-w)/(w+1);
+ *
+ * here  2^(w-1)  is for precomputing the table (we actually need
+ * entries only for windows that have the lowest bit set), and
+ * (b-w)/(w+1)  is an approximation for the expected number of
+ * w-bit windows, not counting the first one.
+ *
+ * Thus we should use
+ *
+ *    w >= 6  if        b > 671
+ *     w = 5  if  671 > b > 239
+ *     w = 4  if  239 > b >  79
+ *     w = 3  if   79 > b >  23
+ *    w <= 2  if   23 > b
+ *
+ * (with draws in between).  Very small exponents are often selected
+ * with low Hamming weight, so we use  w = 1  for b <= 23.
+ */
+#if 1
+#define BN_window_bits_for_exponent_size(b) \
+               ((b) > 671 ? 6 : \
+                (b) > 239 ? 5 : \
+                (b) >  79 ? 4 : \
+                (b) >  23 ? 3 : 1)
+#else
+/* Old SSLeay/OpenSSL table.
+ * Maximum window size was 5, so this table differs for b==1024;
+ * but it coincides for other interesting values (b==160, b==512).
+ */
+#define BN_window_bits_for_exponent_size(b) \
+               ((b) > 255 ? 5 : \
+                (b) > 127 ? 4 : \
+                (b) >  17 ? 3 : 1)
+#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 !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
+/*
+ * BN_UMULT_HIGH section.
+ *
+ * No, I'm not trying to overwhelm you when stating that the
+ * product of N-bit numbers is 2*N bits wide:-) No, I don't expect
+ * you to be impressed when I say that if the compiler doesn't
+ * support 2*N integer type, then you have to replace every N*N
+ * multiplication with 4 (N/2)*(N/2) accompanied by some shifts
+ * and additions which unavoidably results in severe performance
+ * penalties. Of course provided that the hardware is capable of
+ * producing 2*N result... That's when you normally start
+ * considering assembler implementation. However! It should be
+ * pointed out that some CPUs (most notably Alpha, PowerPC and
+ * upcoming IA-64 family:-) provide *separate* instruction
+ * calculating the upper half of the product placing the result
+ * into a general purpose register. Now *if* the compiler supports
+ * inline assembler, then it's not impossible to implement the
+ * "bignum" routines (and have the compiler optimize 'em)
+ * exhibiting "native" performance in C. That's what BN_UMULT_HIGH
+ * macro is about:-)
+ *
+ *                                     <appro@fy.chalmers.se>
+ */
+# if defined(__alpha) && (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT))
+#  if defined(__DECC)
+#   include <c_asm.h>
+#   define BN_UMULT_HIGH(a,b)  (BN_ULONG)asm("umulh %a0,%a1,%v0",(a),(b))
+#  elif defined(__GNUC__)
+#   define BN_UMULT_HIGH(a,b)  ({      \
+       register BN_ULONG ret;          \
+       asm ("umulh     %1,%2,%0"       \
+            : "=r"(ret)                \
+            : "r"(a), "r"(b));         \
+       ret;                    })
+#  endif       /* compiler */
+# elif defined(_ARCH_PPC) && defined(__64BIT__) && defined(SIXTY_FOUR_BIT_LONG)
+#  if defined(__GNUC__)
+#   define BN_UMULT_HIGH(a,b)  ({      \
+       register BN_ULONG ret;          \
+       asm ("mulhdu    %0,%1,%2"       \
+            : "=r"(ret)                \
+            : "r"(a), "r"(b));         \
+       ret;                    })
+#  endif       /* compiler */
+# elif defined(__x86_64) && defined(SIXTY_FOUR_BIT_LONG)
+#  if defined(__GNUC__)
+#   define BN_UMULT_HIGH(a,b)  ({      \
+       register BN_ULONG ret,discard;  \
+       asm ("mulq      %3"             \
+            : "=a"(discard),"=d"(ret)  \
+            : "a"(a), "g"(b)           \
+            : "cc");                   \
+       ret;                    })
+#   define BN_UMULT_LOHI(low,high,a,b) \
+       asm ("mulq      %3"             \
+               : "=a"(low),"=d"(high)  \
+               : "a"(a),"g"(b)         \
+               : "cc");
+#  endif
+# endif                /* cpu */
+#endif         /* OPENSSL_NO_ASM */
+
+/*************************************************************
+ * Using the long long type
+ */
+#define Lw(t)    (((BN_ULONG)(t))&BN_MASK2)
+#define Hw(t)    (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
+
+/* This is used for internal error checking and is not normally used */
+#ifdef BN_DEBUG
+# define bn_check_top(a) asserttop ((a)->top >= 0 && (a)->top <= (a)->dmax);
+#else
+# define bn_check_top(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); \
+       }
+
+#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); \
+       }
+
+#define sqr(r0,r1,a) { \
+       BN_ULLONG t; \
+       t=(BN_ULLONG)(a)*(a); \
+       (r0)=Lw(t); \
+       (r1)=Hw(t); \
+       }
+
+#elif defined(BN_UMULT_HIGH)
+#define mul_add(r,a,w,c) {             \
+       BN_ULONG high,low,ret,tmp=(a);  \
+       ret =  (r);                     \
+       high=  BN_UMULT_HIGH(w,tmp);    \
+       ret += (c);                     \
+       low =  (w) * tmp;               \
+       (c) =  (ret<(c))?1:0;           \
+       (c) += high;                    \
+       ret += low;                     \
+       (c) += (ret<low)?1:0;           \
+       (r) =  ret;                     \
+       }
+
+#define mul(r,a,w,c)   {               \
+       BN_ULONG high,low,ret,ta=(a);   \
+       low =  (w) * ta;                \
+       high=  BN_UMULT_HIGH(w,ta);     \
+       ret =  low + (c);               \
+       (c) =  high;                    \
+       (c) += (ret<low)?1:0;           \
+       (r) =  ret;                     \
+       }
+
+#define sqr(r0,r1,a)   {               \
+       BN_ULONG tmp=(a);               \
+       (r0) = tmp * tmp;               \
+       (r1) = BN_UMULT_HIGH(tmp,tmp);  \
+       }
+
+#else
+/*************************************************************
+ * No long long type
+ */
+
+#define LBITS(a)       ((a)&BN_MASK2l)
+#define HBITS(a)       (((a)>>BN_BITS4)&BN_MASK2l)
+#define        L2HBITS(a)      (((a)<<BN_BITS4)&BN_MASK2)
+
+#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((BN_ULONG)1); \
+       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 /* !BN_LLONG */
+
+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, const BN_ULONG *a, int n, BN_ULONG *tmp);
+void bn_sqr_comba8(BN_ULONG *r,const BN_ULONG *a);
+void bn_sqr_comba4(BN_ULONG *r,const BN_ULONG *a);
+int bn_cmp_words(const BN_ULONG *a,const BN_ULONG *b,int n);
+int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b,
+       int cl, int dl);
+#if 0
+/* bn_mul.c rollback <appro> */
+void bn_mul_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,
+       int dna,int dnb,BN_ULONG *t);
+void bn_mul_part_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,
+       int n,int tna,int tnb,BN_ULONG *t);
+#endif
+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,const 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/arm/crypto/openssl/bn/bn_lib.c b/arm/crypto/openssl/bn/bn_lib.c
new file mode 100644 (file)
index 0000000..aebd8c7
--- /dev/null
@@ -0,0 +1,762 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// removed param querying
+// remove BN_value_one to avoid global data
+// remove options handling
+// added BN_is_negative and BN_set_negative to allow hiding of struct BIGNUM 
+// changed OPENSSL_free to arena_free
+
+#include "bn_lcl.h"
+#include "limits.h"
+
+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_is_negative(const BIGNUM *a)
+       {
+       return (a->neg != 0);
+       }
+
+void BN_set_negative(BIGNUM *a, int neg)
+       {
+       a->neg = (neg ? 1 : 0);
+       }
+
+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];
+       assert(l != 0);
+       i=(a->top-1)*BN_BITS2;
+       return(i+BN_num_bits_word(l));
+       }
+
+void BN_clear_free(BIGNUM *a)
+       {
+       int i;
+
+       if (a == NULL) return;
+       if (a->d != NULL)
+               {
+               OPENSSL_cleanse(a->d,a->dmax*sizeof(a->d[0]));
+               if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
+                       arena_free(a->d);
+               }
+       i=BN_get_flags(a,BN_FLG_MALLOCED);
+       OPENSSL_cleanse(a,sizeof(BIGNUM));
+       if (i)
+               arena_free(a);
+       }
+
+void BN_free(BIGNUM *a)
+       {
+       if (a == NULL) return;
+       if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA)))
+               arena_free(a->d);
+       a->flags|=BN_FLG_FREE; /* REMOVE? */
+       if (a->flags & BN_FLG_MALLOCED)
+               arena_free(a);
+       }
+
+void BN_init(BIGNUM *a)
+       {
+       memset(a,0,sizeof(BIGNUM));
+       }
+
+BIGNUM *BN_new(void)
+       {
+       BIGNUM *ret;
+
+       ret=(BIGNUM *)arena_malloc(sizeof(BIGNUM));
+        // fixme handle errors
+       ret->flags=BN_FLG_MALLOCED;
+       ret->top=0;
+       ret->neg=0;
+       ret->dmax=0;
+       ret->d=NULL;
+       return(ret);
+       }
+
+/* This is used both by bn_expand2() and bn_dup_expand() */
+/* The caller MUST check that words > b->dmax before calling this */
+static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
+       {
+       BN_ULONG *A,*a = NULL;
+       const BN_ULONG *B;
+       int i;
+
+       if (words > (INT_MAX/(4*BN_BITS2)))
+               {
+               BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_BIGNUM_TOO_LONG);
+               return NULL;
+               }
+
+       bn_check_top(b);        
+       if (BN_get_flags(b,BN_FLG_STATIC_DATA))
+               {
+               BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
+               return(NULL);
+               }
+       a=A=(BN_ULONG *)arena_malloc(sizeof(BN_ULONG)*(words+1));
+        // fixme error handling
+#if 1
+       B=b->d;
+       /* Check if the previous number needs to be copied */
+       if (B != NULL)
+               {
+               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: /* workaround for ultrix cc: without 'case 0', the optimizer does
+                        * the switch table by doing a=top&3; a--; goto jump_table[a];
+                        * which fails for top== 0 */
+                       ;
+                       }
+               }
+
+       /* Now need to zero any data between b->top and b->max */
+       /* XXX Why? */
+
+       A= &(a[b->top]);
+       for (i=(words - 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=(words - 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);
+#endif
+               
+       return(a);
+       }
+
+/* This is an internal function that can be used instead of bn_expand2()
+ * when there is a need to copy BIGNUMs instead of only expanding the
+ * data part, while still expanding them.
+ * Especially useful when needing to expand BIGNUMs that are declared
+ * 'const' and should therefore not be changed.
+ * The reason to use this instead of a BN_dup() followed by a bn_expand2()
+ * is memory allocation overhead.  A BN_dup() followed by a bn_expand2()
+ * will allocate new memory for the BIGNUM data twice, and free it once,
+ * while bn_dup_expand() makes sure allocation is made only once.
+ */
+
+BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
+       {
+       BIGNUM *r = NULL;
+
+       /* This function does not work if
+        *      words <= b->dmax && top < words
+        * because BN_dup() does not preserve 'dmax'!
+        * (But bn_dup_expand() is not used anywhere yet.)
+        */
+       
+       if (words > b->dmax)
+               {
+               BN_ULONG *a = bn_expand_internal(b, words);
+
+               if (a)
+                       {
+                       r = BN_new();
+                       if (r)
+                               {
+                               r->top = b->top;
+                               r->dmax = words;
+                               r->neg = b->neg;
+                               r->d = a;
+                               }
+                       else
+                               {
+                               /* r == NULL, BN_new failure */
+                               arena_free(a);
+                               }
+                       }
+               /* If a == NULL, there was an error in allocation in
+                  bn_expand_internal(), and NULL should be returned */
+               }
+       else
+               {
+               r = BN_dup(b);
+               }
+
+       return r;
+       }
+
+/* This is an internal function that should not be used in applications.
+ * It ensures that 'b' has enough room for a 'words' word number number.
+ * It is mostly used by the various BIGNUM routines. If there is an error,
+ * NULL is returned. If not, 'b' is returned. */
+
+BIGNUM *bn_expand2(BIGNUM *b, int words)
+       {
+       if (words > b->dmax)
+               {
+               BN_ULONG *a = bn_expand_internal(b, words);
+
+               if (a)
+                       {
+                       if (b->d)
+                               arena_free(b->d);
+                       b->d=a;
+                       b->dmax=words;
+                       }
+               else
+                       b = NULL;
+               }
+       return b;
+       }
+
+BIGNUM *BN_dup(const BIGNUM *a)
+       {
+       BIGNUM *r, *t;
+
+       if (a == NULL) return NULL;
+
+       bn_check_top(a);
+
+       t = BN_new();
+       if (t == NULL) return(NULL);
+       r = BN_copy(t, a);
+       /* now  r == t || r == NULL */
+       if (r == NULL)
+               BN_free(t);
+       return r;
+       }
+
+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_expand_internal */
+               }
+#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_swap(BIGNUM *a, BIGNUM *b)
+       {
+       int flags_old_a, flags_old_b;
+       BN_ULONG *tmp_d;
+       int tmp_top, tmp_dmax, tmp_neg;
+       
+       flags_old_a = a->flags;
+       flags_old_b = b->flags;
+
+       tmp_d = a->d;
+       tmp_top = a->top;
+       tmp_dmax = a->dmax;
+       tmp_neg = a->neg;
+       
+       a->d = b->d;
+       a->top = b->top;
+       a->dmax = b->dmax;
+       a->neg = b->neg;
+       
+       b->d = tmp_d;
+       b->top = tmp_top;
+       b->dmax = tmp_dmax;
+       b->neg = tmp_neg;
+       
+       a->flags = (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA);
+       b->flags = (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA);
+       }
+
+
+void BN_clear(BIGNUM *a)
+       {
+       if (a->d != NULL)
+               memset(a->d,0,a->dmax*sizeof(a->d[0]));
+       a->top=0;
+       a->neg=0;
+       }
+
+BN_ULONG BN_get_word(const BIGNUM *a)
+       {
+       int i,n;
+       BN_ULONG ret=0;
+
+       n=BN_num_bytes(a);
+       if (n > (int)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);
+       }
+
+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;
+       ret->neg=0;
+       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(const BN_ULONG *a, const 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);
+       }
+
+/* Here follows a specialised variants of bn_cmp_words().  It has the
+   property of performing the operation on arrays of different sizes.
+   The sizes of those arrays is expressed through cl, which is the
+   common length ( basicall, min(len(a),len(b)) ), and dl, which is the
+   delta between the two lengths, calculated as len(a)-len(b).
+   All lengths are the number of BN_ULONGs...  */
+
+int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b,
+       int cl, int dl)
+       {
+       int n,i;
+       n = cl-1;
+
+       if (dl < 0)
+               {
+               for (i=dl; i<0; i++)
+                       {
+                       if (b[n-i] != 0)
+                               return -1; /* a < b */
+                       }
+               }
+       if (dl > 0)
+               {
+               for (i=dl; i>0; i--)
+                       {
+                       if (a[n+i] != 0)
+                               return 1; /* a > b */
+                       }
+               }
+       return bn_cmp_words(a,b,cl);
+       }
diff --git a/arm/crypto/openssl/bn/bn_mod.c b/arm/crypto/openssl/bn/bn_mod.c
new file mode 100644 (file)
index 0000000..b0d828e
--- /dev/null
@@ -0,0 +1,327 @@
+/* crypto/bn/bn_mod.c */
+/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
+ * for the OpenSSL project. */
+/* ====================================================================
+ * Copyright (c) 1998-2000 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).
+ *
+ */
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// changed function pointer in ternary operator to if statement and normal call
+//     (function pointer version crashed on ARM)
+
+#include "bn_lcl.h"
+
+
+#if 0 /* now just a #define */
+int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
+       {
+       return(BN_div(NULL,rem,m,d,ctx));
+       /* note that  rem->neg == m->neg  (unless the remainder is zero) */
+       }
+#endif
+
+
+int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
+       {
+       /* like BN_mod, but returns non-negative remainder
+        * (i.e.,  0 <= r < |d|  always holds) */
+
+       if (!(BN_mod(r,m,d,ctx)))
+               return 0;
+       if (!r->neg)
+               return 1;
+       /* now   -|d| < r < 0,  so we have to set  r := r + |d| */
+        if (d->neg) {
+            return BN_sub(r, r, d);
+        } else {
+            return BN_add(r, r, d);
+        }
+}
+
+
+int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx)
+       {
+       if (!BN_add(r, a, b)) return 0;
+       return BN_nnmod(r, r, m, ctx);
+       }
+
+
+/* BN_mod_add variant that may be used if both  a  and  b  are non-negative
+ * and less than  m */
+int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m)
+       {
+       if (!BN_add(r, a, b)) return 0;
+       if (BN_ucmp(r, m) >= 0)
+               return BN_usub(r, r, m);
+       return 1;
+       }
+
+
+int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx)
+       {
+       if (!BN_sub(r, a, b)) return 0;
+       return BN_nnmod(r, r, m, ctx);
+       }
+
+
+/* BN_mod_sub variant that may be used if both  a  and  b  are non-negative
+ * and less than  m */
+int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m)
+       {
+       if (!BN_sub(r, a, b)) return 0;
+       if (r->neg)
+               return BN_add(r, r, m);
+       return 1;
+       }
+
+
+/* slow but works */
+int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+       BN_CTX *ctx)
+       {
+       BIGNUM *t;
+       int ret=0;
+
+       bn_check_top(a);
+       bn_check_top(b);
+       bn_check_top(m);
+
+       BN_CTX_start(ctx);
+       if ((t = BN_CTX_get(ctx)) == NULL) goto err;
+       if (a == b)
+               { if (!BN_sqr(t,a,ctx)) goto err; }
+       else
+               { if (!BN_mul(t,a,b,ctx)) goto err; }
+       if (!BN_nnmod(r,t,m,ctx)) goto err;
+       ret=1;
+err:
+       BN_CTX_end(ctx);
+       return(ret);
+       }
+
+
+int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
+       {
+       if (!BN_sqr(r, a, ctx)) return 0;
+       /* r->neg == 0,  thus we don't need BN_nnmod */
+       return BN_mod(r, r, m, ctx);
+       }
+
+
+int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
+       {
+       if (!BN_lshift1(r, a)) return 0;
+       return BN_nnmod(r, r, m, ctx);
+       }
+
+
+/* BN_mod_lshift1 variant that may be used if  a  is non-negative
+ * and less than  m */
+int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m)
+       {
+       if (!BN_lshift1(r, a)) return 0;
+       if (BN_cmp(r, m) >= 0)
+               return BN_sub(r, r, m);
+       return 1;
+       }
+
+
+int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ctx)
+       {
+       BIGNUM *abs_m = NULL;
+       int ret;
+
+       if (!BN_nnmod(r, a, m, ctx)) return 0;
+
+       if (m->neg)
+               {
+               abs_m = BN_dup(m);
+               if (abs_m == NULL) return 0;
+               abs_m->neg = 0;
+               }
+       
+       ret = BN_mod_lshift_quick(r, r, n, (abs_m ? abs_m : m));
+
+       if (abs_m)
+               BN_free(abs_m);
+       return ret;
+       }
+
+
+/* BN_mod_lshift variant that may be used if  a  is non-negative
+ * and less than  m */
+int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m)
+       {
+       if (r != a)
+               {
+               if (BN_copy(r, a) == NULL) return 0;
+               }
+
+       while (n > 0)
+               {
+               int max_shift;
+               
+               /* 0 < r < m */
+               max_shift = BN_num_bits(m) - BN_num_bits(r);
+               /* max_shift >= 0 */
+
+               if (max_shift < 0)
+                       {
+                       BNerr(BN_F_BN_MOD_LSHIFT_QUICK, BN_R_INPUT_NOT_REDUCED);
+                       return 0;
+                       }
+
+               if (max_shift > n)
+                       max_shift = n;
+
+               if (max_shift)
+                       {
+                       if (!BN_lshift(r, r, max_shift)) return 0;
+                       n -= max_shift;
+                       }
+               else
+                       {
+                       if (!BN_lshift1(r, r)) return 0;
+                       --n;
+                       }
+
+               /* BN_num_bits(r) <= BN_num_bits(m) */
+
+               if (BN_cmp(r, m) >= 0) 
+                       {
+                       if (!BN_sub(r, r, m)) return 0;
+                       }
+               }
+       
+       return 1;
+       }
diff --git a/arm/crypto/openssl/bn/bn_mont.c b/arm/crypto/openssl/bn/bn_mont.c
new file mode 100644 (file)
index 0000000..e34e822
--- /dev/null
@@ -0,0 +1,378 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+/*
+ * Details about Montgomery multiplication algorithms can be found at
+ * http://security.ece.orst.edu/publications.html, e.g.
+ * http://security.ece.orst.edu/koc/papers/j37acmon.pdf and
+ * sections 3.8 and 4.2 in http://security.ece.orst.edu/koc/papers/r01rsasw.pdf
+ */
+
+// GrP pssh:
+// changed includes
+// disabled MONT_WORD (fixme crashes on ARM)
+// changed OPENSSL_malloc to arena_malloc
+// changed OPENSSL_free to arena_free
+
+#include "bn_lcl.h"
+
+// pssh: this crashes on ARM
+// #define MONT_WORD /* use the faster word-based algorithm */
+
+int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                         BN_MONT_CTX *mont, BN_CTX *ctx)
+       {
+       BIGNUM *tmp;
+       int ret=0;
+
+       BN_CTX_start(ctx);
+       tmp = BN_CTX_get(ctx);
+       if (tmp == NULL) goto err;
+
+       bn_check_top(tmp);
+       if (a == b)
+               {
+               if (!BN_sqr(tmp,a,ctx)) goto err;
+               }
+       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;
+       ret=1;
+err:
+       BN_CTX_end(ctx);
+       return(ret);
+       }
+
+int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
+            BN_CTX *ctx)
+       {
+       int retn=0;
+
+#ifdef MONT_WORD
+       BIGNUM *n,*r;
+       BN_ULONG *ap,*np,*rp,n0,v,*nrp;
+       int al,nl,max,i,x,ri;
+
+       BN_CTX_start(ctx);
+       if ((r = BN_CTX_get(ctx)) == NULL) goto err;
+
+       if (!BN_copy(r,a)) goto err;
+       n= &(mont->N);
+
+       ap=a->d;
+       /* mont->ri is the size of mont->N in bits (rounded up
+          to the word size) */
+       al=ri=mont->ri/BN_BITS2;
+       
+       nl=n->top;
+        // GrP fixme is this right?
+       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 err;
+       if (bn_wexpand(ret,max) == NULL) goto err;
+
+       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
+       fprintf(stderr,"word BN_from_montgomery %d * %d\n",nl,nl);
+#endif
+       for (i=0; i<nl; i++)
+               {
+#ifdef __TANDEM
+                {
+                   long long t1;
+                   long long t2;
+                   long long t3;
+                   t1 = rp[0] * (n0 & 0177777);
+                   t2 = 037777600000l;
+                   t2 = n0 & t2;
+                   t3 = rp[0] & 0177777;
+                   t2 = (t3 * t2) & BN_MASK2;
+                   t1 = t1 + t2;
+                   v=bn_mul_add_words(rp,np,nl,(BN_ULONG) t1);
+                }
+#else
+               v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
+#endif
+               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
+       ret->neg = r->neg;
+       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
+#else /* !MONT_WORD */ 
+       BIGNUM *t1,*t2;
+
+       BN_CTX_start(ctx);
+       t1 = BN_CTX_get(ctx);
+       t2 = BN_CTX_get(ctx);
+       if (t1 == NULL || t2 == NULL) goto err;
+       
+       if (!BN_copy(t1,a)) goto err;
+       BN_mask_bits(t1,mont->ri);
+
+       if (!BN_mul(t2,t1,&mont->Ni,ctx)) goto err;
+       BN_mask_bits(t2,mont->ri);
+
+       if (!BN_mul(t1,t2,&mont->N,ctx)) goto err;
+       if (!BN_add(t2,a,t1)) goto err;
+       if (!BN_rshift(ret,t2,mont->ri)) goto err;
+#endif /* MONT_WORD */
+
+       if (BN_ucmp(ret, &(mont->N)) >= 0)
+               {
+               if (!BN_usub(ret,ret,&(mont->N))) goto err;
+               }
+       retn=1;
+ err:
+       BN_CTX_end(ctx);
+       return(retn);
+       }
+
+BN_MONT_CTX *BN_MONT_CTX_new(void)
+       {
+       BN_MONT_CTX *ret;
+
+       if ((ret=(BN_MONT_CTX *)arena_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->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)
+               arena_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 */
+       mont->N.neg = 0;
+
+#ifdef MONT_WORD
+               {
+               BIGNUM tmod;
+               BN_ULONG buf[2];
+
+               mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
+               if (!(BN_zero(R))) goto err;
+               if (!(BN_set_bit(R,BN_BITS2))) goto err;        /* R */
+
+               buf[0]=mod->d[0]; /* tmod = N mod word size */
+               buf[1]=0;
+               tmod.d=buf;
+               tmod.top=1;
+               tmod.dmax=2;
+               tmod.neg=0;
+                                                       /* Ri = R^-1 mod N*/
+               if ((BN_mod_inverse(&Ri,R,&tmod,ctx)) == NULL)
+                       goto err;
+               if (!BN_lshift(&Ri,&Ri,BN_BITS2)) goto err; /* R*Ri */
+               if (!BN_is_zero(&Ri))
+                       {
+                       if (!BN_sub_word(&Ri,1)) goto err;
+                       }
+               else /* if N mod word size == 1 */
+                       {
+                       if (!BN_set_word(&Ri,BN_MASK2)) goto err;  /* Ri-- (mod word size) */
+                       }
+               if (!BN_div(&Ri,NULL,&Ri,&tmod,ctx)) goto err;
+               /* Ni = (R*Ri-1)/N,
+                * keep only least significant word: */
+               mont->n0 = (Ri.top > 0) ? Ri.d[0] : 0;
+               BN_free(&Ri);
+               }
+#else /* !MONT_WORD */
+               { /* bignum version */
+               mont->ri=BN_num_bits(&mont->N);
+               if (!BN_zero(R)) goto err;
+               if (!BN_set_bit(R,mont->ri)) goto err;  /* R = 2^ri */
+                                                       /* Ri = R^-1 mod N*/
+               if ((BN_mod_inverse(&Ri,R,&mont->N,ctx)) == NULL)
+                       goto err;
+               if (!BN_lshift(&Ri,&Ri,mont->ri)) goto err; /* R*Ri */
+               if (!BN_sub_word(&Ri,1)) goto err;
+                                                       /* Ni = (R*Ri-1) / N */
+               if (!BN_div(&(mont->Ni),NULL,&Ri,&mont->N,ctx)) goto err;
+               BN_free(&Ri);
+               }
+#endif
+
+       /* setup RR for conversions */
+       if (!BN_zero(&(mont->RR))) goto err;
+       if (!BN_set_bit(&(mont->RR),mont->ri*2)) goto err;
+       if (!BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx)) goto err;
+
+       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);
+
+       if (!BN_copy(&(to->RR),&(from->RR))) return NULL;
+       if (!BN_copy(&(to->N),&(from->N))) return NULL;
+       if (!BN_copy(&(to->Ni),&(from->Ni))) return NULL;
+       to->ri=from->ri;
+       to->n0=from->n0;
+       return(to);
+       }
+
diff --git a/arm/crypto/openssl/bn/bn_mul.c b/arm/crypto/openssl/bn/bn_mul.c
new file mode 100644 (file)
index 0000000..cc9e77d
--- /dev/null
@@ -0,0 +1,827 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// changed some ints to unsigned to avoid compiler warnings
+
+#include "bn_lcl.h"
+
+#ifdef BN_RECURSION
+/* Karatsuba recursive multiplication algorithm
+ * (cf. Knuth, The Art of Computer Programming, Vol. 2) */
+
+/* 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 calculate
+ * 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 0
+       if (n2 == 4)
+               {
+               bn_mul_comba4(r,a,b);
+               return;
+               }
+#  endif
+       if (n2 == 8)
+               {
+               bn_mul_comba8(r,a,b);
+               return; 
+               }
+# endif /* BN_MUL_COMBA */
+       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 /* BN_MUL_COMBA */
+               {
+               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,c2,neg,zero;
+       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]) */
+       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;
+               }
+               /* The zero case isn't yet implemented here. The speedup
+                  would probably be negligible. */
+# if 0
+       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
+# endif
+       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));
+
+       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 < 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 /* BN_RECURSION */
+
+int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+       {
+       int top,al,bl;
+       BIGNUM *rr;
+       int ret = 0;
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+       int i;
+#endif
+#ifdef BN_RECURSION
+       BIGNUM *t;
+       int 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;
+
+       if ((al == 0) || (bl == 0))
+               {
+               if (!BN_zero(r)) goto err;
+               return(1);
+               }
+       top=al+bl;
+
+       BN_CTX_start(ctx);
+       if ((r == a) || (r == b))
+               {
+               if ((rr = BN_CTX_get(ctx)) == NULL) goto err;
+               }
+       else
+               rr = r;
+       rr->neg=a->neg^b->neg;
+
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+       i = al-bl;
+#endif
+#ifdef BN_MUL_COMBA
+       if (i == 0)
+               {
+# if 0
+               if (al == 4)
+                       {
+                       if (bn_wexpand(rr,8) == NULL) goto err;
+                       rr->top=8;
+                       bn_mul_comba4(rr->d,a->d,b->d);
+                       goto end;
+                       }
+# endif
+               if (al == 8)
+                       {
+                       if (bn_wexpand(rr,16) == NULL) goto err;
+                       rr->top=16;
+                       bn_mul_comba8(rr->d,a->d,b->d);
+                       goto end;
+                       }
+               }
+#endif /* BN_MUL_COMBA */
+#ifdef BN_RECURSION
+       if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL))
+               {
+               if (i == 1 && !BN_get_flags(b,BN_FLG_STATIC_DATA) && bl<b->dmax)
+                       {
+#if 0  /* tribute to const-ification, bl<b->dmax above covers for this */
+                       if (bn_wexpand(b,al) == NULL) goto err;
+#endif
+                       b->d[bl]=0;
+                       bl++;
+                       i--;
+                       }
+               else if (i == -1 && !BN_get_flags(a,BN_FLG_STATIC_DATA) && al<a->dmax)
+                       {
+#if 0  /* tribute to const-ification, al<a->dmax above covers for this */
+                       if (bn_wexpand(a,bl) == NULL) goto err;
+#endif
+                       a->d[al]=0;
+                       al++;
+                       i++;
+                       }
+               if (i == 0)
+                       {
+                       /* symmetric and > 4 */
+                       /* 16 or larger */
+                       j=BN_num_bits_word((BN_ULONG)al);
+                       j=1<<(j-1);
+                       k=j+j;
+                       t = BN_CTX_get(ctx);
+                       if (al == j) /* exact multiple */
+                               {
+                               if (bn_wexpand(t,k*2) == NULL) goto err;
+                               if (bn_wexpand(rr,k*2) == NULL) goto err;
+                               bn_mul_recursive(rr->d,a->d,b->d,al,t->d);
+                               rr->top=top;
+                               goto end;
+                               }
+#if 0  /* tribute to const-ification, rsa/dsa performance is not affected */
+                       else
+                               {
+                               if (bn_wexpand(a,k) == NULL ) goto err;
+                               if (bn_wexpand(b,k) == NULL ) goto err;
+                               if (bn_wexpand(t,k*4) == NULL ) goto err;
+                               if (bn_wexpand(rr,k*4) == NULL ) goto err;
+                               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;
+                       goto end;
+#endif
+                       }
+               }
+#endif /* BN_RECURSION */
+       if (bn_wexpand(rr,top) == NULL) goto err;
+       rr->top=top;
+       bn_mul_normal(rr->d,a->d,al,b->d,bl);
+
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+end:
+#endif
+       bn_fix_top(rr);
+       if (r != rr) BN_copy(r,rr);
+       ret=1;
+err:
+       BN_CTX_end(ctx);
+       return(ret);
+       }
+
+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/arm/crypto/openssl/bn/bn_print.c b/arm/crypto/openssl/bn/bn_print.c
new file mode 100644 (file)
index 0000000..da0ba13
--- /dev/null
@@ -0,0 +1,191 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// changed OPENSSL_malloc to arena_malloc
+// removed BN_bn2dec, BN_dec2bn, BN_print_fp, BN_print, BN_dump1
+
+#include "bn_lcl.h"
+#include "ctype.h"
+
+static const char *Hex="0123456789ABCDEF";
+
+/* Must 'OPENSSL_free' the returned data */
+char *BN_bn2hex(const BIGNUM *a)
+       {
+       int i,j,v,z=0;
+       char *buf;
+       char *p;
+
+       buf=(char *)arena_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);
+       }
+
+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 digits, 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 significant '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);
+       }
diff --git a/arm/crypto/openssl/bn/bn_rand.c b/arm/crypto/openssl/bn/bn_rand.c
new file mode 100644 (file)
index 0000000..9c17b2a
--- /dev/null
@@ -0,0 +1,314 @@
+/* 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.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 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).
+ *
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// removed time-based entropy seeding from bnrand
+// changed OPENSSL_malloc to arena_malloc
+// changed OPENSSL_free to arena_free
+
+#include "bn_lcl.h"
+#include "rand.h"
+
+static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom)
+       {
+       unsigned char *buf=NULL;
+       int ret=0,bit,bytes,mask;
+
+       if (bits == 0)
+               {
+               BN_zero(rnd);
+               return 1;
+               }
+
+       bytes=(bits+7)/8;
+       bit=(bits-1)%8;
+       mask=0xff<<(bit+1);
+
+       buf=(unsigned char *)arena_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 */
+
+       if (pseudorand)
+               {
+               if (RAND_pseudo_bytes(buf, bytes) == -1)
+                       goto err;
+               }
+       else
+               {
+               if (RAND_bytes(buf, bytes) <= 0)
+                       goto err;
+               }
+
+#if 1
+       if (pseudorand == 2)
+               {
+               /* generate patterns that are more likely to trigger BN
+                  library bugs */
+               int i;
+               unsigned char c;
+
+               for (i = 0; i < bytes; i++)
+                       {
+                       RAND_pseudo_bytes(&c, 1);
+                       if (c >= 128 && i > 0)
+                               buf[i] = buf[i-1];
+                       else if (c < 42)
+                               buf[i] = 0;
+                       else if (c < 84)
+                               buf[i] = 255;
+                       }
+               }
+#endif
+
+       if (top != -1)
+               {
+               if (top)
+                       {
+                       if (bit == 0)
+                               {
+                               buf[0]=1;
+                               buf[1]|=0x80;
+                               }
+                       else
+                               {
+                               buf[0]|=(3<<(bit-1));
+                               }
+                       }
+               else
+                       {
+                       buf[0]|=(1<<bit);
+                       }
+               }
+       buf[0] &= ~mask;
+       if (bottom) /* set bottom bit if requested */
+               buf[bytes-1]|=1;
+       if (!BN_bin2bn(buf,bytes,rnd)) goto err;
+       ret=1;
+err:
+       if (buf != NULL)
+               {
+               OPENSSL_cleanse(buf,bytes);
+               arena_free(buf);
+               }
+       return(ret);
+       }
+
+int     BN_rand(BIGNUM *rnd, int bits, int top, int bottom)
+       {
+       return bnrand(0, rnd, bits, top, bottom);
+       }
+
+int     BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom)
+       {
+       return bnrand(1, rnd, bits, top, bottom);
+       }
+
+#if 1
+int     BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom)
+       {
+       return bnrand(2, rnd, bits, top, bottom);
+       }
+#endif
+
+
+/* random number r:  0 <= r < range */
+static int bn_rand_range(int pseudo, BIGNUM *r, BIGNUM *range)
+       {
+       int (*bn_rand)(BIGNUM *, int, int, int) = pseudo ? BN_pseudo_rand : BN_rand;
+       int n;
+
+       if (range->neg || BN_is_zero(range))
+               {
+               BNerr(BN_F_BN_RAND_RANGE, BN_R_INVALID_RANGE);
+               return 0;
+               }
+
+       n = BN_num_bits(range); /* n > 0 */
+
+       /* BN_is_bit_set(range, n - 1) always holds */
+
+       if (n == 1)
+               {
+               if (!BN_zero(r)) return 0;
+               }
+       else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3))
+               {
+               /* range = 100..._2,
+                * so  3*range (= 11..._2)  is exactly one bit longer than  range */
+               do
+                       {
+                       if (!bn_rand(r, n + 1, -1, 0)) return 0;
+                       /* If  r < 3*range,  use  r := r MOD range
+                        * (which is either  r, r - range,  or  r - 2*range).
+                        * Otherwise, iterate once more.
+                        * Since  3*range = 11..._2, each iteration succeeds with
+                        * probability >= .75. */
+                       if (BN_cmp(r ,range) >= 0)
+                               {
+                               if (!BN_sub(r, r, range)) return 0;
+                               if (BN_cmp(r, range) >= 0)
+                                       if (!BN_sub(r, r, range)) return 0;
+                               }
+                       }
+               while (BN_cmp(r, range) >= 0);
+               }
+       else
+               {
+               do
+                       {
+                       /* range = 11..._2  or  range = 101..._2 */
+                       if (!bn_rand(r, n, -1, 0)) return 0;
+                       }
+               while (BN_cmp(r, range) >= 0);
+               }
+
+       return 1;
+       }
+
+
+int    BN_rand_range(BIGNUM *r, BIGNUM *range)
+       {
+       return bn_rand_range(0, r, range);
+       }
+
+int    BN_pseudo_rand_range(BIGNUM *r, BIGNUM *range)
+       {
+       return bn_rand_range(1, r, range);
+       }
diff --git a/arm/crypto/openssl/bn/bn_recp.c b/arm/crypto/openssl/bn/bn_recp.c
new file mode 100644 (file)
index 0000000..4f5f34e
--- /dev/null
@@ -0,0 +1,256 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// changed OPENSSL_malloc to arena_malloc
+// changed OPENSSL_free to arena_free
+
+#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 *)arena_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)
+               arena_free(recp);
+       }
+
+int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx)
+       {
+       if (!BN_copy(&(recp->N),d)) return 0;
+       if (!BN_zero(&(recp->Nr))) return 0;
+       recp->num_bits=BN_num_bits(d);
+       recp->shift=0;
+       return(1);
+       }
+
+int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
+       BN_RECP_CTX *recp, BN_CTX *ctx)
+       {
+       int ret=0;
+       BIGNUM *a;
+       const BIGNUM *ca;
+
+       BN_CTX_start(ctx);
+       if ((a = BN_CTX_get(ctx)) == NULL) goto err;
+       if (y != NULL)
+               {
+               if (x == y)
+                       { if (!BN_sqr(a,x,ctx)) goto err; }
+               else
+                       { if (!BN_mul(a,x,y,ctx)) goto err; }
+               ca = a;
+               }
+       else
+               ca=x; /* Just do the mod */
+
+       ret = BN_div_recp(NULL,r,ca,recp,ctx);
+err:
+       BN_CTX_end(ctx);
+       return(ret);
+       }
+
+int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
+       BN_RECP_CTX *recp, BN_CTX *ctx)
+       {
+       int i,j,ret=0;
+       BIGNUM *a,*b,*d,*r;
+
+       BN_CTX_start(ctx);
+       a=BN_CTX_get(ctx);
+       b=BN_CTX_get(ctx);
+       if (dv != NULL)
+               d=dv;
+       else
+               d=BN_CTX_get(ctx);
+       if (rem != NULL)
+               r=rem;
+       else
+               r=BN_CTX_get(ctx);
+       if (a == NULL || b == NULL || d == NULL || r == NULL) goto err;
+
+       if (BN_ucmp(m,&(recp->N)) < 0)
+               {
+               if (!BN_zero(d)) return 0;
+               if (!BN_copy(r,m)) return 0;
+               BN_CTX_end(ctx);
+               return(1);
+               }
+
+       /* We want the remainder
+        * Given input of ABCDEF / ab
+        * we need multiply ABCDEF by 3 digests of the reciprocal of ab
+        *
+        */
+
+       /* i := max(BN_num_bits(m), 2*BN_num_bits(N)) */
+       i=BN_num_bits(m);
+       j=recp->num_bits<<1;
+       if (j>i) i=j;
+
+       /* Nr := round(2^i / N) */
+       if (i != recp->shift)
+               recp->shift=BN_reciprocal(&(recp->Nr),&(recp->N),
+                       i,ctx); /* BN_reciprocal returns i, or -1 for an error */
+       if (recp->shift == -1) goto err;
+
+       /* d := |round(round(m / 2^BN_num_bits(N)) * recp->Nr / 2^(i - BN_num_bits(N)))|
+        *    = |round(round(m / 2^BN_num_bits(N)) * round(2^i / N) / 2^(i - BN_num_bits(N)))|
+        *   <= |(m / 2^BN_num_bits(N)) * (2^i / N) * (2^BN_num_bits(N) / 2^i)|
+        *    = |m/N|
+        */
+       if (!BN_rshift(a,m,recp->num_bits)) goto err;
+       if (!BN_mul(b,a,&(recp->Nr),ctx)) goto err;
+       if (!BN_rshift(d,b,i-recp->num_bits)) 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;
+
+#if 1
+       j=0;
+       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:
+       BN_CTX_end(ctx);
+       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.
+ */
+/* r := 2^len / m */
+int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx)
+       {
+       int ret= -1;
+       BIGNUM t;
+
+       BN_init(&t);
+
+       if (!BN_zero(&t)) goto err;
+       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/arm/crypto/openssl/bn/bn_shift.c b/arm/crypto/openssl/bn/bn_shift.c
new file mode 100644 (file)
index 0000000..cd4515c
--- /dev/null
@@ -0,0 +1,229 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+
+#include "bn_lcl.h"
+
+int BN_lshift1(BIGNUM *r, const 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, const 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;
+       nw=n/BN_BITS2;
+       if (bn_wexpand(r,a->top+nw+1) == NULL) return(0);
+       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, const 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 || a->top == 0)
+               {
+               BN_zero(r);
+               return(1);
+               }
+       if (r != a)
+               {
+               r->neg=a->neg;
+               if (bn_wexpand(r,a->top-nw+1) == NULL) return(0);
+               }
+       else
+               {
+               if (n == 0)
+                       return 1; /* or the copying loop will go berserk */
+               }
+
+       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/arm/crypto/openssl/bn/bn_sqr.c b/arm/crypto/openssl/bn/bn_sqr.c
new file mode 100644 (file)
index 0000000..3c8a429
--- /dev/null
@@ -0,0 +1,312 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+
+#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, const BIGNUM *a, BN_CTX *ctx)
+       {
+       int max,al;
+       int ret = 0;
+       BIGNUM *tmp,*rr;
+
+#ifdef BN_COUNT
+       fprintf(stderr,"BN_sqr %d * %d\n",a->top,a->top);
+#endif
+       bn_check_top(a);
+
+       al=a->top;
+       if (al <= 0)
+               {
+               r->top=0;
+               return(1);
+               }
+
+       BN_CTX_start(ctx);
+       rr=(a != r) ? r : BN_CTX_get(ctx);
+       tmp=BN_CTX_get(ctx);
+       if (tmp == NULL) goto err;
+
+       max=(al+al);
+       if (bn_wexpand(rr,max+1) == NULL) goto err;
+
+       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(tmp,k*2) == NULL) goto err;
+                               bn_sqr_recursive(rr->d,a->d,al,tmp->d);
+                               }
+                       else
+                               {
+                               if (bn_wexpand(tmp,max) == NULL) goto err;
+                               bn_sqr_normal(rr->d,a->d,al,tmp->d);
+                               }
+                       }
+#else
+               if (bn_wexpand(tmp,max) == NULL) goto err;
+               bn_sqr_normal(rr->d,a->d,al,tmp->d);
+#endif
+               }
+
+       rr->top=max;
+       rr->neg=0;
+       if ((max > 0) && (rr->d[max-1] == 0)) rr->top--;
+       if (rr != r) BN_copy(r,rr);
+       ret = 1;
+ err:
+       BN_CTX_end(ctx);
+       return(ret);
+       }
+
+/* tmp must have 2*n words */
+void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp)
+       {
+       int i,j,max;
+       const BN_ULONG *ap;
+       BN_ULONG *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.    (There's not actually a 'b' here ...)
+ * n must be a power of 2.
+ * We multiply and return the result.
+ * t must be 2*n words in size
+ * We calculate
+ * 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, const BN_ULONG *a, int n2, BN_ULONG *t)
+       {
+       int n=n2/2;
+       int zero,c1;
+       BN_ULONG ln,lo,*p;
+
+#ifdef BN_COUNT
+       fprintf(stderr," 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,n2*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/arm/crypto/openssl/bn/bn_word.c b/arm/crypto/openssl/bn/bn_word.c
new file mode 100644 (file)
index 0000000..1701ec9
--- /dev/null
@@ -0,0 +1,226 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+
+#include "bn_lcl.h"
+
+BN_ULONG BN_mod_word(const 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=!(a->neg);
+               return(i);
+               }
+       w&=BN_MASK2;
+       if (bn_wexpand(a,a->top+1) == NULL) return(0);
+       i=0;
+       for (;;)
+               {
+               if (i >= a->top)
+                       l=w;
+               else
+                       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 (BN_is_zero(a) || 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)
+               {
+               if (w == 0)
+                       BN_zero(a);
+               else
+                       {
+                       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/arm/crypto/openssl/cryptlib.h b/arm/crypto/openssl/cryptlib.h
new file mode 100644 (file)
index 0000000..d411248
--- /dev/null
@@ -0,0 +1,115 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+/* Assorted OpenSSL definitions */
+
+#ifndef CRYPTLIB_H
+#define CRYPTLIB_H
+
+#include "includes.h"
+
+#include "xmalloc.h"
+
+#define OPENSSL_VERSION_NUMBER 0x0090703fL
+
+/* size of string representations */
+#define DECIMAL_SIZE(type)      ((sizeof(type)*8+2)/3+1)
+#define HEX_SIZE(type)          (sizeof(type)*2)
+
+#define DHerr(a,b) fatal("dh error " #a " " #b)
+#define EVPerr(a,b) fatal("EVP error " #a " " #b)
+#define DSAerr(a,b) fatal("DSA error " #a " " #b)
+#define RSAerr(a,b) fatal("RSA error " #a " " #b)
+
+#define OPENSSL_malloc(p) arena_malloc(p)
+#define OPENSSL_free(p) arena_free(p)
+#define OPENSSL_assert(a) do { if (!(a)) fatal("OpenSSL error"); } while (0)
+
+// in mem_clr.c
+extern void OPENSSL_cleanse(void *ptr, size_t len);
+
+#define OPENSSL_NO_BIO
+#define OPENSSL_NO_FP_API
+#define OPENSSL_NO_ENGINE
+
+#define OPENSSL_NO_MD2
+#define OPENSSL_NO_MD4
+#define OPENSSL_NO_RIPEMD
+#define OPENSSL_NO_RC4
+#define OPENSSL_NO_RC2
+#define OPENSSL_NO_RC5
+#define OPENSSL_NO_BF
+#define OPENSSL_NO_CAST
+#define OPENSSL_NO_IDEA
+#define OPENSSL_NO_MDC2
+
+#define OPENSSL_DISABLE_OLD_DES_SUPPORT
+#define OPENSSL_NO_SHA0
+
+#define OPENSSL_VERSION_PTEXT /**/
+
+#define STACK_OF(a) void
+
+#define DES_LONG uint32_t
+
+#define ASN1_TYPE void
+#define ASN1_OBJECT void
+
+#define ENGINE void
+typedef struct evp_cipher_st EVP_CIPHER;
+typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
+typedef struct env_md_st EVP_MD;
+typedef struct env_md_ctx_st EVP_MD_CTX;
+typedef struct evp_pkey_st EVP_PKEY;
+
+
+
+/* Macros to allow global variables to be reached through function calls when
+   required (if a shared library version requvres it, for example.
+   The way it's done allows definitions like this:
+
+        // in foobar.c
+        OPENSSL_IMPLEMENT_GLOBAL(int,foobar) = 0;
+        // in foobar.h
+        OPENSSL_DECLARE_GLOBAL(int,foobar);
+        #define foobar OPENSSL_GLOBAL_REF(foobar)
+*/
+#ifdef OPENSSL_EXPORT_VAR_AS_FUNCTION
+# define OPENSSL_IMPLEMENT_GLOBAL(type,name) static type _hide_##name; \
+        type *_shadow_##name(void) { return &_hide_##name; } \
+        static type _hide_##name
+# define OPENSSL_DECLARE_GLOBAL(type,name) type *_shadow_##name(void)
+# define OPENSSL_GLOBAL_REF(name) (*(_shadow_##name()))
+#else
+# define OPENSSL_IMPLEMENT_GLOBAL(type,name) OPENSSL_GLOBAL type _shadow_##name
+# define OPENSSL_DECLARE_GLOBAL(type,name) OPENSSL_EXPORT type _shadow_##name
+# define OPENSSL_GLOBAL_REF(name) _shadow_##name
+#endif
+
+#define OPENSSL_EXPORT extern
+#define OPENSSL_IMPORT extern
+#define OPENSSL_GLOBAL
+#define OPENSSL_EXTERN OPENSSL_IMPORT
+
+#endif
diff --git a/arm/crypto/rand.c b/arm/crypto/rand.c
new file mode 100644 (file)
index 0000000..6cfa84e
--- /dev/null
@@ -0,0 +1,331 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// fixme additional entropy sources for non-CPM:
+// microphone input
+// hardware timers / counters
+
+
+#include "includes.h"
+#include "assert.h"
+#include "rand.h"
+#include "rand_time.h"
+#include "fortuna/fortuna.h"
+#include "rsrc/rsrc.h"
+#ifdef USE_CPMLIB
+#include <CPMLib.h>
+#endif
+
+
+static uint32_t lastTime = 0;
+static int useARMTime = -1;
+
+static uint32_t RAND_time(void)
+{
+    rand_log(__PRETTY_FUNCTION__);
+
+    assert(useARMTime != -1);
+    if (useARMTime) {
+        lastTime = ARM_time(lastTime);
+    } else {
+        lastTime = TimGetTicks();
+    }
+    return lastTime;
+}
+
+
+
+static int UseCPM = 0;
+
+// Fortuna version
+static struct fortuna_t *rng = NULL;
+#define SAVED_SEED_SIZE 32
+
+#ifdef USE_CPMLIB
+
+// CPM version
+static UInt16 CPMLibRefnum = 0;
+static int LoadedCPMLib = 0;
+
+static Boolean CPMLibAvailable(void) 
+{
+    Err err;
+    UInt16 providerCount;
+
+    // fixme dunno if CPMLib is any good, 
+    // or whether CPMLibGenerateRandomBytes is documented and usable, 
+    // or whether CPMLibAddRandomSeed is necessary to make it work.
+
+    rand_log(__PRETTY_FUNCTION__);
+
+    return false;
+
+    err = SysLibFind("CPMLib", &CPMLibRefnum);
+    if (!err) {
+        // library already loaded
+        return true;
+    } else {
+        // not already loaded - try to load it ourselves
+        err = SysLibLoad(sysFileTLibrary, cpmCreator, &CPMLibRefnum);
+        if (!err) {
+            // loaded successfully - balance with SysLibRemove() later
+            LoadedCPMLib = 1;
+            return true;
+        } else {
+            // not loaded
+            return false;
+        }
+    }
+}
+
+#endif
+
+
+void RAND_init(void)
+{
+    Err err;
+
+    rand_log(__PRETTY_FUNCTION__);
+
+#ifdef USE_CPMLIB
+    if (CPMLibAvailable()) {
+        UInt16 providerCount;
+        err = CPMLibOpen(CPMLibRefnum, &providerCount);
+        if (!err  ||  err == cpmErrAlreadyOpen) {
+            UseCPM = 1;
+        }
+    }
+#endif
+
+    if (!UseCPM) {
+        // init Fortuna instead of CPM
+        UInt32 ftr;
+        uint8_t *ftrBuf;
+        uint32_t value32;
+        uint8_t value8;
+        uint32_t warned = 0;
+
+        if (!rng) rng = fortuna_create();
+
+        if (useARMTime == -1) {
+            // use ARM time code on Tungsten C only
+            uint32_t companyID = 0;
+            uint32_t deviceID = 0;
+            FtrGet(sysFtrCreator, sysFtrNumOEMCompanyID, &companyID);
+            FtrGet(sysFtrCreator, sysFtrNumOEMDeviceID, &deviceID);
+            useARMTime = (companyID == 'palm'  &&  deviceID == 'MT64'); // T|C
+            
+            if (!useARMTime) {
+                // Entropy sources suck - complain
+                err = FtrGet(PSSH_CREATOR, ftrEntropyWarning, &warned);
+                if (err) warned = 0;
+                if (!warned) {
+                    FrmCustomAlert(AlertFormID, "WARNING: Low-quality random number generator in use. pssh is currently EVEN MORE INSECURE than on devices with a high-quality random number generator.", " ", " ");
+                    warned = 1;
+                    FtrSet(PSSH_CREATOR, ftrEntropyWarning, warned);
+                }
+            }
+        }
+
+        // Seed PRNG with initial values. 
+        // All values are be placed in pool 0; 
+        // the generator will be reseeded from pool 0 when the first 
+        // random bytes are extracted.
+        
+        // saved seed file
+        ftr = 0;
+        err = FtrGet(PSSH_CREATOR, ftrEntropy, (UInt32 *)&ftr);
+        ftrBuf = (uint8_t *)ftr;
+        if (!err  &&  ftrBuf  &&  MemPtrSize(ftrBuf) == SAVED_SEED_SIZE) {
+            fortuna_put_bytes(rng, RAND_source_init, 0, ftrBuf, SAVED_SEED_SIZE);
+            DmSet(ftrBuf, 0, SAVED_SEED_SIZE, 0);
+        } else {
+            // fixme add a few seconds of high-resolution timer queries 
+            // and other additional sources if seed file is gone
+            
+            // record count and byte size of all databases
+            UInt16 dbIndex;
+            UInt16 dbCount = DmNumDatabases(0);
+            for (dbIndex = 0; dbIndex < dbCount; dbIndex++) {
+                UInt32 recordCount;
+                UInt32 dbBytes;
+                LocalID dbid = DmGetDatabase(0, dbIndex);
+                if (dbid == 0) continue;
+                
+                err = DmDatabaseSize(0, dbid, &recordCount, &dbBytes, NULL);
+                if (err) continue;
+                
+                fortuna_put_bytes(rng, RAND_source_init, 0, (uint8_t *)&recordCount, sizeof(recordCount));
+                fortuna_put_bytes(rng, RAND_source_init, 0, (uint8_t *)&dbBytes, sizeof(dbBytes));
+            }
+        }
+        FtrPtrFree(PSSH_CREATOR, ftrEntropy);
+        
+        value32 = RAND_time();
+        fortuna_put_bytes(rng, RAND_source_init, 0, (uint8_t *)&value32, sizeof(value32));
+        
+        // current date and clock time
+        value32 = TimGetSeconds();
+        fortuna_put_bytes(rng, RAND_source_init, 0, (uint8_t *)&value32, sizeof(value32));
+        
+        value32 = RAND_time();
+        fortuna_put_bytes(rng, RAND_source_init, 0, (uint8_t *)&value32, sizeof(value32));
+        
+        // battery level
+        SysBatteryInfo(false, NULL, NULL, NULL, NULL, NULL, &value8);
+        fortuna_put_bytes(rng, RAND_source_init, 0, &value8, sizeof(value8));
+        
+        value32 = RAND_time();
+        fortuna_put_bytes(rng, RAND_source_init, 0, (uint8_t *)&value32, sizeof(value32));
+    }
+}
+
+
+void RAND_stop(void)
+{
+    rand_log(__PRETTY_FUNCTION__);
+
+#ifdef USE_CPMLIB
+    if (UseCPM) {
+        if (CPMLibRefnum) {
+            CPMLibClose(CPMLibRefnum);
+            if (LoadedCPMLib) {
+                SysLibRemove(CPMLibRefnum);
+            }
+        }
+    }
+    else 
+#endif
+    {
+        void *ftr;
+        uint8_t *ftrBuf = NULL;
+        Err err;
+        
+        if (!rng) return;
+        
+        // write new seed file
+        err = FtrPtrNew(PSSH_CREATOR, ftrEntropy, SAVED_SEED_SIZE, &ftr);
+        ftrBuf = (uint8_t *)ftr;
+        if (!err  &&  ftrBuf  &&  MemPtrSize(ftrBuf) == SAVED_SEED_SIZE) {
+            uint8_t *bytesBuf = arena_malloc(SAVED_SEED_SIZE);
+            fortuna_get_bytes(rng, bytesBuf, SAVED_SEED_SIZE);
+            DmWrite(ftrBuf, 0, bytesBuf, SAVED_SEED_SIZE);
+            arena_free(bytesBuf);
+        }
+    }
+}
+
+
+void RAND_add(uint8_t sourceID, uint8_t poolID, uint8_t *inBytes, unsigned int byteCount)
+{
+    rand_log(__PRETTY_FUNCTION__);
+
+    if (UseCPM) {
+        // do nothing
+        // fixme make sure CPM RNG doesn't need manual seeding
+    }
+    else {
+        if (!rng) rng = fortuna_create();
+        fortuna_put_bytes(rng, sourceID, poolID, inBytes, byteCount);
+    }
+}
+
+
+int32_t RAND_pseudo_bytes(char *buf, uint32_t len) 
+{
+    rand_log(__PRETTY_FUNCTION__);
+
+    return RAND_bytes(buf, len);
+}
+
+
+static uint8_t generatorPool = 0;
+int32_t RAND_bytes(char *buf, uint32_t len)
+{
+    rand_log(__PRETTY_FUNCTION__);
+
+#ifdef USE_CPMLIB
+    if (UseCPM) {
+        Err err = CPMLibGenerateRandomBytes(CPMLibRefnum, buf, &len);
+        if (err) fatal("CPMLibGenerateRandomBytes failed (%d)", err);
+    }
+    else 
+#endif
+    {
+        uint32_t time;
+        time = RAND_time();
+        if (!rng) rng = fortuna_create();
+        
+        RAND_add(RAND_source_generator, generatorPool++, 
+                 (uint8_t *)&time, sizeof(time));
+        fortuna_get_bytes(rng, buf, len);
+    }
+    return 1;
+}
+
+
+static uint8_t eventPool = 0;
+void RAND_add_event_entropy(EventType *e)
+{
+    rand_log(__PRETTY_FUNCTION__);
+
+    if (UseCPM) {
+        // do nothing
+    } 
+    else {
+        UInt16 v[4];
+        uint32_t time = RAND_time();
+        v[0] = time & 0xffff;
+        v[1] = time >> 16;
+        v[2] = e->eType;
+        switch (e->eType) {
+        case keyDownEvent: 
+            v[3] = e->data.keyDown.chr; 
+            break;
+        case penDownEvent:
+        case penUpEvent:
+        case penMoveEvent:
+        default:
+            v[3] = (e->screenX << 8) | e->screenY;
+            break;
+        }
+        
+        RAND_add(RAND_source_event, eventPool++, (uint8_t *)v, sizeof(v));
+    }
+}
+
+
+static uint8_t netPool = 0;
+void RAND_add_net_entropy(void)
+{
+    rand_log(__PRETTY_FUNCTION__);
+
+    if (UseCPM) {
+        // do nothing
+    }
+    else {
+        uint32_t time = RAND_time();
+        RAND_add(RAND_source_net, netPool++, (uint8_t *)&time, sizeof(time));
+    }
+}
diff --git a/arm/crypto/rand.h b/arm/crypto/rand.h
new file mode 100644 (file)
index 0000000..5964475
--- /dev/null
@@ -0,0 +1,48 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef RAND_H
+#define RAND_H
+
+#include "includes.h"
+
+void RAND_init(void);
+void RAND_stop(void);
+
+void RAND_add(uint8_t sourceID, uint8_t poolID, uint8_t *inBytes, unsigned int byteCount);
+
+// Do NOT put these in a segment other than the main segment. 
+// If you do, the callbacks from ARM will die horribly.
+// fixme this is because of bogus extern decls in bn_armstubs.c
+int32_t RAND_pseudo_bytes(char *buf, uint32_t len);
+int32_t RAND_bytes(char *buf, uint32_t len);
+void RAND_add_event_entropy(EventType *e);
+void RAND_add_net_entropy(void);
+
+#define RAND_source_init 0
+#define RAND_source_event 1
+#define RAND_source_net 2
+#define RAND_source_generator 3
+
+#endif
diff --git a/arm/crypto/rand_armcalls.c b/arm/crypto/rand_armcalls.c
new file mode 100644 (file)
index 0000000..3275a7e
--- /dev/null
@@ -0,0 +1,51 @@
+#include "includes.h"
+#include "swap.h"
+#include "rand.h"
+
+uint32_t RAND_init_stub(void);
+uint32_t RAND_stop_stub(void);
+uint32_t RAND_bytes_stub(uint32_t *param);
+uint32_t RAND_add_event_entropy_stub(uint32_t *param);
+uint32_t RAND_add_net_entropy_stub(void);
+
+
+uint32_t RAND_init_stub(void)
+{
+    RAND_init();
+    return 0;
+}
+
+
+uint32_t RAND_stop_stub(void)
+{
+    RAND_stop();
+    return 0;
+}
+
+
+uint32_t RAND_bytes_stub(uint32_t *param)
+{
+    char *buf = (char *)read32(&param[0]);
+    uint32_t len = (uint32_t)read32(&param[1]);
+    return (int32_t) RAND_bytes(buf, len);
+}
+
+
+uint32_t RAND_add_event_entropy_stub(uint32_t *param)
+{
+    EventType *e = (EventType *)read32(&param[0]);
+
+    // swap eType, but don't bother with the rest
+    // because we're only using it for entropy anyway
+    swap16P(&e->eType);
+    RAND_add_event_entropy(e);
+    swap16P(&e->eType);
+    return 0;
+}
+
+
+uint32_t RAND_add_net_entropy_stub(void)
+{
+    RAND_add_net_entropy();
+    return 0;
+}
diff --git a/arm/crypto/rand_time.S b/arm/crypto/rand_time.S
new file mode 100644 (file)
index 0000000..08effb3
--- /dev/null
@@ -0,0 +1,15 @@
+.code 16
+.global ARM_time
+.thumb_func
+ARM_time:
+       // switch to ARM
+       mov   r3, pc
+       bx    r3
+       
+.code 32       
+        mrc   p14, 0, r1, c1, c0, 0    // read timer
+        cmp   r1, r0                   // if (time == oldtime) {
+        ldreq r2, =0x00000005          //     enable timer
+        mcreq p14, 0, r2, c0, c0, 0    //     enable timer
+       mov   r0, r1                   // return new time
+       bx    lr                       // return to caller (ARM or Thumb)
diff --git a/arm/crypto/rand_time.h b/arm/crypto/rand_time.h
new file mode 100644 (file)
index 0000000..cb262fe
--- /dev/null
@@ -0,0 +1,32 @@
+/**********
+ * Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef RAND_TIME
+#define RAND_TIME
+
+#include "includes.h"
+
+uint32_t ARM_time(uint32_t param);
+
+#endif
diff --git a/arm/crypto/sha2/sha2.c b/arm/crypto/sha2/sha2.c
new file mode 100644 (file)
index 0000000..6e4d7f4
--- /dev/null
@@ -0,0 +1,1107 @@
+/*
+ * FILE:       sha2.c
+ * AUTHOR:     Aaron D. Gifford <me@aarongifford.com>
+ * 
+ * Copyright (c) 2000-2001, Aaron D. Gifford
+ * 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. Neither the name of the copyright holder nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 CONTRIBUTOR(S) 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.
+ *
+ * $Id: sha2.c,v 1.3 2004/12/30 01:56:29 admin Exp $
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// disabled SHA-384 and SHA-512 (PSSH_NO_BIG_SHA2)
+
+#include "sha2.h"
+#include "assert.h"
+
+/*
+ * ASSERT NOTE:
+ * Some sanity checking code is included using assert().  On my FreeBSD
+ * system, this additional code can be removed by compiling with NDEBUG
+ * defined.  Check your own systems manpage on assert() to see how to
+ * compile WITHOUT the sanity checking code on your system.
+ *
+ * UNROLLED TRANSFORM LOOP NOTE:
+ * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
+ * loop version for the hash transform rounds (defined using macros
+ * later in this file).  Either define on the command line, for example:
+ *
+ *   cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
+ *
+ * or define below:
+ *
+ *   #define SHA2_UNROLL_TRANSFORM
+ *
+ */
+
+
+/*** SHA-256/384/512 Machine Architecture Definitions *****************/
+/*
+ * BYTE_ORDER NOTE:
+ *
+ * Please make sure that your system defines BYTE_ORDER.  If your
+ * architecture is little-endian, make sure it also defines
+ * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
+ * equivilent.
+ *
+ * If your system does not define the above, then you can do so by
+ * hand like this:
+ *
+ *   #define LITTLE_ENDIAN 1234
+ *   #define BIG_ENDIAN    4321
+ *
+ * And for little-endian machines, add:
+ *
+ *   #define BYTE_ORDER LITTLE_ENDIAN 
+ *
+ * Or for big-endian machines:
+ *
+ *   #define BYTE_ORDER BIG_ENDIAN
+ *
+ * The FreeBSD machine this was written on defines BYTE_ORDER
+ * appropriately by including <sys/types.h> (which in turn includes
+ * <machine/endian.h> where the appropriate definitions are actually
+ * made).
+ */
+#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
+#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
+#endif
+
+/*
+ * Define the followingsha2_* types to types of the correct length on
+ * the native archtecture.   Most BSD systems and Linux define u_intXX_t
+ * types.  Machines with very recent ANSI C headers, can use the
+ * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H
+ * during compile or in the sha.h header file.
+ *
+ * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t
+ * will need to define these three typedefs below (and the appropriate
+ * ones in sha.h too) by hand according to their system architecture.
+ *
+ * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t
+ * types and pointing out recent ANSI C support for uintXX_t in inttypes.h.
+ */
+#ifdef SHA2_USE_INTTYPES_H
+
+typedef uint8_t  sha2_byte;    /* Exactly 1 byte */
+typedef uint32_t sha2_word32;  /* Exactly 4 bytes */
+typedef uint64_t sha2_word64;  /* Exactly 8 bytes */
+
+#else /* SHA2_USE_INTTYPES_H */
+
+typedef u_int8_t  sha2_byte;   /* Exactly 1 byte */
+typedef u_int32_t sha2_word32; /* Exactly 4 bytes */
+typedef u_int64_t sha2_word64; /* Exactly 8 bytes */
+
+#endif /* SHA2_USE_INTTYPES_H */
+
+
+/*** SHA-256/384/512 Various Length Definitions ***********************/
+/* NOTE: Most of these are in sha2.h */
+#define SHA256_SHORT_BLOCK_LENGTH      (SHA256_BLOCK_LENGTH - 8)
+#ifndef PSSH_NO_BIG_SHA2
+#define SHA384_SHORT_BLOCK_LENGTH      (SHA384_BLOCK_LENGTH - 16)
+#define SHA512_SHORT_BLOCK_LENGTH      (SHA512_BLOCK_LENGTH - 16)
+#endif
+
+
+/*** ENDIAN REVERSAL MACROS *******************************************/
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define REVERSE32(w,x) { \
+       sha2_word32 tmp = (w); \
+       tmp = (tmp >> 16) | (tmp << 16); \
+       (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
+}
+#define REVERSE64(w,x) { \
+       sha2_word64 tmp = (w); \
+       tmp = (tmp >> 32) | (tmp << 32); \
+       tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
+             ((tmp & 0x00ff00ff00ff00ffULL) << 8); \
+       (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
+             ((tmp & 0x0000ffff0000ffffULL) << 16); \
+}
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+/*
+ * Macro for incrementally adding the unsigned 64-bit integer n to the
+ * unsigned 128-bit integer (represented using a two-element array of
+ * 64-bit words):
+ */
+#define ADDINC128(w,n) { \
+       (w)[0] += (sha2_word64)(n); \
+       if ((w)[0] < (n)) { \
+               (w)[1]++; \
+       } \
+}
+
+/*
+ * Macros for copying blocks of memory and for zeroing out ranges
+ * of memory.  Using these macros makes it easy to switch from
+ * using memset()/memcpy() and using bzero()/bcopy().
+ *
+ * Please define either SHA2_USE_MEMSET_MEMCPY or define
+ * SHA2_USE_BZERO_BCOPY depending on which function set you
+ * choose to use:
+ */
+#if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY)
+/* Default to memset()/memcpy() if no option is specified */
+#define        SHA2_USE_MEMSET_MEMCPY  1
+#endif
+#if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY)
+/* Abort with an error if BOTH options are defined */
+#error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!
+#endif
+
+#ifdef SHA2_USE_MEMSET_MEMCPY
+#define MEMSET_BZERO(p,l)      memset((p), 0, (l))
+#define MEMCPY_BCOPY(d,s,l)    memcpy((d), (s), (l))
+#endif
+#ifdef SHA2_USE_BZERO_BCOPY
+#define MEMSET_BZERO(p,l)      bzero((p), (l))
+#define MEMCPY_BCOPY(d,s,l)    bcopy((s), (d), (l))
+#endif
+
+
+/*** THE SIX LOGICAL FUNCTIONS ****************************************/
+/*
+ * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
+ *
+ *   NOTE:  The naming of R and S appears backwards here (R is a SHIFT and
+ *   S is a ROTATION) because the SHA-256/384/512 description document
+ *   (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
+ *   same "backwards" definition.
+ */
+/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
+#define R(b,x)                 ((x) >> (b))
+/* 32-bit Rotate-right (used in SHA-256): */
+#define S32(b,x)       (((x) >> (b)) | ((x) << (32 - (b))))
+/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
+#define S64(b,x)       (((x) >> (b)) | ((x) << (64 - (b))))
+
+/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
+#define Ch(x,y,z)      (((x) & (y)) ^ ((~(x)) & (z)))
+#define Maj(x,y,z)     (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+/* Four of six logical functions used in SHA-256: */
+#define Sigma0_256(x)  (S32(2,  (x)) ^ S32(13, (x)) ^ S32(22, (x)))
+#define Sigma1_256(x)  (S32(6,  (x)) ^ S32(11, (x)) ^ S32(25, (x)))
+#define sigma0_256(x)  (S32(7,  (x)) ^ S32(18, (x)) ^ R(3 ,   (x)))
+#define sigma1_256(x)  (S32(17, (x)) ^ S32(19, (x)) ^ R(10,   (x)))
+
+/* Four of six logical functions used in SHA-384 and SHA-512: */
+#ifndef PSSH_NO_BIG_SHA2
+#define Sigma0_512(x)  (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
+#define Sigma1_512(x)  (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
+#define sigma0_512(x)  (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7,   (x)))
+#define sigma1_512(x)  (S64(19, (x)) ^ S64(61, (x)) ^ R( 6,   (x)))
+#endif
+
+/*** INTERNAL FUNCTION PROTOTYPES *************************************/
+/* NOTE: These should not be accessed directly from outside this
+ * library -- they are intended for private internal visibility/use
+ * only.
+ */
+static void SHA256_Transform(SHA256_CTX*, const sha2_word32*);
+#ifndef PSSH_NO_BIG_SHA2
+static void SHA512_Transform(SHA512_CTX*, const sha2_word64*);
+static void SHA512_Last(SHA512_CTX*);
+#endif
+
+
+/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
+/* Hash constant words K for SHA-256: */
+static const sha2_word32 K256[64] = {
+       0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
+       0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
+       0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
+       0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
+       0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+       0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
+       0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
+       0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
+       0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
+       0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+       0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
+       0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
+       0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
+       0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
+       0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+       0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
+};
+
+/* Initial hash value H for SHA-256: */
+static const sha2_word32 sha256_initial_hash_value[8] = {
+       0x6a09e667UL,
+       0xbb67ae85UL,
+       0x3c6ef372UL,
+       0xa54ff53aUL,
+       0x510e527fUL,
+       0x9b05688cUL,
+       0x1f83d9abUL,
+       0x5be0cd19UL
+};
+
+#ifndef PSSH_NO_BIG_SHA2
+/* Hash constant words K for SHA-384 and SHA-512: */
+const static sha2_word64 K512[80] = {
+       0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
+       0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
+       0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+       0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
+       0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
+       0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+       0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
+       0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
+       0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+       0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
+       0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
+       0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+       0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
+       0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
+       0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+       0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
+       0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
+       0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+       0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
+       0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
+       0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+       0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
+       0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
+       0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+       0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
+       0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
+       0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+       0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
+       0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
+       0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+       0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
+       0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
+       0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+       0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
+       0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
+       0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+       0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
+       0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
+       0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+       0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
+};
+
+/* Initial hash value H for SHA-384 */
+const static sha2_word64 sha384_initial_hash_value[8] = {
+       0xcbbb9d5dc1059ed8ULL,
+       0x629a292a367cd507ULL,
+       0x9159015a3070dd17ULL,
+       0x152fecd8f70e5939ULL,
+       0x67332667ffc00b31ULL,
+       0x8eb44a8768581511ULL,
+       0xdb0c2e0d64f98fa7ULL,
+       0x47b5481dbefa4fa4ULL
+};
+
+/* Initial hash value H for SHA-512 */
+const static sha2_word64 sha512_initial_hash_value[8] = {
+       0x6a09e667f3bcc908ULL,
+       0xbb67ae8584caa73bULL,
+       0x3c6ef372fe94f82bULL,
+       0xa54ff53a5f1d36f1ULL,
+       0x510e527fade682d1ULL,
+       0x9b05688c2b3e6c1fULL,
+       0x1f83d9abfb41bd6bULL,
+       0x5be0cd19137e2179ULL
+};
+#endif
+
+/*
+ * Constant used by SHA256/384/512_End() functions for converting the
+ * digest to a readable hexadecimal character string:
+ */
+static const char *sha2_hex_digits = "0123456789abcdef";
+
+
+/*** SHA-256: *********************************************************/
+void SHA256_Init(SHA256_CTX* context) {
+       if (context == (SHA256_CTX*)0) {
+               return;
+       }
+       MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
+       MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH);
+       context->bitcount = 0;
+}
+
+#ifdef SHA2_UNROLL_TRANSFORM
+
+/* Unrolled SHA-256 round macros: */
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)      \
+       REVERSE32(*data++, W256[j]); \
+       T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
+             K256[j] + W256[j]; \
+       (d) += T1; \
+       (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
+       j++
+
+
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)      \
+       T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
+            K256[j] + (W256[j] = *data++); \
+       (d) += T1; \
+       (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
+       j++
+
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND256(a,b,c,d,e,f,g,h)      \
+       s0 = W256[(j+1)&0x0f]; \
+       s0 = sigma0_256(s0); \
+       s1 = W256[(j+14)&0x0f]; \
+       s1 = sigma1_256(s1); \
+       T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
+            (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
+       (d) += T1; \
+       (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
+       j++
+
+void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
+       sha2_word32     a, b, c, d, e, f, g, h, s0, s1;
+       sha2_word32     T1, *W256;
+       int             j;
+
+       W256 = (sha2_word32*)context->buffer;
+
+       /* Initialize registers with the prev. intermediate value */
+       a = context->state[0];
+       b = context->state[1];
+       c = context->state[2];
+       d = context->state[3];
+       e = context->state[4];
+       f = context->state[5];
+       g = context->state[6];
+       h = context->state[7];
+
+       j = 0;
+       do {
+               /* Rounds 0 to 15 (unrolled): */
+               ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
+               ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
+               ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
+               ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
+               ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
+               ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
+               ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
+               ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
+       } while (j < 16);
+
+       /* Now for the remaining rounds to 64: */
+       do {
+               ROUND256(a,b,c,d,e,f,g,h);
+               ROUND256(h,a,b,c,d,e,f,g);
+               ROUND256(g,h,a,b,c,d,e,f);
+               ROUND256(f,g,h,a,b,c,d,e);
+               ROUND256(e,f,g,h,a,b,c,d);
+               ROUND256(d,e,f,g,h,a,b,c);
+               ROUND256(c,d,e,f,g,h,a,b);
+               ROUND256(b,c,d,e,f,g,h,a);
+       } while (j < 64);
+
+       /* Compute the current intermediate hash value */
+       context->state[0] += a;
+       context->state[1] += b;
+       context->state[2] += c;
+       context->state[3] += d;
+       context->state[4] += e;
+       context->state[5] += f;
+       context->state[6] += g;
+       context->state[7] += h;
+
+       /* Clean up */
+       a = b = c = d = e = f = g = h = T1 = 0;
+}
+
+#else /* SHA2_UNROLL_TRANSFORM */
+
+void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
+       sha2_word32     a, b, c, d, e, f, g, h, s0, s1;
+       sha2_word32     T1, T2, *W256;
+       int             j;
+
+       W256 = (sha2_word32*)context->buffer;
+
+       /* Initialize registers with the prev. intermediate value */
+       a = context->state[0];
+       b = context->state[1];
+       c = context->state[2];
+       d = context->state[3];
+       e = context->state[4];
+       f = context->state[5];
+       g = context->state[6];
+       h = context->state[7];
+
+       j = 0;
+       do {
+#if BYTE_ORDER == LITTLE_ENDIAN
+               /* Copy data while converting to host byte order */
+               REVERSE32(*data++,W256[j]);
+               /* Apply the SHA-256 compression function to update a..h */
+               T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+               /* Apply the SHA-256 compression function to update a..h with copy */
+               T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+               T2 = Sigma0_256(a) + Maj(a, b, c);
+               h = g;
+               g = f;
+               f = e;
+               e = d + T1;
+               d = c;
+               c = b;
+               b = a;
+               a = T1 + T2;
+
+               j++;
+       } while (j < 16);
+
+       do {
+               /* Part of the message block expansion: */
+               s0 = W256[(j+1)&0x0f];
+               s0 = sigma0_256(s0);
+               s1 = W256[(j+14)&0x0f]; 
+               s1 = sigma1_256(s1);
+
+               /* Apply the SHA-256 compression function to update a..h */
+               T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + 
+                    (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
+               T2 = Sigma0_256(a) + Maj(a, b, c);
+               h = g;
+               g = f;
+               f = e;
+               e = d + T1;
+               d = c;
+               c = b;
+               b = a;
+               a = T1 + T2;
+
+               j++;
+       } while (j < 64);
+
+       /* Compute the current intermediate hash value */
+       context->state[0] += a;
+       context->state[1] += b;
+       context->state[2] += c;
+       context->state[3] += d;
+       context->state[4] += e;
+       context->state[5] += f;
+       context->state[6] += g;
+       context->state[7] += h;
+
+       /* Clean up */
+       a = b = c = d = e = f = g = h = T1 = T2 = 0;
+}
+
+#endif /* SHA2_UNROLL_TRANSFORM */
+
+void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
+       unsigned int    freespace, usedspace;
+
+       if (len == 0) {
+               /* Calling with no data is valid - we do nothing */
+               return;
+       }
+
+       /* Sanity check: */
+       assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0);
+
+       usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
+       if (usedspace > 0) {
+               /* Calculate how much free space is available in the buffer */
+               freespace = SHA256_BLOCK_LENGTH - usedspace;
+
+               if (len >= freespace) {
+                       /* Fill the buffer completely and process it */
+                       MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
+                       context->bitcount += freespace << 3;
+                       len -= freespace;
+                       data += freespace;
+                       SHA256_Transform(context, (sha2_word32*)context->buffer);
+               } else {
+                       /* The buffer is not yet full */
+                       MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
+                       context->bitcount += len << 3;
+                       /* Clean up: */
+                       usedspace = freespace = 0;
+                       return;
+               }
+       }
+       while (len >= SHA256_BLOCK_LENGTH) {
+               /* Process as many complete blocks as we can */
+               SHA256_Transform(context, (sha2_word32*)data);
+               context->bitcount += SHA256_BLOCK_LENGTH << 3;
+               len -= SHA256_BLOCK_LENGTH;
+               data += SHA256_BLOCK_LENGTH;
+       }
+       if (len > 0) {
+               /* There's left-overs, so save 'em */
+               MEMCPY_BCOPY(context->buffer, data, len);
+               context->bitcount += len << 3;
+       }
+       /* Clean up: */
+       usedspace = freespace = 0;
+}
+
+void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) {
+       sha2_word32     *d = (sha2_word32*)digest;
+       unsigned int    usedspace;
+
+       /* Sanity check: */
+       assert(context != (SHA256_CTX*)0);
+
+       /* If no digest buffer is passed, we don't bother doing this: */
+       if (digest != (sha2_byte*)0) {
+               usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
+#if BYTE_ORDER == LITTLE_ENDIAN
+               /* Convert FROM host byte order */
+               REVERSE64(context->bitcount,context->bitcount);
+#endif
+               if (usedspace > 0) {
+                       /* Begin padding with a 1 bit: */
+                       context->buffer[usedspace++] = 0x80;
+
+                       if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
+                               /* Set-up for the last transform: */
+                               MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);
+                       } else {
+                               if (usedspace < SHA256_BLOCK_LENGTH) {
+                                       MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
+                               }
+                               /* Do second-to-last transform: */
+                               SHA256_Transform(context, (sha2_word32*)context->buffer);
+
+                               /* And set-up for the last transform: */
+                               MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
+                       }
+               } else {
+                       /* Set-up for the last transform: */
+                       MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
+
+                       /* Begin padding with a 1 bit: */
+                       *context->buffer = 0x80;
+               }
+               /* Set the bit count: */
+               *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;
+
+               /* Final transform: */
+               SHA256_Transform(context, (sha2_word32*)context->buffer);
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+               {
+                       /* Convert TO host byte order */
+                       int     j;
+                       for (j = 0; j < 8; j++) {
+                               REVERSE32(context->state[j],context->state[j]);
+                               *d++ = context->state[j];
+                       }
+               }
+#else
+               MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH);
+#endif
+       }
+
+       /* Clean up state data: */
+       MEMSET_BZERO(context, sizeof(context));
+       usedspace = 0;
+}
+
+char *SHA256_End(SHA256_CTX* context, char buffer[]) {
+       sha2_byte       digest[SHA256_DIGEST_LENGTH], *d = digest;
+       int             i;
+
+       /* Sanity check: */
+       assert(context != (SHA256_CTX*)0);
+
+       if (buffer != (char*)0) {
+               SHA256_Final(digest, context);
+
+               for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
+                       *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
+                       *buffer++ = sha2_hex_digits[*d & 0x0f];
+                       d++;
+               }
+               *buffer = (char)0;
+       } else {
+               MEMSET_BZERO(context, sizeof(context));
+       }
+       MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH);
+       return buffer;
+}
+
+char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) {
+       SHA256_CTX      context;
+
+       SHA256_Init(&context);
+       SHA256_Update(&context, data, len);
+       return SHA256_End(&context, digest);
+}
+
+
+/*** SHA-512: *********************************************************/
+
+#ifndef PSSH_NO_BIG_SHA2
+
+void SHA512_Init(SHA512_CTX* context) {
+       if (context == (SHA512_CTX*)0) {
+               return;
+       }
+       MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
+       MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH);
+       context->bitcount[0] = context->bitcount[1] =  0;
+}
+
+#ifdef SHA2_UNROLL_TRANSFORM
+
+/* Unrolled SHA-512 round macros: */
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)      \
+       REVERSE64(*data++, W512[j]); \
+       T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
+             K512[j] + W512[j]; \
+       (d) += T1, \
+       (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \
+       j++
+
+
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)      \
+       T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
+             K512[j] + (W512[j] = *data++); \
+       (d) += T1; \
+       (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
+       j++
+
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND512(a,b,c,d,e,f,g,h)      \
+       s0 = W512[(j+1)&0x0f]; \
+       s0 = sigma0_512(s0); \
+       s1 = W512[(j+14)&0x0f]; \
+       s1 = sigma1_512(s1); \
+       T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
+             (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
+       (d) += T1; \
+       (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
+       j++
+
+void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
+       sha2_word64     a, b, c, d, e, f, g, h, s0, s1;
+       sha2_word64     T1, *W512 = (sha2_word64*)context->buffer;
+       int             j;
+
+       /* Initialize registers with the prev. intermediate value */
+       a = context->state[0];
+       b = context->state[1];
+       c = context->state[2];
+       d = context->state[3];
+       e = context->state[4];
+       f = context->state[5];
+       g = context->state[6];
+       h = context->state[7];
+
+       j = 0;
+       do {
+               ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
+               ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
+               ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
+               ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
+               ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
+               ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
+               ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
+               ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
+       } while (j < 16);
+
+       /* Now for the remaining rounds up to 79: */
+       do {
+               ROUND512(a,b,c,d,e,f,g,h);
+               ROUND512(h,a,b,c,d,e,f,g);
+               ROUND512(g,h,a,b,c,d,e,f);
+               ROUND512(f,g,h,a,b,c,d,e);
+               ROUND512(e,f,g,h,a,b,c,d);
+               ROUND512(d,e,f,g,h,a,b,c);
+               ROUND512(c,d,e,f,g,h,a,b);
+               ROUND512(b,c,d,e,f,g,h,a);
+       } while (j < 80);
+
+       /* Compute the current intermediate hash value */
+       context->state[0] += a;
+       context->state[1] += b;
+       context->state[2] += c;
+       context->state[3] += d;
+       context->state[4] += e;
+       context->state[5] += f;
+       context->state[6] += g;
+       context->state[7] += h;
+
+       /* Clean up */
+       a = b = c = d = e = f = g = h = T1 = 0;
+}
+
+#else /* SHA2_UNROLL_TRANSFORM */
+
+void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
+       sha2_word64     a, b, c, d, e, f, g, h, s0, s1;
+       sha2_word64     T1, T2, *W512 = (sha2_word64*)context->buffer;
+       int             j;
+
+       /* Initialize registers with the prev. intermediate value */
+       a = context->state[0];
+       b = context->state[1];
+       c = context->state[2];
+       d = context->state[3];
+       e = context->state[4];
+       f = context->state[5];
+       g = context->state[6];
+       h = context->state[7];
+
+       j = 0;
+       do {
+#if BYTE_ORDER == LITTLE_ENDIAN
+               /* Convert TO host byte order */
+               REVERSE64(*data++, W512[j]);
+               /* Apply the SHA-512 compression function to update a..h */
+               T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+               /* Apply the SHA-512 compression function to update a..h with copy */
+               T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+               T2 = Sigma0_512(a) + Maj(a, b, c);
+               h = g;
+               g = f;
+               f = e;
+               e = d + T1;
+               d = c;
+               c = b;
+               b = a;
+               a = T1 + T2;
+
+               j++;
+       } while (j < 16);
+
+       do {
+               /* Part of the message block expansion: */
+               s0 = W512[(j+1)&0x0f];
+               s0 = sigma0_512(s0);
+               s1 = W512[(j+14)&0x0f];
+               s1 =  sigma1_512(s1);
+
+               /* Apply the SHA-512 compression function to update a..h */
+               T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
+                    (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
+               T2 = Sigma0_512(a) + Maj(a, b, c);
+               h = g;
+               g = f;
+               f = e;
+               e = d + T1;
+               d = c;
+               c = b;
+               b = a;
+               a = T1 + T2;
+
+               j++;
+       } while (j < 80);
+
+       /* Compute the current intermediate hash value */
+       context->state[0] += a;
+       context->state[1] += b;
+       context->state[2] += c;
+       context->state[3] += d;
+       context->state[4] += e;
+       context->state[5] += f;
+       context->state[6] += g;
+       context->state[7] += h;
+
+       /* Clean up */
+       a = b = c = d = e = f = g = h = T1 = T2 = 0;
+}
+
+#endif /* SHA2_UNROLL_TRANSFORM */
+
+void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
+       unsigned int    freespace, usedspace;
+
+       if (len == 0) {
+               /* Calling with no data is valid - we do nothing */
+               return;
+       }
+
+       /* Sanity check: */
+       assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0);
+
+       usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
+       if (usedspace > 0) {
+               /* Calculate how much free space is available in the buffer */
+               freespace = SHA512_BLOCK_LENGTH - usedspace;
+
+               if (len >= freespace) {
+                       /* Fill the buffer completely and process it */
+                       MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
+                       ADDINC128(context->bitcount, freespace << 3);
+                       len -= freespace;
+                       data += freespace;
+                       SHA512_Transform(context, (sha2_word64*)context->buffer);
+               } else {
+                       /* The buffer is not yet full */
+                       MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
+                       ADDINC128(context->bitcount, len << 3);
+                       /* Clean up: */
+                       usedspace = freespace = 0;
+                       return;
+               }
+       }
+       while (len >= SHA512_BLOCK_LENGTH) {
+               /* Process as many complete blocks as we can */
+               SHA512_Transform(context, (sha2_word64*)data);
+               ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
+               len -= SHA512_BLOCK_LENGTH;
+               data += SHA512_BLOCK_LENGTH;
+       }
+       if (len > 0) {
+               /* There's left-overs, so save 'em */
+               MEMCPY_BCOPY(context->buffer, data, len);
+               ADDINC128(context->bitcount, len << 3);
+       }
+       /* Clean up: */
+       usedspace = freespace = 0;
+}
+
+void SHA512_Last(SHA512_CTX* context) {
+       unsigned int    usedspace;
+
+       usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
+#if BYTE_ORDER == LITTLE_ENDIAN
+       /* Convert FROM host byte order */
+       REVERSE64(context->bitcount[0],context->bitcount[0]);
+       REVERSE64(context->bitcount[1],context->bitcount[1]);
+#endif
+       if (usedspace > 0) {
+               /* Begin padding with a 1 bit: */
+               context->buffer[usedspace++] = 0x80;
+
+               if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
+                       /* Set-up for the last transform: */
+                       MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
+               } else {
+                       if (usedspace < SHA512_BLOCK_LENGTH) {
+                               MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
+                       }
+                       /* Do second-to-last transform: */
+                       SHA512_Transform(context, (sha2_word64*)context->buffer);
+
+                       /* And set-up for the last transform: */
+                       MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2);
+               }
+       } else {
+               /* Prepare for final transform: */
+               MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH);
+
+               /* Begin padding with a 1 bit: */
+               *context->buffer = 0x80;
+       }
+       /* Store the length of input data (in bits): */
+       *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1];
+       *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0];
+
+       /* Final transform: */
+       SHA512_Transform(context, (sha2_word64*)context->buffer);
+}
+
+void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) {
+       sha2_word64     *d = (sha2_word64*)digest;
+
+       /* Sanity check: */
+       assert(context != (SHA512_CTX*)0);
+
+       /* If no digest buffer is passed, we don't bother doing this: */
+       if (digest != (sha2_byte*)0) {
+               SHA512_Last(context);
+
+               /* Save the hash data for output: */
+#if BYTE_ORDER == LITTLE_ENDIAN
+               {
+                       /* Convert TO host byte order */
+                       int     j;
+                       for (j = 0; j < 8; j++) {
+                               REVERSE64(context->state[j],context->state[j]);
+                               *d++ = context->state[j];
+                       }
+               }
+#else
+               MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH);
+#endif
+       }
+
+       /* Zero out state data */
+       MEMSET_BZERO(context, sizeof(context));
+}
+
+char *SHA512_End(SHA512_CTX* context, char buffer[]) {
+       sha2_byte       digest[SHA512_DIGEST_LENGTH], *d = digest;
+       int             i;
+
+       /* Sanity check: */
+       assert(context != (SHA512_CTX*)0);
+
+       if (buffer != (char*)0) {
+               SHA512_Final(digest, context);
+
+               for (i = 0; i < SHA512_DIGEST_LENGTH; i++) {
+                       *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
+                       *buffer++ = sha2_hex_digits[*d & 0x0f];
+                       d++;
+               }
+               *buffer = (char)0;
+       } else {
+               MEMSET_BZERO(context, sizeof(context));
+       }
+       MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH);
+       return buffer;
+}
+
+char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) {
+       SHA512_CTX      context;
+
+       SHA512_Init(&context);
+       SHA512_Update(&context, data, len);
+       return SHA512_End(&context, digest);
+}
+
+#endif
+
+/*** SHA-384: *********************************************************/
+
+#ifndef PSSH_NO_BIG_SHA2
+
+void SHA384_Init(SHA384_CTX* context) {
+       if (context == (SHA384_CTX*)0) {
+               return;
+       }
+       MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH);
+       MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH);
+       context->bitcount[0] = context->bitcount[1] = 0;
+}
+
+void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) {
+       SHA512_Update((SHA512_CTX*)context, data, len);
+}
+
+void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) {
+       sha2_word64     *d = (sha2_word64*)digest;
+
+       /* Sanity check: */
+       assert(context != (SHA384_CTX*)0);
+
+       /* If no digest buffer is passed, we don't bother doing this: */
+       if (digest != (sha2_byte*)0) {
+               SHA512_Last((SHA512_CTX*)context);
+
+               /* Save the hash data for output: */
+#if BYTE_ORDER == LITTLE_ENDIAN
+               {
+                       /* Convert TO host byte order */
+                       int     j;
+                       for (j = 0; j < 6; j++) {
+                               REVERSE64(context->state[j],context->state[j]);
+                               *d++ = context->state[j];
+                       }
+               }
+#else
+               MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH);
+#endif
+       }
+
+       /* Zero out state data */
+       MEMSET_BZERO(context, sizeof(context));
+}
+
+char *SHA384_End(SHA384_CTX* context, char buffer[]) {
+       sha2_byte       digest[SHA384_DIGEST_LENGTH], *d = digest;
+       int             i;
+
+       /* Sanity check: */
+       assert(context != (SHA384_CTX*)0);
+
+       if (buffer != (char*)0) {
+               SHA384_Final(digest, context);
+
+               for (i = 0; i < SHA384_DIGEST_LENGTH; i++) {
+                       *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
+                       *buffer++ = sha2_hex_digits[*d & 0x0f];
+                       d++;
+               }
+               *buffer = (char)0;
+       } else {
+               MEMSET_BZERO(context, sizeof(context));
+       }
+       MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH);
+       return buffer;
+}
+
+char* SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) {
+       SHA384_CTX      context;
+
+       SHA384_Init(&context);
+       SHA384_Update(&context, data, len);
+       return SHA384_End(&context, digest);
+}
+
+#endif
diff --git a/arm/crypto/sha2/sha2.h b/arm/crypto/sha2/sha2.h
new file mode 100644 (file)
index 0000000..19890bf
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * FILE:       sha2.h
+ * AUTHOR:     Aaron D. Gifford <me@aarongifford.com>
+ * 
+ * Copyright (c) 2000-2001, Aaron D. Gifford
+ * 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. Neither the name of the copyright holder nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 CONTRIBUTOR(S) 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.
+ *
+ * $Id: sha2.h,v 1.3 2004/12/30 01:56:29 admin Exp $
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// disabled SHA-384 and SHA-512 (PSSH_NO_BIG_SHA2)
+// use BIG-ENDIAN for Palm 68K (fixme armify?)
+
+#ifndef __SHA2_H__
+#define __SHA2_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "includes.h"
+#define SHA2_USE_INTTYPES_H
+#define PSSH_NO_BIG_SHA2
+#define BYTE_ORDER BIG_ENDIAN
+
+/*** SHA-256/384/512 Various Length Definitions ***********************/
+#define SHA256_BLOCK_LENGTH            64
+#define SHA256_DIGEST_LENGTH           32
+#define SHA256_DIGEST_STRING_LENGTH    (SHA256_DIGEST_LENGTH * 2 + 1)
+#ifndef PSSH_NO_BIG_SHA2
+#define SHA384_BLOCK_LENGTH            128
+#define SHA384_DIGEST_LENGTH           48
+#define SHA384_DIGEST_STRING_LENGTH    (SHA384_DIGEST_LENGTH * 2 + 1)
+#define SHA512_BLOCK_LENGTH            128
+#define SHA512_DIGEST_LENGTH           64
+#define SHA512_DIGEST_STRING_LENGTH    (SHA512_DIGEST_LENGTH * 2 + 1)
+#endif
+
+
+/*** SHA-256/384/512 Context Structures *******************************/
+/* NOTE: If your architecture does not define either u_intXX_t types or
+ * uintXX_t (from inttypes.h), you may need to define things by hand
+ * for your system:
+ */
+#if 0
+typedef unsigned char u_int8_t;                /* 1-byte  (8-bits)  */
+typedef unsigned int u_int32_t;                /* 4-bytes (32-bits) */
+typedef unsigned long long u_int64_t;  /* 8-bytes (64-bits) */
+#endif
+/*
+ * Most BSD systems already define u_intXX_t types, as does Linux.
+ * Some systems, however, like Compaq's Tru64 Unix instead can use
+ * uintXX_t types defined by very recent ANSI C standards and included
+ * in the file:
+ *
+ *   #include <inttypes.h>
+ *
+ * If you choose to use <inttypes.h> then please define: 
+ *
+ *   #define SHA2_USE_INTTYPES_H
+ *
+ * Or on the command line during compile:
+ *
+ *   cc -DSHA2_USE_INTTYPES_H ...
+ */
+#ifdef SHA2_USE_INTTYPES_H
+
+typedef struct _SHA256_CTX {
+       uint32_t        state[8];
+       uint64_t        bitcount;
+       uint8_t buffer[SHA256_BLOCK_LENGTH];
+} SHA256_CTX;
+#ifndef PSSH_NO_BIG_SHA2
+typedef struct _SHA512_CTX {
+       uint64_t        state[8];
+       uint64_t        bitcount[2];
+       uint8_t buffer[SHA512_BLOCK_LENGTH];
+} SHA512_CTX;
+#endif
+
+#else /* SHA2_USE_INTTYPES_H */
+
+typedef struct _SHA256_CTX {
+       u_int32_t       state[8];
+       u_int64_t       bitcount;
+       u_int8_t        buffer[SHA256_BLOCK_LENGTH];
+} SHA256_CTX;
+#ifndef PSSH_NO_BIG_SHA2
+typedef struct _SHA512_CTX {
+       u_int64_t       state[8];
+       u_int64_t       bitcount[2];
+       u_int8_t        buffer[SHA512_BLOCK_LENGTH];
+} SHA512_CTX;
+#endif
+
+#endif /* SHA2_USE_INTTYPES_H */
+
+#ifndef PSSH_NO_BIG_SHA2
+typedef SHA512_CTX SHA384_CTX;
+#endif
+
+
+/*** SHA-256/384/512 Function Prototypes ******************************/
+#ifndef NOPROTO
+#ifdef SHA2_USE_INTTYPES_H
+
+void SHA256_Init(SHA256_CTX *);
+void SHA256_Update(SHA256_CTX*, const uint8_t*, size_t);
+void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*);
+char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]);
+char* SHA256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]);
+
+#ifndef PSSH_NO_BIG_SHA2
+void SHA384_Init(SHA384_CTX*);
+void SHA384_Update(SHA384_CTX*, const uint8_t*, size_t);
+void SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*);
+char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]);
+char* SHA384_Data(const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]);
+
+void SHA512_Init(SHA512_CTX*);
+void SHA512_Update(SHA512_CTX*, const uint8_t*, size_t);
+void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
+char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]);
+char* SHA512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]);
+#endif
+
+#else /* SHA2_USE_INTTYPES_H */
+
+void SHA256_Init(SHA256_CTX *);
+void SHA256_Update(SHA256_CTX*, const u_int8_t*, size_t);
+void SHA256_Final(u_int8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*);
+char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]);
+char* SHA256_Data(const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]);
+
+#ifndef PSSH_NO_BIG_SHA2
+void SHA384_Init(SHA384_CTX*);
+void SHA384_Update(SHA384_CTX*, const u_int8_t*, size_t);
+void SHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*);
+char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]);
+char* SHA384_Data(const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]);
+
+void SHA512_Init(SHA512_CTX*);
+void SHA512_Update(SHA512_CTX*, const u_int8_t*, size_t);
+void SHA512_Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
+char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]);
+char* SHA512_Data(const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]);
+#endif
+
+#endif /* SHA2_USE_INTTYPES_H */
+
+#else /* NOPROTO */
+
+void SHA256_Init();
+void SHA256_Update();
+void SHA256_Final();
+char* SHA256_End();
+char* SHA256_Data();
+
+#ifndef PSSH_NO_BIG_SHA2
+void SHA384_Init();
+void SHA384_Update();
+void SHA384_Final();
+char* SHA384_End();
+char* SHA384_Data();
+
+void SHA512_Init();
+void SHA512_Update();
+void SHA512_Final();
+char* SHA512_End();
+char* SHA512_Data();
+#endif
+
+#endif /* NOPROTO */
+
+#ifdef PSSH_CRYPTOTESTS
+int sha2test(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __SHA2_H__ */
+
diff --git a/arm/data/prefs.c b/arm/data/prefs.c
new file mode 100644 (file)
index 0000000..ca684f9
--- /dev/null
@@ -0,0 +1,145 @@
+/**********
+ * Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "prefs.h"
+#include "pace.h"
+
+// There is one global default prefs list. 
+// There is also a set of override values for each connection, mostly 
+// for terminal settings.
+
+// Each preference is a RESOURCE
+// res type: 'dflt' or some ID for a connection override
+// res id: which pref
+
+/* 
+   interface: 
+   echo password (NO)
+   keyboard pane(s)
+   
+   terminal:
+   TERM type ("xterm")
+   scrollback line count (500?)
+   scroll down on input (NO)
+   scroll down on keypress (YES)
+   
+   ssh:
+   compression (NO) (fixme implement)
+   ciphers ("aes128-cbc,3des-cbc")
+   authmethod (fixme implement)
+   
+   putty terminal:
+   wrap_mode (YES==autowrap)
+   dec_om "DEC Origin Mode" (YES)
+   lfhascr "Implicit CR in every LF" (NO)
+   bce "Background Color Erase" (?)
+   blink_text "Blink" (NO)
+   answerback "Answerback to ^E" ("pssh")
+   localecho (NO)
+   localedit (NO)
+   printing (NO)
+
+   putty keyboard:
+   bksp_is_delete "Backspace is DEL" (YES==^? rather than ^H)
+   rxvt_homeend "rxvt Home and End" (NO)
+   funky_type "Function Keys" (DIGITAL, Linux, xterm, VT400, VT100+, SCO)
+   app_cursor "Application Cursor Keys" (NO?)
+   app_keypad "Application Keypad" (NO?)
+   nethack "NetHack Keypad" (NO)
+   compose (NO) (use real compose key on keyboard?)
+   ctrlalt (NO)
+   
+   lots more putty...
+   
+*/
+
+
+#define noRecord ((UInt16)0xffff)
+
+
+uintptr_t PrefsInit_68K = 0;
+uintptr_t PrefsGetInt_68K = 0;
+uintptr_t PrefsGetString_68K = 0;
+uintptr_t PrefsPutInt_68K = 0;
+uintptr_t PrefsPutString_68K = 0;
+
+// static DmOpenRef PrefsDB = 0;
+// fixme implement overrides
+
+// extern DmOpenRef OpenDB(UInt32 type, char *name, Boolean resDB, Boolean create);
+
+int PrefsInit(void)
+{
+    PACE_PARAMS = {
+        0
+    };
+
+    return (int) PACE_EXEC_FN(PrefsInit_68K, 0);
+}
+
+
+uint32_t PrefsGetInt(uint32_t which, uint32_t defaultValue)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(which)
+        PACE_PARAMS_ADD32(defaultValue)
+    };
+
+    return (uint32_t) PACE_EXEC_FN(PrefsGetInt_68K, 0);
+}
+
+
+void PrefsPutInt(uint32_t which, uint32_t value)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(which)
+        PACE_PARAMS_ADD32(value)
+    };
+
+    PACE_EXEC_FN(PrefsPutInt_68K, 0);
+}
+
+
+char *PrefsGetString(uint32_t which, char *defaultValue)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(which)
+        PACE_PARAMS_ADD32(defaultValue)
+    };
+
+    return (char *) PACE_EXEC_FN(PrefsGetString_68K, kPceNativeWantA0);
+}
+
+
+void PrefsPutString(uint32_t which, char *value)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(which)
+        PACE_PARAMS_ADD32(value)
+    };
+
+    PACE_EXEC_FN(PrefsPutString_68K, 0);
+}
+
diff --git a/arm/data/prefs.h b/arm/data/prefs.h
new file mode 100644 (file)
index 0000000..722f0d5
--- /dev/null
@@ -0,0 +1,108 @@
+/**********
+ * Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+
+#ifndef PREFS_H
+#define PREFS_H
+
+#include "includes.h"
+
+// Preference values
+// NEVER CHANGE THESE, only add to them.
+
+// non-terminal interface
+#define prefEchoPassword 1 // boolean
+#define prefTopPane 2      // int
+#define prefBottomPane 3   // int
+#define prefNoAutoOff 4    // unused
+#define prefHideTitleBar 5 // boolean
+#define prefHideInputArea 6 // boolean
+
+// ssh
+#define prefCipherAES128CBC 100 // boolean
+#define prefCipher3DESCBC 101   // boolean
+#define prefAuthPublicKey 102   // boolean
+#define prefAuthPassword 103    // boolean
+#define prefCompressZLib 104    // boolean
+
+// basic terminal
+#define prefTerminalType 200          // string
+#define prefScrollbackLines 201       // int
+#define prefScrollDownOnActivity 202  // boolean
+#define prefScrollDownOnTyping 203    // boolean
+#define prefTerminalFont 204          // int
+#define prefTerminalForeColor 205     // int
+#define prefTerminalBackColor 206     // int
+#define prefBellBeep 207              // boolean
+#define prefBellFlash 208             // boolean
+#define prefBackspace 209           // boolean
+
+// values for prefTerminalFont:
+#define font4x6 1
+#define font6x10 2
+#define fontDefault font4x6
+
+
+// values for prefTerminalFore/BackColor
+#define blackColor   0
+#define redColor     1
+#define greenColor   2
+#define yellowColor  3
+#define blueColor    4
+#define magentaColor 5
+#define cyanColor    6
+#define whiteColor   7
+#define defaultForeColor blackColor
+#define defaultBackColor whiteColor
+
+// values for prefScrollbackLines
+#define defaultScrollbackLines 500
+#define maxScrollbackLines 9999
+
+// values for bell
+#define defaultBellBeep 1
+#define defaultBellFlash 0
+
+// values for scroll behavior
+#define defaultScrollDownOnTyping 1
+#define defaultScrollDownOnActivity 0
+
+// values for compression
+// fixme change to 1?
+#define defaultCompressZLib 0
+
+// value for backspace - default is DEL
+#define backspaceDEL 0
+#define backspaceBS 1
+#define defaultBackspace backspaceDEL
+
+
+int PrefsInit(void);
+uint32_t PrefsGetInt(uint32_t which, uint32_t defaultValue);
+void PrefsPutInt(uint32_t which, uint32_t value);
+
+char *PrefsGetString(uint32_t which, char *defaultValue);
+void PrefsPutString(uint32_t which, char *value);
+
+#endif
diff --git a/arm/export-list b/arm/export-list
new file mode 100644 (file)
index 0000000..38341f8
--- /dev/null
@@ -0,0 +1,94 @@
+BN_is_negative_stub
+BN_CTX_new_stub
+BN_CTX_free_stub
+BN_CTX_start_stub
+BN_CTX_get_stub
+BN_CTX_end_stub
+BN_rand_stub
+BN_num_bits_stub
+BN_new_stub
+BN_clear_free_stub
+BN_bin2bn_stub
+BN_bn2bin_stub
+BN_cmp_stub
+BN_free_stub
+BN_is_bit_set_stub
+BN_mod_exp_mont_stub
+BN_mod_exp_mont_word_stub
+BN_bn2hex_stub
+BN_hex2bn_stub
+BN_MONT_CTX_new_stub
+BN_MONT_CTX_free_stub
+BN_MONT_CTX_set_stub
+BN_is_zero_stub
+BN_mod_mul_stub
+BN_ucmp_stub
+BN_mod_inverse_stub
+BN_div_stub
+BN_add_stub
+BN_sub_stub
+BN_rand_range_stub
+BN_time_stub
+
+AES_set_encrypt_key_stub
+AES_set_decrypt_key_stub
+AES_cbc_encrypt_stub
+AES_encrypt_stub
+
+Te0
+Te1
+Te2
+Te3
+Te4
+Td0
+Td1
+Td2
+Td3
+Td4
+
+vt100_new_stub
+vt100_free_stub
+vt100_write_stub
+vt100_update_stub
+vt100_task_stub
+vt100_scroll_stub
+vt100_activate_stub
+vt100_deactivate_stub
+vt100_set_bounds_stub
+vt100_click_stub
+vt100_deselect_stub
+vt100_copy_stub
+vt100_paste_stub
+vt100_selection_exists_stub
+vt100_size_stub
+vt100_reread_prefs_stub
+vt100_seen_key_stub
+vt100_app_cursor_keys_stub
+font_for_screen_stub
+set_palm_color_stub
+
+PrefsInit_68K
+PrefsGetInt_68K
+PrefsGetString_68K
+PrefsPutInt_68K
+PrefsPutString_68K
+ssh_bytes_68K
+assert_failed_68K
+fatal_68K
+arena_malloc_68K
+arena_realloc_68K
+arena_calloc_68K
+arena_free_68K
+
+RAND_init_stub
+RAND_stop_stub
+RAND_bytes_stub
+RAND_add_event_entropy_stub
+RAND_add_net_entropy_stub
+
+zlib_compress_init_stub
+zlib_compress_cleanup_stub
+zlib_compress_block_stub
+zlib_decompress_init_stub
+zlib_decompress_cleanup_stub
+zlib_decompress_block_stub
diff --git a/arm/rsrc/rsrc.h b/arm/rsrc/rsrc.h
new file mode 100644 (file)
index 0000000..6034ce3
--- /dev/null
@@ -0,0 +1,25 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "../../rsrc/rsrc.h"
diff --git a/arm/ssh/openssh/openbsd-compat/CVS/Entries b/arm/ssh/openssh/openbsd-compat/CVS/Entries
new file mode 100644 (file)
index 0000000..b802759
--- /dev/null
@@ -0,0 +1,2 @@
+/bsd-snprintf.c/1.3/Thu Dec 30 01:56:34 2004//Tpssh-2005_06_23
+D
diff --git a/arm/ssh/openssh/openbsd-compat/CVS/Repository b/arm/ssh/openssh/openbsd-compat/CVS/Repository
new file mode 100644 (file)
index 0000000..79162d0
--- /dev/null
@@ -0,0 +1 @@
+pssh-rep/pssh/arm/ssh/openssh/openbsd-compat
diff --git a/arm/ssh/openssh/openbsd-compat/CVS/Root b/arm/ssh/openssh/openbsd-compat/CVS/Root
new file mode 100644 (file)
index 0000000..c78f222
--- /dev/null
@@ -0,0 +1 @@
+/Volumes/poindexter/repository
diff --git a/arm/ssh/openssh/openbsd-compat/CVS/Tag b/arm/ssh/openssh/openbsd-compat/CVS/Tag
new file mode 100644 (file)
index 0000000..5b46a87
--- /dev/null
@@ -0,0 +1 @@
+Npssh-2005_06_23
diff --git a/arm/ssh/openssh/openbsd-compat/bsd-snprintf.c b/arm/ssh/openssh/openbsd-compat/bsd-snprintf.c
new file mode 100644 (file)
index 0000000..bd3e53e
--- /dev/null
@@ -0,0 +1,659 @@
+/*
+ * Copyright Patrick Powell 1995
+ * This code is based on code written by Patrick Powell (papowell@astart.com)
+ * It may be used for any purpose as long as this notice remains intact
+ * on all source code distributions
+ */
+
+/**************************************************************
+ * Original:
+ * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
+ * A bombproof version of doprnt (dopr) included.
+ * Sigh.  This sort of thing is always nasty do deal with.  Note that
+ * the version here does not include floating point...
+ *
+ * snprintf() is used instead of sprintf() as it does limit checks
+ * for string length.  This covers a nasty loophole.
+ *
+ * The other functions are there to prevent NULL pointers from
+ * causing nast effects.
+ *
+ * More Recently:
+ *  Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
+ *  This was ugly.  It is still ugly.  I opted out of floating point
+ *  numbers, but the formatter understands just about everything
+ *  from the normal C string format, at least as far as I can tell from
+ *  the Solaris 2.5 printf(3S) man page.
+ *
+ *  Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1
+ *    Ok, added some minimal floating point support, which means this
+ *    probably requires libm on most operating systems.  Don't yet
+ *    support the exponent (e,E) and sigfig (g,G).  Also, fmtint()
+ *    was pretty badly broken, it just wasn't being exercised in ways
+ *    which showed it, so that's been fixed.  Also, formated the code
+ *    to mutt conventions, and removed dead code left over from the
+ *    original.  Also, there is now a builtin-test, just compile with:
+ *           gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
+ *    and run snprintf for results.
+ * 
+ *  Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
+ *    The PGP code was using unsigned hexadecimal formats. 
+ *    Unfortunately, unsigned formats simply didn't work.
+ *
+ *  Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
+ *    The original code assumed that both snprintf() and vsnprintf() were
+ *    missing.  Some systems only have snprintf() but not vsnprintf(), so
+ *    the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
+ *
+ *  Ben Lindstrom <mouring@eviladmin.org> 09/27/00 for OpenSSH
+ *    Welcome to the world of %lld and %qd support.  With other
+ *    long long support.  This is needed for sftp-server to work
+ *    right.
+ *
+ *  Ben Lindstrom <mouring@eviladmin.org> 02/12/01 for OpenSSH
+ *    Removed all hint of VARARGS stuff and banished it to the void,
+ *    and did a bit of KNF style work to make things a bit more
+ *    acceptable.  Consider stealing from mutt or enlightenment.
+ **************************************************************/
+
+#include "includes.h"
+#include "ctype.h"
+
+RCSID("$Id: bsd-snprintf.c,v 1.3 2004/12/30 01:56:34 admin Exp $");
+
+#if defined(BROKEN_SNPRINTF)           /* For those with broken snprintf() */
+# undef HAVE_SNPRINTF
+# undef HAVE_VSNPRINTF
+#endif
+
+#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
+
+static void 
+dopr(char *buffer, size_t maxlen, const char *format, va_list args);
+
+static void 
+fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, 
+    int min, int max);
+
+static void 
+fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base, 
+    int min, int max, int flags);
+
+static long double 
+pow10(int exp);
+
+static long 
+round(long double value);
+
+static void 
+fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, 
+    int min, int max, int flags);
+
+static void
+dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c);
+
+/*
+ * dopr(): poor man's version of doprintf
+ */
+
+/* format read states */
+#define DP_S_DEFAULT 0
+#define DP_S_FLAGS   1
+#define DP_S_MIN     2
+#define DP_S_DOT     3
+#define DP_S_MAX     4
+#define DP_S_MOD     5
+#define DP_S_CONV    6
+#define DP_S_DONE    7
+
+/* format flags - Bits */
+#define DP_F_MINUS     (1 << 0)
+#define DP_F_PLUS      (1 << 1)
+#define DP_F_SPACE     (1 << 2)
+#define DP_F_NUM       (1 << 3)
+#define DP_F_ZERO      (1 << 4)
+#define DP_F_UP        (1 << 5)
+#define DP_F_UNSIGNED  (1 << 6)
+
+/* Conversion Flags */
+#define DP_C_SHORT     1
+#define DP_C_LONG      2
+#define DP_C_LDOUBLE   3
+#define DP_C_LONG_LONG 4
+
+#define char_to_int(p) (p - '0')
+#define abs_val(p) (p < 0 ? -p : p)
+
+
+static void 
+dopr(char *buffer, size_t maxlen, const char *format, va_list args)
+{
+       char *strvalue, ch;
+       long value;
+       long double fvalue;
+       int min = 0, max = -1, state = DP_S_DEFAULT, flags = 0, cflags = 0;
+       size_t currlen = 0;
+  
+       ch = *format++;
+
+       while (state != DP_S_DONE) {
+               if ((ch == '\0') || (currlen >= maxlen)) 
+                       state = DP_S_DONE;
+
+               switch(state) {
+               case DP_S_DEFAULT:
+                       if (ch == '%') 
+                               state = DP_S_FLAGS;
+                       else 
+                               dopr_outch(buffer, &currlen, maxlen, ch);
+                       ch = *format++;
+                       break;
+               case DP_S_FLAGS:
+                       switch (ch) {
+                       case '-':
+                               flags |= DP_F_MINUS;
+                               ch = *format++;
+                               break;
+                       case '+':
+                               flags |= DP_F_PLUS;
+                               ch = *format++;
+                               break;
+                       case ' ':
+                               flags |= DP_F_SPACE;
+                               ch = *format++;
+                               break;
+                       case '#':
+                               flags |= DP_F_NUM;
+                               ch = *format++;
+                               break;
+                       case '0':
+                               flags |= DP_F_ZERO;
+                               ch = *format++;
+                               break;
+                       default:
+                               state = DP_S_MIN;
+                               break;
+                       }
+                       break;
+               case DP_S_MIN:
+                       if (isdigit((unsigned char)ch)) {
+                               min = 10 * min + char_to_int (ch);
+                               ch = *format++;
+                       } else if (ch == '*') {
+                               min = va_arg (args, int);
+                               ch = *format++;
+                               state = DP_S_DOT;
+                       } else 
+                               state = DP_S_DOT;
+                       break;
+               case DP_S_DOT:
+                       if (ch == '.') {
+                               state = DP_S_MAX;
+                               ch = *format++;
+                       } else 
+                               state = DP_S_MOD;
+                       break;
+               case DP_S_MAX:
+                       if (isdigit((unsigned char)ch)) {
+                               if (max < 0)
+                                       max = 0;
+                               max = 10 * max + char_to_int(ch);
+                               ch = *format++;
+                       } else if (ch == '*') {
+                               max = va_arg (args, int);
+                               ch = *format++;
+                               state = DP_S_MOD;
+                       } else 
+                               state = DP_S_MOD;
+                       break;
+               case DP_S_MOD:
+                       switch (ch) {
+                       case 'h':
+                               cflags = DP_C_SHORT;
+                               ch = *format++;
+                               break;
+                       case 'l':
+                               cflags = DP_C_LONG;
+                               ch = *format++;
+                               if (ch == 'l') {
+                                       cflags = DP_C_LONG_LONG;
+                                       ch = *format++;
+                               }
+                               break;
+                       case 'q':
+                               cflags = DP_C_LONG_LONG;
+                               ch = *format++;
+                               break;
+                       case 'L':
+                               cflags = DP_C_LDOUBLE;
+                               ch = *format++;
+                               break;
+                       default:
+                               break;
+                       }
+                       state = DP_S_CONV;
+                       break;
+               case DP_S_CONV:
+                       switch (ch) {
+                       case 'd':
+                       case 'i':
+                               if (cflags == DP_C_SHORT) 
+                                       value = va_arg(args, int);
+                               else if (cflags == DP_C_LONG)
+                                       value = va_arg(args, long int);
+                               else if (cflags == DP_C_LONG_LONG)
+                                       value = va_arg (args, long long);
+                               else
+                                       value = va_arg (args, int);
+                               fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags);
+                               break;
+                       case 'o':
+                               flags |= DP_F_UNSIGNED;
+                               if (cflags == DP_C_SHORT)
+                                       value = va_arg(args, unsigned int);
+                               else if (cflags == DP_C_LONG)
+                                       value = va_arg(args, unsigned long int);
+                               else if (cflags == DP_C_LONG_LONG)
+                                       value = va_arg(args, unsigned long long);
+                               else
+                                       value = va_arg(args, unsigned int);
+                               fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags);
+                               break;
+                       case 'u':
+                               flags |= DP_F_UNSIGNED;
+                               if (cflags == DP_C_SHORT)
+                                       value = va_arg(args, unsigned int);
+                               else if (cflags == DP_C_LONG)
+                                       value = va_arg(args, unsigned long int);
+                               else if (cflags == DP_C_LONG_LONG)
+                                       value = va_arg(args, unsigned long long);
+                               else
+                                       value = va_arg(args, unsigned int);
+                               fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
+                               break;
+                       case 'X':
+                               flags |= DP_F_UP;
+                       case 'x':
+                               flags |= DP_F_UNSIGNED;
+                               if (cflags == DP_C_SHORT)
+                                       value = va_arg(args, unsigned int);
+                               else if (cflags == DP_C_LONG)
+                                       value = va_arg(args, unsigned long int);
+                               else if (cflags == DP_C_LONG_LONG)
+                                       value = va_arg(args, unsigned long long);
+                               else
+                                       value = va_arg(args, unsigned int);
+                               fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags);
+                               break;
+                       case 'f':
+                               if (cflags == DP_C_LDOUBLE)
+                                       fvalue = va_arg(args, long double);
+                               else
+                                       fvalue = va_arg(args, double);
+                               /* um, floating point? */
+                               fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags);
+                               break;
+                       case 'E':
+                               flags |= DP_F_UP;
+                       case 'e':
+                               if (cflags == DP_C_LDOUBLE)
+                                       fvalue = va_arg(args, long double);
+                               else
+                                       fvalue = va_arg(args, double);
+                               break;
+                       case 'G':
+                               flags |= DP_F_UP;
+                       case 'g':
+                               if (cflags == DP_C_LDOUBLE)
+                                       fvalue = va_arg(args, long double);
+                               else
+                                       fvalue = va_arg(args, double);
+                               break;
+                       case 'c':
+                               dopr_outch(buffer, &currlen, maxlen, va_arg(args, int));
+                               break;
+                       case 's':
+                               strvalue = va_arg(args, char *);
+                               if (max < 0) 
+                                       max = maxlen; /* ie, no max */
+                               fmtstr(buffer, &currlen, maxlen, strvalue, flags, min, max);
+                               break;
+                       case 'p':
+                               strvalue = va_arg(args, void *);
+                               fmtint(buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
+                               break;
+                       case 'n':
+                               if (cflags == DP_C_SHORT) {
+                                       short int *num;
+                                       num = va_arg(args, short int *);
+                                       *num = currlen;
+                               } else if (cflags == DP_C_LONG) {
+                                       long int *num;
+                                       num = va_arg(args, long int *);
+                                       *num = currlen;
+                               } else if (cflags == DP_C_LONG_LONG) {
+                                       long long *num;
+                                       num = va_arg(args, long long *);
+                                       *num = currlen;
+                               } else {
+                                       int *num;
+                                       num = va_arg(args, int *);
+                                       *num = currlen;
+                               }
+                               break;
+                       case '%':
+                               dopr_outch(buffer, &currlen, maxlen, ch);
+                               break;
+                       case 'w': /* not supported yet, treat as next char */
+                               ch = *format++;
+                               break;
+                       default: /* Unknown, skip */
+                       break;
+                       }
+                       ch = *format++;
+                       state = DP_S_DEFAULT;
+                       flags = cflags = min = 0;
+                       max = -1;
+                       break;
+               case DP_S_DONE:
+                       break;
+               default: /* hmm? */
+                       break; /* some picky compilers need this */
+               }
+       }
+       if (currlen < maxlen - 1) 
+               buffer[currlen] = '\0';
+       else 
+               buffer[maxlen - 1] = '\0';
+}
+
+static void
+fmtstr(char *buffer, size_t *currlen, size_t maxlen,
+    char *value, int flags, int min, int max)
+{
+       int cnt = 0, padlen, strln;     /* amount to pad */
+  
+       if (value == 0) 
+               value = "<NULL>";
+
+       for (strln = 0; value[strln]; ++strln); /* strlen */
+       padlen = min - strln;
+       if (padlen < 0) 
+               padlen = 0;
+       if (flags & DP_F_MINUS) 
+               padlen = -padlen; /* Left Justify */
+
+       while ((padlen > 0) && (cnt < max)) {
+               dopr_outch(buffer, currlen, maxlen, ' ');
+               --padlen;
+               ++cnt;
+       }
+       while (*value && (cnt < max)) {
+               dopr_outch(buffer, currlen, maxlen, *value++);
+               ++cnt;
+       }
+       while ((padlen < 0) && (cnt < max)) {
+               dopr_outch(buffer, currlen, maxlen, ' ');
+               ++padlen;
+               ++cnt;
+       }
+}
+
+/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
+
+static void 
+fmtint(char *buffer, size_t *currlen, size_t maxlen,
+    long value, int base, int min, int max, int flags)
+{
+       unsigned long uvalue;
+       char convert[20];
+       int signvalue = 0, place = 0, caps = 0;
+       int spadlen = 0; /* amount to space pad */
+       int zpadlen = 0; /* amount to zero pad */
+  
+       if (max < 0)
+               max = 0;
+
+       uvalue = value;
+
+       if (!(flags & DP_F_UNSIGNED)) {
+               if (value < 0) {
+                       signvalue = '-';
+                       uvalue = -value;
+               } else if (flags & DP_F_PLUS)  /* Do a sign (+/i) */
+                       signvalue = '+';
+               else if (flags & DP_F_SPACE)
+                       signvalue = ' ';
+       }
+  
+       if (flags & DP_F_UP) 
+               caps = 1; /* Should characters be upper case? */
+       do {
+               convert[place++] =
+                   (caps ? "0123456789ABCDEF" : "0123456789abcdef")
+                   [uvalue % (unsigned)base];
+               uvalue = (uvalue / (unsigned)base );
+       } while (uvalue && (place < 20));
+       if (place == 20) 
+               place--;
+       convert[place] = 0;
+
+       zpadlen = max - place;
+       spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);
+       if (zpadlen < 0)
+               zpadlen = 0;
+       if (spadlen < 0)
+               spadlen = 0;
+       if (flags & DP_F_ZERO) {
+               zpadlen = MAX(zpadlen, spadlen);
+               spadlen = 0;
+       }
+       if (flags & DP_F_MINUS) 
+               spadlen = -spadlen; /* Left Justifty */
+
+       /* Spaces */
+       while (spadlen > 0) {
+               dopr_outch(buffer, currlen, maxlen, ' ');
+               --spadlen;
+       }
+
+       /* Sign */
+       if (signvalue) 
+               dopr_outch(buffer, currlen, maxlen, signvalue);
+
+       /* Zeros */
+       if (zpadlen > 0) {
+               while (zpadlen > 0) {
+                       dopr_outch(buffer, currlen, maxlen, '0');
+                       --zpadlen;
+               }
+       }
+
+       /* Digits */
+       while (place > 0) 
+               dopr_outch(buffer, currlen, maxlen, convert[--place]);
+  
+       /* Left Justified spaces */
+       while (spadlen < 0) {
+               dopr_outch (buffer, currlen, maxlen, ' ');
+               ++spadlen;
+       }
+}
+
+static long double 
+pow10(int exp)
+{
+       long double result = 1;
+
+       while (exp) {
+               result *= 10;
+               exp--;
+       }
+  
+       return result;
+}
+
+static long 
+round(long double value)
+{
+       long intpart = value;
+
+       value -= intpart;
+       if (value >= 0.5)
+               intpart++;
+
+       return intpart;
+}
+
+static void 
+fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, 
+      int min, int max, int flags)
+{
+       char iconvert[20], fconvert[20];
+       int signvalue = 0, iplace = 0, fplace = 0;
+       int padlen = 0; /* amount to pad */
+       int zpadlen = 0, caps = 0;
+       long intpart, fracpart;
+       long double ufvalue;
+  
+       /* 
+        * AIX manpage says the default is 0, but Solaris says the default
+        * is 6, and sprintf on AIX defaults to 6
+        */
+       if (max < 0)
+               max = 6;
+
+       ufvalue = abs_val(fvalue);
+
+       if (fvalue < 0)
+               signvalue = '-';
+       else if (flags & DP_F_PLUS)  /* Do a sign (+/i) */
+               signvalue = '+';
+       else if (flags & DP_F_SPACE)
+               signvalue = ' ';
+
+       intpart = ufvalue;
+
+       /* 
+        * Sorry, we only support 9 digits past the decimal because of our 
+        * conversion method
+        */
+       if (max > 9)
+               max = 9;
+
+       /* We "cheat" by converting the fractional part to integer by
+        * multiplying by a factor of 10
+        */
+       fracpart = round((pow10 (max)) * (ufvalue - intpart));
+
+       if (fracpart >= pow10 (max)) {
+               intpart++;
+               fracpart -= pow10 (max);
+       }
+
+       /* Convert integer part */
+       do {
+               iconvert[iplace++] =
+                   (caps ? "0123456789ABCDEF" : "0123456789abcdef")
+                   [intpart % 10];
+               intpart = (intpart / 10);
+       } while(intpart && (iplace < 20));
+       if (iplace == 20) 
+               iplace--;
+       iconvert[iplace] = 0;
+
+       /* Convert fractional part */
+       do {
+               fconvert[fplace++] =
+                   (caps ? "0123456789ABCDEF" : "0123456789abcdef")
+                   [fracpart % 10];
+               fracpart = (fracpart / 10);
+       } while(fracpart && (fplace < 20));
+       if (fplace == 20) 
+               fplace--;
+       fconvert[fplace] = 0;
+
+       /* -1 for decimal point, another -1 if we are printing a sign */
+       padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); 
+       zpadlen = max - fplace;
+       if (zpadlen < 0)
+               zpadlen = 0;
+       if (padlen < 0) 
+               padlen = 0;
+       if (flags & DP_F_MINUS) 
+               padlen = -padlen; /* Left Justifty */
+
+       if ((flags & DP_F_ZERO) && (padlen > 0)) {
+               if (signvalue) {
+                       dopr_outch(buffer, currlen, maxlen, signvalue);
+                       --padlen;
+                       signvalue = 0;
+               }
+               while (padlen > 0) {
+                       dopr_outch(buffer, currlen, maxlen, '0');
+                       --padlen;
+               }
+       }
+       while (padlen > 0) {
+               dopr_outch(buffer, currlen, maxlen, ' ');
+               --padlen;
+       }
+       if (signvalue) 
+               dopr_outch(buffer, currlen, maxlen, signvalue);
+
+       while (iplace > 0) 
+               dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]);
+
+       /*
+        * Decimal point.  This should probably use locale to find the 
+        * correct char to print out.
+        */
+       dopr_outch(buffer, currlen, maxlen, '.');
+
+       while (fplace > 0) 
+               dopr_outch(buffer, currlen, maxlen, fconvert[--fplace]);
+
+       while (zpadlen > 0) {
+               dopr_outch(buffer, currlen, maxlen, '0');
+               --zpadlen;
+       }
+
+       while (padlen < 0) {
+               dopr_outch(buffer, currlen, maxlen, ' ');
+               ++padlen;
+       }
+}
+
+static void 
+dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
+{
+       if (*currlen < maxlen)
+               buffer[(*currlen)++] = c;
+}
+#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */
+
+#ifndef HAVE_VSNPRINTF
+int 
+vsnprintf(char *str, size_t count, const char *fmt, va_list args)
+{
+       str[0] = 0;
+       dopr(str, count, fmt, args);
+
+       return(strlen(str));
+}
+#endif /* !HAVE_VSNPRINTF */
+
+#ifndef HAVE_SNPRINTF
+int 
+snprintf(char *str,size_t count,const char *fmt,...)
+{
+       va_list ap;
+
+       va_start(ap, fmt);
+       (void) vsnprintf(str, count, fmt, ap);
+       va_end(ap);
+
+       return(strlen(str));
+}
+
+#endif /* !HAVE_SNPRINTF */
diff --git a/arm/ssh/ssh.c b/arm/ssh/ssh.c
new file mode 100644 (file)
index 0000000..6d8d538
--- /dev/null
@@ -0,0 +1,18 @@
+#include "ssh.h"
+
+#include "includes.h"
+#include "pace.h"
+
+// 68K function addresses (written by 68K code)
+uintptr_t ssh_bytes_68K = 0;
+
+void ssh_bytes(struct ssh_session_t *ss, uint8_t *buf, uint16_t bufLen)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(ss)
+        PACE_PARAMS_ADD32(buf)
+        PACE_PARAMS_ADD16(bufLen)
+    };
+
+    PACE_EXEC_FN(ssh_bytes_68K, 0);
+}
diff --git a/arm/ssh/ssh.h b/arm/ssh/ssh.h
new file mode 100644 (file)
index 0000000..a1cb6c9
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef SSH_H
+#define SSH_H
+
+#include "includes.h"
+
+struct ssh_session_t;
+
+void ssh_bytes(struct ssh_session_t *ss, uint8_t *buf, uint16_t bufLen);
+
+#endif
diff --git a/arm/ssh/sshzlib.c b/arm/ssh/sshzlib.c
new file mode 100644 (file)
index 0000000..7c72b65
--- /dev/null
@@ -0,0 +1,1291 @@
+/*
+PuTTY is copyright 1997-2004 Simon Tatham.
+
+Portions copyright Robert de Bath, Joris van Rantwijk, Delian
+Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
+Justin Bradford, Ben Harris, and CORE SDI S.A.
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation files
+(the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/**********
+ * Portions Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+
+/*
+ * Zlib (RFC1950 / RFC1951) compression for PuTTY.
+ * 
+ * There will no doubt be criticism of my decision to reimplement
+ * Zlib compression from scratch instead of using the existing zlib
+ * code. People will cry `reinventing the wheel'; they'll claim
+ * that the `fundamental basis of OSS' is code reuse; they'll want
+ * to see a really good reason for me having chosen not to use the
+ * existing code.
+ * 
+ * Well, here are my reasons. Firstly, I don't want to link the
+ * whole of zlib into the PuTTY binary; PuTTY is justifiably proud
+ * of its small size and I think zlib contains a lot of unnecessary
+ * baggage for the kind of compression that SSH requires.
+ * 
+ * Secondly, I also don't like the alternative of using zlib.dll.
+ * Another thing PuTTY is justifiably proud of is its ease of
+ * installation, and the last thing I want to do is to start
+ * mandating DLLs. Not only that, but there are two _kinds_ of
+ * zlib.dll kicking around, one with C calling conventions on the
+ * exported functions and another with WINAPI conventions, and
+ * there would be a significant danger of getting the wrong one.
+ * 
+ * Thirdly, there seems to be a difference of opinion on the IETF
+ * secsh mailing list about the correct way to round off a
+ * compressed packet and start the next. In particular, there's
+ * some talk of switching to a mechanism zlib isn't currently
+ * capable of supporting (see below for an explanation). Given that
+ * sort of uncertainty, I thought it might be better to have code
+ * that will support even the zlib-incompatible worst case.
+ * 
+ * Fourthly, it's a _second implementation_. Second implementations
+ * are fundamentally a Good Thing in standardisation efforts. The
+ * difference of opinion mentioned above has arisen _precisely_
+ * because there has been only one zlib implementation and
+ * everybody has used it. I don't intend that this should happen
+ * again.
+ */
+
+#include "includes.h"
+#include "sshzlib.h"
+#include "tree234.h"
+#include "puttymem.h"
+
+
+/* ----------------------------------------------------------------------
+ * Basic LZ77 code. This bit is designed modularly, so it could be
+ * ripped out and used in a different LZ77 compressor. Go to it,
+ * and good luck :-)
+ */
+
+struct LZ77InternalContext;
+struct LZ77Context {
+    struct LZ77InternalContext *ictx;
+    void *userdata;
+    void (*literal) (struct LZ77Context * ctx, unsigned char c);
+    void (*match) (struct LZ77Context * ctx, int distance, int len);
+};
+
+/*
+ * Initialise the private fields of an LZ77Context. It's up to the
+ * user to initialise the public fields.
+ */
+static int lz77_init(struct LZ77Context *ctx);
+
+/*
+ * Supply data to be compressed. Will update the private fields of
+ * the LZ77Context, and will call literal() and match() to output.
+ * If `compress' is FALSE, it will never emit a match, but will
+ * instead call literal() for everything.
+ */
+static void lz77_compress(struct LZ77Context *ctx,
+                         unsigned char *data, int len, int compress);
+
+/*
+ * Modifiable parameters.
+ * Be sure to change format spec in zlib_compress_block when changing WINSIZE!
+ */
+#define WINSIZE 32768                 /* window size. Must be power of 2! */
+#define HASHMAX 2039                  /* one more than max hash value */
+#define MAXMATCH 32                   /* how many matches we track */
+#define HASHCHARS 3                   /* how many chars make a hash */
+
+/*
+ * This compressor takes a less slapdash approach than the
+ * gzip/zlib one. Rather than allowing our hash chains to fall into
+ * disuse near the far end, we keep them doubly linked so we can
+ * _find_ the far end, and then every time we add a new byte to the
+ * window (thus rolling round by one and removing the previous
+ * byte), we can carefully remove the hash chain entry.
+ */
+
+#define INVALID -1                    /* invalid hash _and_ invalid offset */
+struct WindowEntry {
+    short next, prev;                 /* array indices within the window */
+    short hashval;
+};
+
+struct HashEntry {
+    short first;                      /* window index of first in chain */
+};
+
+struct Match {
+    int distance, len;
+};
+
+struct LZ77InternalContext {
+    int winpos;
+    int npending;
+    struct HashEntry hashtab[HASHMAX];
+    struct WindowEntry win[WINSIZE];
+    unsigned char data[WINSIZE];
+    unsigned char pending[HASHCHARS];
+};
+
+static int lz77_hash(unsigned char *data)
+{
+    return (257 * data[0] + 263 * data[1] + 269 * data[2]) % HASHMAX;
+}
+
+static int lz77_init(struct LZ77Context *ctx)
+{
+    struct LZ77InternalContext *st;
+    int i;
+
+    st = snew(struct LZ77InternalContext);
+    if (!st)
+       return 0;
+
+    ctx->ictx = st;
+
+    for (i = 0; i < WINSIZE; i++)
+       st->win[i].next = st->win[i].prev = st->win[i].hashval = INVALID;
+    for (i = 0; i < HASHMAX; i++)
+       st->hashtab[i].first = INVALID;
+    st->winpos = 0;
+
+    st->npending = 0;
+
+    return 1;
+}
+
+static void lz77_advance(struct LZ77InternalContext *st,
+                        unsigned char c, int hash)
+{
+    int off;
+
+    /*
+     * Remove the hash entry at winpos from the tail of its chain,
+     * or empty the chain if it's the only thing on the chain.
+     */
+    if (st->win[st->winpos].prev != INVALID) {
+       st->win[st->win[st->winpos].prev].next = INVALID;
+    } else if (st->win[st->winpos].hashval != INVALID) {
+       st->hashtab[st->win[st->winpos].hashval].first = INVALID;
+    }
+
+    /*
+     * Create a new entry at winpos and add it to the head of its
+     * hash chain.
+     */
+    st->win[st->winpos].hashval = hash;
+    st->win[st->winpos].prev = INVALID;
+    off = st->win[st->winpos].next = st->hashtab[hash].first;
+    st->hashtab[hash].first = st->winpos;
+    if (off != INVALID)
+       st->win[off].prev = st->winpos;
+    st->data[st->winpos] = c;
+
+    /*
+     * Advance the window pointer.
+     */
+    st->winpos = (st->winpos + 1) & (WINSIZE - 1);
+}
+
+#define CHARAT(k) ( (k)<0 ? st->data[(st->winpos+k)&(WINSIZE-1)] : data[k] )
+
+static void lz77_compress(struct LZ77Context *ctx,
+                         unsigned char *data, int len, int compress)
+{
+    struct LZ77InternalContext *st = ctx->ictx;
+    int i, hash, distance, off, nmatch, matchlen, advance;
+    struct Match defermatch, matches[MAXMATCH];
+    int deferchr;
+
+    /*
+     * Add any pending characters from last time to the window. (We
+     * might not be able to.)
+     */
+    for (i = 0; i < st->npending; i++) {
+       unsigned char foo[HASHCHARS];
+       int j;
+       if (len + st->npending - i < HASHCHARS) {
+           /* Update the pending array. */
+           for (j = i; j < st->npending; j++)
+               st->pending[j - i] = st->pending[j];
+           break;
+       }
+       for (j = 0; j < HASHCHARS; j++)
+           foo[j] = (i + j < st->npending ? st->pending[i + j] :
+                     data[i + j - st->npending]);
+       lz77_advance(st, foo[0], lz77_hash(foo));
+    }
+    st->npending -= i;
+
+    defermatch.len = 0;
+    deferchr = '\0';
+    while (len > 0) {
+
+       /* Don't even look for a match, if we're not compressing. */
+       if (compress && len >= HASHCHARS) {
+           /*
+            * Hash the next few characters.
+            */
+           hash = lz77_hash(data);
+
+           /*
+            * Look the hash up in the corresponding hash chain and see
+            * what we can find.
+            */
+           nmatch = 0;
+           for (off = st->hashtab[hash].first;
+                off != INVALID; off = st->win[off].next) {
+               /* distance = 1       if off == st->winpos-1 */
+               /* distance = WINSIZE if off == st->winpos   */
+               distance =
+                   WINSIZE - (off + WINSIZE - st->winpos) % WINSIZE;
+               for (i = 0; i < HASHCHARS; i++)
+                   if (CHARAT(i) != CHARAT(i - distance))
+                       break;
+               if (i == HASHCHARS) {
+                   matches[nmatch].distance = distance;
+                   matches[nmatch].len = 3;
+                   if (++nmatch >= MAXMATCH)
+                       break;
+               }
+           }
+       } else {
+           nmatch = 0;
+           hash = INVALID;
+       }
+
+       if (nmatch > 0) {
+           /*
+            * We've now filled up matches[] with nmatch potential
+            * matches. Follow them down to find the longest. (We
+            * assume here that it's always worth favouring a
+            * longer match over a shorter one.)
+            */
+           matchlen = HASHCHARS;
+           while (matchlen < len) {
+               int j;
+               for (i = j = 0; i < nmatch; i++) {
+                   if (CHARAT(matchlen) ==
+                       CHARAT(matchlen - matches[i].distance)) {
+                       matches[j++] = matches[i];
+                   }
+               }
+               if (j == 0)
+                   break;
+               matchlen++;
+               nmatch = j;
+           }
+
+           /*
+            * We've now got all the longest matches. We favour the
+            * shorter distances, which means we go with matches[0].
+            * So see if we want to defer it or throw it away.
+            */
+           matches[0].len = matchlen;
+           if (defermatch.len > 0) {
+               if (matches[0].len > defermatch.len + 1) {
+                   /* We have a better match. Emit the deferred char,
+                    * and defer this match. */
+                   ctx->literal(ctx, (unsigned char) deferchr);
+                   defermatch = matches[0];
+                   deferchr = data[0];
+                   advance = 1;
+               } else {
+                   /* We don't have a better match. Do the deferred one. */
+                   ctx->match(ctx, defermatch.distance, defermatch.len);
+                   advance = defermatch.len - 1;
+                   defermatch.len = 0;
+               }
+           } else {
+               /* There was no deferred match. Defer this one. */
+               defermatch = matches[0];
+               deferchr = data[0];
+               advance = 1;
+           }
+       } else {
+           /*
+            * We found no matches. Emit the deferred match, if
+            * any; otherwise emit a literal.
+            */
+           if (defermatch.len > 0) {
+               ctx->match(ctx, defermatch.distance, defermatch.len);
+               advance = defermatch.len - 1;
+               defermatch.len = 0;
+           } else {
+               ctx->literal(ctx, data[0]);
+               advance = 1;
+           }
+       }
+
+       /*
+        * Now advance the position by `advance' characters,
+        * keeping the window and hash chains consistent.
+        */
+       while (advance > 0) {
+           if (len >= HASHCHARS) {
+               lz77_advance(st, *data, lz77_hash(data));
+           } else {
+               st->pending[st->npending++] = *data;
+           }
+           data++;
+           len--;
+           advance--;
+       }
+    }
+}
+
+/* ----------------------------------------------------------------------
+ * Zlib compression. We always use the static Huffman tree option.
+ * Mostly this is because it's hard to scan a block in advance to
+ * work out better trees; dynamic trees are great when you're
+ * compressing a large file under no significant time constraint,
+ * but when you're compressing little bits in real time, things get
+ * hairier.
+ * 
+ * I suppose it's possible that I could compute Huffman trees based
+ * on the frequencies in the _previous_ block, as a sort of
+ * heuristic, but I'm not confident that the gain would balance out
+ * having to transmit the trees.
+ */
+
+struct Outbuf {
+    unsigned char *outbuf;
+    int outlen, outsize;
+    unsigned long outbits;
+    int noutbits;
+    int firstblock;
+    int comp_disabled;
+};
+
+static void outbits(struct Outbuf *out, unsigned long bits, int nbits)
+{
+    assert(out->noutbits + nbits <= 32);
+    out->outbits |= bits << out->noutbits;
+    out->noutbits += nbits;
+    while (out->noutbits >= 8) {
+       if (out->outlen >= out->outsize) {
+           out->outsize = out->outlen + 64;
+           out->outbuf = sresize(out->outbuf, out->outsize, unsigned char);
+       }
+       out->outbuf[out->outlen++] = (unsigned char) (out->outbits & 0xFF);
+       out->outbits >>= 8;
+       out->noutbits -= 8;
+    }
+}
+
+static const unsigned char mirrorbytes[256] = {
+    0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+    0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+    0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+    0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+    0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+    0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+    0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+    0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+    0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+    0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+    0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+    0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+    0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+    0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+    0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+    0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+    0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+    0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+    0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+    0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+    0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+    0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+    0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+    0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+    0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+    0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+    0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+    0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+    0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+    0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+    0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+    0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
+};
+
+typedef struct {
+    short code, extrabits;
+    int min, max;
+} coderecord;
+
+static const coderecord lencodes[] = {
+    {257, 0, 3, 3},
+    {258, 0, 4, 4},
+    {259, 0, 5, 5},
+    {260, 0, 6, 6},
+    {261, 0, 7, 7},
+    {262, 0, 8, 8},
+    {263, 0, 9, 9},
+    {264, 0, 10, 10},
+    {265, 1, 11, 12},
+    {266, 1, 13, 14},
+    {267, 1, 15, 16},
+    {268, 1, 17, 18},
+    {269, 2, 19, 22},
+    {270, 2, 23, 26},
+    {271, 2, 27, 30},
+    {272, 2, 31, 34},
+    {273, 3, 35, 42},
+    {274, 3, 43, 50},
+    {275, 3, 51, 58},
+    {276, 3, 59, 66},
+    {277, 4, 67, 82},
+    {278, 4, 83, 98},
+    {279, 4, 99, 114},
+    {280, 4, 115, 130},
+    {281, 5, 131, 162},
+    {282, 5, 163, 194},
+    {283, 5, 195, 226},
+    {284, 5, 227, 257},
+    {285, 0, 258, 258},
+};
+
+static const coderecord distcodes[] = {
+    {0, 0, 1, 1},
+    {1, 0, 2, 2},
+    {2, 0, 3, 3},
+    {3, 0, 4, 4},
+    {4, 1, 5, 6},
+    {5, 1, 7, 8},
+    {6, 2, 9, 12},
+    {7, 2, 13, 16},
+    {8, 3, 17, 24},
+    {9, 3, 25, 32},
+    {10, 4, 33, 48},
+    {11, 4, 49, 64},
+    {12, 5, 65, 96},
+    {13, 5, 97, 128},
+    {14, 6, 129, 192},
+    {15, 6, 193, 256},
+    {16, 7, 257, 384},
+    {17, 7, 385, 512},
+    {18, 8, 513, 768},
+    {19, 8, 769, 1024},
+    {20, 9, 1025, 1536},
+    {21, 9, 1537, 2048},
+    {22, 10, 2049, 3072},
+    {23, 10, 3073, 4096},
+    {24, 11, 4097, 6144},
+    {25, 11, 6145, 8192},
+    {26, 12, 8193, 12288},
+    {27, 12, 12289, 16384},
+    {28, 13, 16385, 24576},
+    {29, 13, 24577, 32768},
+};
+
+static void zlib_literal(struct LZ77Context *ectx, unsigned char c)
+{
+    struct Outbuf *out = (struct Outbuf *) ectx->userdata;
+
+    if (out->comp_disabled) {
+       /*
+        * We're in an uncompressed block, so just output the byte.
+        */
+       outbits(out, c, 8);
+       return;
+    }
+
+    if (c <= 143) {
+       /* 0 through 143 are 8 bits long starting at 00110000. */
+       outbits(out, mirrorbytes[0x30 + c], 8);
+    } else {
+       /* 144 through 255 are 9 bits long starting at 110010000. */
+       outbits(out, 1 + 2 * mirrorbytes[0x90 - 144 + c], 9);
+    }
+}
+
+static void zlib_match(struct LZ77Context *ectx, int distance, int len)
+{
+    const coderecord *d, *l;
+    int i, j, k;
+    struct Outbuf *out = (struct Outbuf *) ectx->userdata;
+
+    assert(!out->comp_disabled);
+
+    while (len > 0) {
+       int thislen;
+
+       /*
+        * We can transmit matches of lengths 3 through 258
+        * inclusive. So if len exceeds 258, we must transmit in
+        * several steps, with 258 or less in each step.
+        * 
+        * Specifically: if len >= 261, we can transmit 258 and be
+        * sure of having at least 3 left for the next step. And if
+        * len <= 258, we can just transmit len. But if len == 259
+        * or 260, we must transmit len-3.
+        */
+       thislen = (len > 260 ? 258 : len <= 258 ? len : len - 3);
+       len -= thislen;
+
+       /*
+        * Binary-search to find which length code we're
+        * transmitting.
+        */
+       i = -1;
+       j = sizeof(lencodes) / sizeof(*lencodes);
+       while (1) {
+           assert(j - i >= 2);
+           k = (j + i) / 2;
+           if (thislen < lencodes[k].min)
+               j = k;
+           else if (thislen > lencodes[k].max)
+               i = k;
+           else {
+               l = &lencodes[k];
+               break;                 /* found it! */
+           }
+       }
+
+       /*
+        * Transmit the length code. 256-279 are seven bits
+        * starting at 0000000; 280-287 are eight bits starting at
+        * 11000000.
+        */
+       if (l->code <= 279) {
+           outbits(out, mirrorbytes[(l->code - 256) * 2], 7);
+       } else {
+           outbits(out, mirrorbytes[0xc0 - 280 + l->code], 8);
+       }
+
+       /*
+        * Transmit the extra bits.
+        */
+       if (l->extrabits)
+           outbits(out, thislen - l->min, l->extrabits);
+
+       /*
+        * Binary-search to find which distance code we're
+        * transmitting.
+        */
+       i = -1;
+       j = sizeof(distcodes) / sizeof(*distcodes);
+       while (1) {
+           assert(j - i >= 2);
+           k = (j + i) / 2;
+           if (distance < distcodes[k].min)
+               j = k;
+           else if (distance > distcodes[k].max)
+               i = k;
+           else {
+               d = &distcodes[k];
+               break;                 /* found it! */
+           }
+       }
+
+       /*
+        * Transmit the distance code. Five bits starting at 00000.
+        */
+       outbits(out, mirrorbytes[d->code * 8], 5);
+
+       /*
+        * Transmit the extra bits.
+        */
+       if (d->extrabits)
+           outbits(out, distance - d->min, d->extrabits);
+    }
+}
+
+void *zlib_compress_init(void)
+{
+    struct Outbuf *out;
+    struct LZ77Context *ectx = snew(struct LZ77Context);
+
+    lz77_init(ectx);
+    ectx->literal = zlib_literal;
+    ectx->match = zlib_match;
+
+    out = snew(struct Outbuf);
+    out->outbits = out->noutbits = 0;
+    out->firstblock = 1;
+    out->comp_disabled = FALSE;
+    ectx->userdata = out;
+
+    return ectx;
+}
+
+void zlib_compress_cleanup(void *handle)
+{
+    struct LZ77Context *ectx = (struct LZ77Context *)handle;
+    sfree(ectx->userdata);
+    sfree(ectx->ictx);
+    sfree(ectx);
+}
+
+/*
+ * Turn off actual LZ77 analysis for one block, to facilitate
+ * construction of a precise-length IGNORE packet. Returns the
+ * length adjustment (which is only valid for packets < 65536
+ * bytes, but that seems reasonable enough).
+ */
+static int zlib_disable_compression(void *handle)
+{
+    struct LZ77Context *ectx = (struct LZ77Context *)handle;
+    struct Outbuf *out = (struct Outbuf *) ectx->userdata;
+    int n;
+
+    out->comp_disabled = TRUE;
+
+    n = 0;
+    /*
+     * If this is the first block, we will start by outputting two
+     * header bytes, and then three bits to begin an uncompressed
+     * block. This will cost three bytes (because we will start on
+     * a byte boundary, this is certain).
+     */
+    if (out->firstblock) {
+       n = 3;
+    } else {
+       /*
+        * Otherwise, we will output seven bits to close the
+        * previous static block, and _then_ three bits to begin an
+        * uncompressed block, and then flush the current byte.
+        * This may cost two bytes or three, depending on noutbits.
+        */
+       n += (out->noutbits + 10) / 8;
+    }
+
+    /*
+     * Now we output four bytes for the length / ~length pair in
+     * the uncompressed block.
+     */
+    n += 4;
+
+    return n;
+}
+
+int zlib_compress_block(void *handle, unsigned char *block, size_t len,
+                       unsigned char **outblock, size_t *outlen)
+{
+    struct LZ77Context *ectx = (struct LZ77Context *)handle;
+    struct Outbuf *out = (struct Outbuf *) ectx->userdata;
+    int in_block;
+
+    out->outbuf = NULL;
+    out->outlen = out->outsize = 0;
+
+    /*
+     * If this is the first block, output the Zlib (RFC1950) header
+     * bytes 78 9C. (Deflate compression, 32K window size, default
+     * algorithm.)
+     * GrP 48 9C for 4K window size
+     */
+    if (out->firstblock) {
+       outbits(out, 0x9C78, 16);
+       out->firstblock = 0;
+
+       in_block = FALSE;
+    } else
+       in_block = TRUE;
+
+    if (out->comp_disabled) {
+       if (in_block)
+           outbits(out, 0, 7);        /* close static block */
+
+       while (len > 0) {
+           size_t blen = (len < 65535 ? len : 65535);
+
+           /*
+            * Start a Deflate (RFC1951) uncompressed block. We
+            * transmit a zero bit (BFINAL=0), followed by a zero
+            * bit and a one bit (BTYPE=00). Of course these are in
+            * the wrong order (00 0).
+            */
+           outbits(out, 0, 3);
+
+           /*
+            * Output zero bits to align to a byte boundary.
+            */
+           if (out->noutbits)
+               outbits(out, 0, 8 - out->noutbits);
+
+           /*
+            * Output the block length, and then its one's
+            * complement. They're little-endian, so all we need to
+            * do is pass them straight to outbits() with bit count
+            * 16.
+            */
+           outbits(out, blen, 16);
+           outbits(out, blen ^ 0xFFFF, 16);
+
+           /*
+            * Do the `compression': we need to pass the data to
+            * lz77_compress so that it will be taken into account
+            * for subsequent (distance,length) pairs. But
+            * lz77_compress is passed FALSE, which means it won't
+            * actually find (or even look for) any matches; so
+            * every character will be passed straight to
+            * zlib_literal which will spot out->comp_disabled and
+            * emit in the uncompressed format.
+            */
+           lz77_compress(ectx, block, blen, FALSE);
+
+           len -= blen;
+           block += blen;
+       }
+       outbits(out, 2, 3);            /* open new block */
+    } else {
+       if (!in_block) {
+           /*
+            * Start a Deflate (RFC1951) fixed-trees block. We
+            * transmit a zero bit (BFINAL=0), followed by a zero
+            * bit and a one bit (BTYPE=01). Of course these are in
+            * the wrong order (01 0).
+            */
+           outbits(out, 2, 3);
+       }
+
+       /*
+        * Do the compression.
+        */
+       lz77_compress(ectx, block, len, TRUE);
+
+       /*
+        * End the block (by transmitting code 256, which is
+        * 0000000 in fixed-tree mode), and transmit some empty
+        * blocks to ensure we have emitted the byte containing the
+        * last piece of genuine data. There are three ways we can
+        * do this:
+        *
+        *  - Minimal flush. Output end-of-block and then open a
+        *    new static block. This takes 9 bits, which is
+        *    guaranteed to flush out the last genuine code in the
+        *    closed block; but allegedly zlib can't handle it.
+        *
+        *  - Zlib partial flush. Output EOB, open and close an
+        *    empty static block, and _then_ open the new block.
+        *    This is the best zlib can handle.
+        *
+        *  - Zlib sync flush. Output EOB, then an empty
+        *    _uncompressed_ block (000, then sync to byte
+        *    boundary, then send bytes 00 00 FF FF). Then open the
+        *    new block.
+        *
+        * For the moment, we will use Zlib partial flush.
+        */
+       outbits(out, 0, 7);            /* close block */
+       outbits(out, 2, 3 + 7);        /* empty static block */
+       outbits(out, 2, 3);            /* open new block */
+    }
+
+    out->comp_disabled = FALSE;
+
+    *outblock = out->outbuf;
+    *outlen = out->outlen;
+
+    return 1;
+}
+
+/* ----------------------------------------------------------------------
+ * Zlib decompression. Of course, even though our compressor always
+ * uses static trees, our _decompressor_ has to be capable of
+ * handling dynamic trees if it sees them.
+ */
+
+/*
+ * The way we work the Huffman decode is to have a table lookup on
+ * the first N bits of the input stream (in the order they arrive,
+ * of course, i.e. the first bit of the Huffman code is in bit 0).
+ * Each table entry lists the number of bits to consume, plus
+ * either an output code or a pointer to a secondary table.
+ */
+struct zlib_table;
+struct zlib_tableentry;
+
+struct zlib_tableentry {
+    struct zlib_table *nexttable;
+    short code;
+    unsigned char nbits;
+};
+
+struct zlib_table {
+    int mask;                         /* mask applied to input bit stream */
+    struct zlib_tableentry *table;
+};
+
+#define MAXCODELEN 16
+#define MAXSYMS 288
+
+/*
+ * Build a single-level decode table for elements
+ * [minlength,maxlength) of the provided code/length tables, and
+ * recurse to build subtables.
+ */
+static struct zlib_table *zlib_mkonetab(int *codes, unsigned char *lengths,
+                                       int nsyms,
+                                       int pfx, int pfxbits, int bits)
+{
+    struct zlib_table *tab = snew(struct zlib_table);
+    int pfxmask = (1 << pfxbits) - 1;
+    int nbits, i, j, code;
+
+    tab->table = snewn(1 << bits, struct zlib_tableentry);
+    tab->mask = (1 << bits) - 1;
+
+    for (code = 0; code <= tab->mask; code++) {
+       tab->table[code].code = -1;
+       tab->table[code].nbits = 0;
+       tab->table[code].nexttable = NULL;
+    }
+
+    for (i = 0; i < nsyms; i++) {
+       if (lengths[i] <= pfxbits || (codes[i] & pfxmask) != pfx)
+           continue;
+       code = (codes[i] >> pfxbits) & tab->mask;
+       for (j = code; j <= tab->mask; j += 1 << (lengths[i] - pfxbits)) {
+           tab->table[j].code = i;
+           nbits = lengths[i] - pfxbits;
+           if (tab->table[j].nbits < nbits)
+               tab->table[j].nbits = nbits;
+       }
+    }
+    for (code = 0; code <= tab->mask; code++) {
+       if (tab->table[code].nbits <= bits)
+           continue;
+       /* Generate a subtable. */
+       tab->table[code].code = -1;
+       nbits = tab->table[code].nbits - bits;
+       if (nbits > 7)
+           nbits = 7;
+       tab->table[code].nbits = bits;
+       tab->table[code].nexttable = zlib_mkonetab(codes, lengths, nsyms,
+                                                  pfx | (code << pfxbits),
+                                                  pfxbits + bits, nbits);
+    }
+
+    return tab;
+}
+
+/*
+ * Build a decode table, given a set of Huffman tree lengths.
+ */
+static struct zlib_table *zlib_mktable(unsigned char *lengths,
+                                      int nlengths)
+{
+    int count[MAXCODELEN], startcode[MAXCODELEN], codes[MAXSYMS];
+    int code, maxlen;
+    int i, j;
+
+    /* Count the codes of each length. */
+    maxlen = 0;
+    for (i = 1; i < MAXCODELEN; i++)
+       count[i] = 0;
+    for (i = 0; i < nlengths; i++) {
+       count[lengths[i]]++;
+       if (maxlen < lengths[i])
+           maxlen = lengths[i];
+    }
+    /* Determine the starting code for each length block. */
+    code = 0;
+    for (i = 1; i < MAXCODELEN; i++) {
+       startcode[i] = code;
+       code += count[i];
+       code <<= 1;
+    }
+    /* Determine the code for each symbol. Mirrored, of course. */
+    for (i = 0; i < nlengths; i++) {
+       code = startcode[lengths[i]]++;
+       codes[i] = 0;
+       for (j = 0; j < lengths[i]; j++) {
+           codes[i] = (codes[i] << 1) | (code & 1);
+           code >>= 1;
+       }
+    }
+
+    /*
+     * Now we have the complete list of Huffman codes. Build a
+     * table.
+     */
+    return zlib_mkonetab(codes, lengths, nlengths, 0, 0,
+                        maxlen < 9 ? maxlen : 9);
+}
+
+static int zlib_freetable(struct zlib_table **ztab)
+{
+    struct zlib_table *tab;
+    int code;
+
+    if (ztab == NULL)
+       return -1;
+
+    if (*ztab == NULL)
+       return 0;
+
+    tab = *ztab;
+
+    for (code = 0; code <= tab->mask; code++)
+       if (tab->table[code].nexttable != NULL)
+           zlib_freetable(&tab->table[code].nexttable);
+
+    sfree(tab->table);
+    tab->table = NULL;
+
+    sfree(tab);
+    *ztab = NULL;
+
+    return (0);
+}
+
+struct zlib_decompress_ctx {
+    struct zlib_table *staticlentable, *staticdisttable;
+    struct zlib_table *currlentable, *currdisttable, *lenlentable;
+    enum {
+       START, OUTSIDEBLK,
+       TREES_HDR, TREES_LENLEN, TREES_LEN, TREES_LENREP,
+       INBLK, GOTLENSYM, GOTLEN, GOTDISTSYM,
+       UNCOMP_LEN, UNCOMP_NLEN, UNCOMP_DATA
+    } state;
+    int sym, hlit, hdist, hclen, lenptr, lenextrabits, lenaddon, len,
+       lenrep;
+    int uncomplen;
+    unsigned long bits;
+    int nbits;
+    int winpos;
+    unsigned char *outblk;
+    int outlen, outsize;
+    unsigned char window[WINSIZE];
+    unsigned char lenlen[19];
+    unsigned char lengths[286 + 32];
+};
+
+void *zlib_decompress_init(void)
+{
+    struct zlib_decompress_ctx *dctx = snew(struct zlib_decompress_ctx);
+    unsigned char lengths[288];
+
+    memset(lengths, 8, 144);
+    memset(lengths + 144, 9, 256 - 144);
+    memset(lengths + 256, 7, 280 - 256);
+    memset(lengths + 280, 8, 288 - 280);
+    dctx->staticlentable = zlib_mktable(lengths, 288);
+    memset(lengths, 5, 32);
+    dctx->staticdisttable = zlib_mktable(lengths, 32);
+    dctx->state = START;                      /* even before header */
+    dctx->currlentable = dctx->currdisttable = dctx->lenlentable = NULL;
+    dctx->bits = 0;
+    dctx->nbits = 0;
+    dctx->winpos = 0;
+
+    return dctx;
+}
+
+void zlib_decompress_cleanup(void *handle)
+{
+    struct zlib_decompress_ctx *dctx = (struct zlib_decompress_ctx *)handle;
+
+    if (dctx->currlentable && dctx->currlentable != dctx->staticlentable)
+       zlib_freetable(&dctx->currlentable);
+    if (dctx->currdisttable && dctx->currdisttable != dctx->staticdisttable)
+       zlib_freetable(&dctx->currdisttable);
+    if (dctx->lenlentable)
+       zlib_freetable(&dctx->lenlentable);
+    zlib_freetable(&dctx->staticlentable);
+    zlib_freetable(&dctx->staticdisttable);
+    sfree(dctx);
+}
+
+static int zlib_huflookup(unsigned long *bitsp, int *nbitsp,
+                  struct zlib_table *tab)
+{
+    unsigned long bits = *bitsp;
+    int nbits = *nbitsp;
+    while (1) {
+       struct zlib_tableentry *ent;
+       ent = &tab->table[bits & tab->mask];
+       if (ent->nbits > nbits)
+           return -1;                 /* not enough data */
+       bits >>= ent->nbits;
+       nbits -= ent->nbits;
+       if (ent->code == -1)
+           tab = ent->nexttable;
+       else {
+           *bitsp = bits;
+           *nbitsp = nbits;
+           return ent->code;
+       }
+
+       if (!tab) {
+           /*
+            * There was a missing entry in the table, presumably
+            * due to an invalid Huffman table description, and the
+            * subsequent data has attempted to use the missing
+            * entry. Return a decoding failure.
+            */
+           return -2;
+       }
+    }
+}
+
+static void zlib_emit_char(struct zlib_decompress_ctx *dctx, int c)
+{
+    dctx->window[dctx->winpos] = c;
+    dctx->winpos = (dctx->winpos + 1) & (WINSIZE - 1);
+    if (dctx->outlen >= dctx->outsize) {
+       dctx->outsize = dctx->outlen + 512;
+       dctx->outblk = sresize(dctx->outblk, dctx->outsize, unsigned char);
+    }
+    dctx->outblk[dctx->outlen++] = c;
+}
+
+#define EATBITS(n) ( dctx->nbits -= (n), dctx->bits >>= (n) )
+
+int zlib_decompress_block(void *handle, unsigned char *block, size_t len,
+                         unsigned char **outblock, size_t *outlen)
+{
+    struct zlib_decompress_ctx *dctx = (struct zlib_decompress_ctx *)handle;
+    const coderecord *rec;
+    int code, blktype, rep, dist, nlen;
+    static const unsigned char lenlenmap[] = {
+       16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
+    };
+
+    dctx->outblk = NULL;
+    dctx->outsize = dctx->outlen = 0;
+    while (len > 0 || dctx->nbits > 0) {
+       while (dctx->nbits < 24 && len > 0) {
+           dctx->bits |= (*block++) << dctx->nbits;
+           dctx->nbits += 8;
+           len--;
+       }
+       switch (dctx->state) {
+         case START:
+           /* Expect 16-bit zlib header, which we'll dishonourably ignore. */
+           if (dctx->nbits < 16)
+               goto finished;         /* done all we can */
+           EATBITS(16);
+           dctx->state = OUTSIDEBLK;
+           break;
+         case OUTSIDEBLK:
+           /* Expect 3-bit block header. */
+           if (dctx->nbits < 3)
+               goto finished;         /* done all we can */
+           EATBITS(1);
+           blktype = dctx->bits & 3;
+           EATBITS(2);
+           if (blktype == 0) {
+               int to_eat = dctx->nbits & 7;
+               dctx->state = UNCOMP_LEN;
+               EATBITS(to_eat);       /* align to byte boundary */
+           } else if (blktype == 1) {
+               dctx->currlentable = dctx->staticlentable;
+               dctx->currdisttable = dctx->staticdisttable;
+               dctx->state = INBLK;
+           } else if (blktype == 2) {
+               dctx->state = TREES_HDR;
+           }
+           break;
+         case TREES_HDR:
+           /*
+            * Dynamic block header. Five bits of HLIT, five of
+            * HDIST, four of HCLEN.
+            */
+           if (dctx->nbits < 5 + 5 + 4)
+               goto finished;         /* done all we can */
+           dctx->hlit = 257 + (dctx->bits & 31);
+           EATBITS(5);
+           dctx->hdist = 1 + (dctx->bits & 31);
+           EATBITS(5);
+           dctx->hclen = 4 + (dctx->bits & 15);
+           EATBITS(4);
+           dctx->lenptr = 0;
+           dctx->state = TREES_LENLEN;
+           memset(dctx->lenlen, 0, sizeof(dctx->lenlen));
+           break;
+         case TREES_LENLEN:
+           if (dctx->nbits < 3)
+               goto finished;
+           while (dctx->lenptr < dctx->hclen && dctx->nbits >= 3) {
+               dctx->lenlen[lenlenmap[dctx->lenptr++]] =
+                   (unsigned char) (dctx->bits & 7);
+               EATBITS(3);
+           }
+           if (dctx->lenptr == dctx->hclen) {
+               dctx->lenlentable = zlib_mktable(dctx->lenlen, 19);
+               dctx->state = TREES_LEN;
+               dctx->lenptr = 0;
+           }
+           break;
+         case TREES_LEN:
+           if (dctx->lenptr >= dctx->hlit + dctx->hdist) {
+               dctx->currlentable = zlib_mktable(dctx->lengths, dctx->hlit);
+               dctx->currdisttable = zlib_mktable(dctx->lengths + dctx->hlit,
+                                                 dctx->hdist);
+               zlib_freetable(&dctx->lenlentable);
+               dctx->lenlentable = NULL;
+               dctx->state = INBLK;
+               break;
+           }
+           code =
+               zlib_huflookup(&dctx->bits, &dctx->nbits, dctx->lenlentable);
+           if (code == -1)
+               goto finished;
+           if (code == -2)
+               goto decode_error;
+           if (code < 16)
+               dctx->lengths[dctx->lenptr++] = code;
+           else {
+               dctx->lenextrabits = (code == 16 ? 2 : code == 17 ? 3 : 7);
+               dctx->lenaddon = (code == 18 ? 11 : 3);
+               dctx->lenrep = (code == 16 && dctx->lenptr > 0 ?
+                              dctx->lengths[dctx->lenptr - 1] : 0);
+               dctx->state = TREES_LENREP;
+           }
+           break;
+         case TREES_LENREP:
+           if (dctx->nbits < dctx->lenextrabits)
+               goto finished;
+           rep =
+               dctx->lenaddon +
+               (dctx->bits & ((1 << dctx->lenextrabits) - 1));
+           EATBITS(dctx->lenextrabits);
+           while (rep > 0 && dctx->lenptr < dctx->hlit + dctx->hdist) {
+               dctx->lengths[dctx->lenptr] = dctx->lenrep;
+               dctx->lenptr++;
+               rep--;
+           }
+           dctx->state = TREES_LEN;
+           break;
+         case INBLK:
+           code =
+               zlib_huflookup(&dctx->bits, &dctx->nbits, dctx->currlentable);
+           if (code == -1)
+               goto finished;
+           if (code == -2)
+               goto decode_error;
+           if (code < 256)
+               zlib_emit_char(dctx, code);
+           else if (code == 256) {
+               dctx->state = OUTSIDEBLK;
+               if (dctx->currlentable != dctx->staticlentable) {
+                   zlib_freetable(&dctx->currlentable);
+                   dctx->currlentable = NULL;
+               }
+               if (dctx->currdisttable != dctx->staticdisttable) {
+                   zlib_freetable(&dctx->currdisttable);
+                   dctx->currdisttable = NULL;
+               }
+           } else if (code < 286) {   /* static tree can give >285; ignore */
+               dctx->state = GOTLENSYM;
+               dctx->sym = code;
+           }
+           break;
+         case GOTLENSYM:
+           rec = &lencodes[dctx->sym - 257];
+           if (dctx->nbits < rec->extrabits)
+               goto finished;
+           dctx->len =
+               rec->min + (dctx->bits & ((1 << rec->extrabits) - 1));
+           EATBITS(rec->extrabits);
+           dctx->state = GOTLEN;
+           break;
+         case GOTLEN:
+           code =
+               zlib_huflookup(&dctx->bits, &dctx->nbits,
+                              dctx->currdisttable);
+           if (code == -1)
+               goto finished;
+           if (code == -2)
+               goto decode_error;
+           dctx->state = GOTDISTSYM;
+           dctx->sym = code;
+           break;
+         case GOTDISTSYM:
+           rec = &distcodes[dctx->sym];
+           if (dctx->nbits < rec->extrabits)
+               goto finished;
+           dist = rec->min + (dctx->bits & ((1 << rec->extrabits) - 1));
+           EATBITS(rec->extrabits);
+           dctx->state = INBLK;
+           while (dctx->len--)
+               zlib_emit_char(dctx, dctx->window[(dctx->winpos - dist) &
+                                                 (WINSIZE - 1)]);
+           break;
+         case UNCOMP_LEN:
+           /*
+            * Uncompressed block. We expect to see a 16-bit LEN.
+            */
+           if (dctx->nbits < 16)
+               goto finished;
+           dctx->uncomplen = dctx->bits & 0xFFFF;
+           EATBITS(16);
+           dctx->state = UNCOMP_NLEN;
+           break;
+         case UNCOMP_NLEN:
+           /*
+            * Uncompressed block. We expect to see a 16-bit NLEN,
+            * which should be the one's complement of the previous
+            * LEN.
+            */
+           if (dctx->nbits < 16)
+               goto finished;
+           nlen = dctx->bits & 0xFFFF;
+           EATBITS(16);
+           if (dctx->uncomplen == 0)
+               dctx->state = OUTSIDEBLK;       /* block is empty */
+           else
+               dctx->state = UNCOMP_DATA;
+           break;
+         case UNCOMP_DATA:
+           if (dctx->nbits < 8)
+               goto finished;
+           zlib_emit_char(dctx, dctx->bits & 0xFF);
+           EATBITS(8);
+           if (--dctx->uncomplen == 0)
+               dctx->state = OUTSIDEBLK;       /* end of uncompressed block */
+           break;
+       }
+    }
+
+  finished:
+    *outblock = dctx->outblk;
+    *outlen = dctx->outlen;
+    return 1;
+
+  decode_error:
+    sfree(dctx->outblk);
+    *outblock = dctx->outblk = NULL;
+    *outlen = 0;
+    return 0;
+}
diff --git a/arm/ssh/sshzlib.h b/arm/ssh/sshzlib.h
new file mode 100644 (file)
index 0000000..89869ab
--- /dev/null
@@ -0,0 +1,39 @@
+/**********
+ * Copyright (c) 2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef SSHZLIB_H
+#define SSHZLIB_H
+
+#include "includes.h"
+
+void *zlib_compress_init(void);
+void zlib_compress_cleanup(void *ctx);
+void *zlib_decompress_init(void);
+void zlib_decompress_cleanup(void *ctx);
+int zlib_compress_block(void *ctx, unsigned char *block, size_t len,
+                        unsigned char **outblock, size_t *outlen);
+int zlib_decompress_block(void *ctx, unsigned char *block, size_t len,
+                          unsigned char **outblock, size_t *outlen);
+
+#endif
diff --git a/arm/ssh/sshzlib_armcalls.c b/arm/ssh/sshzlib_armcalls.c
new file mode 100644 (file)
index 0000000..22bbd59
--- /dev/null
@@ -0,0 +1,112 @@
+/**********
+ * Copyright (c) 2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "sshzlib.h"
+#include "pealstub.h"
+#include "swap.h"
+
+uint32_t zlib_compress_init_stub(uint32_t *param);
+uint32_t zlib_compress_cleanup_stub(uint32_t *param);
+uint32_t zlib_decompress_init_stub(uint32_t *param);
+uint32_t zlib_decompress_cleanup_stub(uint32_t *param);
+uint32_t zlib_compress_block_stub(uint32_t *param);
+uint32_t zlib_decompress_block_stub(uint32_t *param);
+
+
+uint32_t zlib_compress_init_stub(uint32_t *param)
+{
+    return (uint32_t) zlib_compress_init();
+}
+
+
+uint32_t zlib_compress_cleanup_stub(uint32_t *param)
+{
+    void *ctx = (void *)read32(&param[0]);
+    zlib_compress_cleanup(ctx);
+    return 0;
+}
+
+
+uint32_t zlib_decompress_init_stub(uint32_t *param)
+{
+    return (uint32_t) zlib_decompress_init();
+}
+
+
+uint32_t zlib_decompress_cleanup_stub(uint32_t *param)
+{
+    void *ctx = (void *)read32(&param[0]);
+    zlib_decompress_cleanup(ctx);
+    return 0;
+}
+
+
+uint32_t zlib_compress_block_stub(uint32_t *param)
+{
+    void *ctx = (void *)read32(&param[0]);
+    unsigned char *block = (unsigned char *)read32(&param[1]);
+    size_t len = (size_t)read32(&param[2]);
+    unsigned char **outblockP = (unsigned char **)read32(&param[3]);
+    size_t *outlenP= (size_t *)read32(&param[4]);
+
+    unsigned char *outblock;
+    size_t outlen;
+    int result;
+
+    if (outblockP) outblock = (unsigned char *)read32(outblockP);
+    if (outlenP) outlen = (size_t)read32(outlenP);
+
+    result = zlib_compress_block(ctx, block, len, &outblock, &outlen);
+
+    if (outblockP) write32(outblockP, (uint32_t)outblock);
+    if (outlenP) write32(outlenP, outlen);
+
+    return (uint32_t) result;
+}
+
+
+uint32_t zlib_decompress_block_stub(uint32_t *param)
+{
+    void *ctx = (void *)read32(&param[0]);
+    unsigned char *block = (unsigned char *)read32(&param[1]);
+    size_t len = (size_t)read32(&param[2]);
+    unsigned char **outblockP = (unsigned char **)read32(&param[3]);
+    size_t *outlenP = (size_t *)read32(&param[4]);
+
+    unsigned char *outblock;
+    size_t outlen;
+    int result;
+
+    if (outblockP) outblock = (unsigned char *)read32(outblockP);
+    if (outlenP) outlen = (size_t)read32(outlenP);
+
+    result = zlib_decompress_block(ctx, block, len, &outblock, &outlen);
+
+    if (outblockP) write32(outblockP, (uint32_t)outblock);
+    if (outlenP) write32(outlenP, outlen);
+
+    return (uint32_t) result;
+}
+
+
diff --git a/arm/util/PalmOS.c b/arm/util/PalmOS.c
new file mode 100644 (file)
index 0000000..5e63d25
--- /dev/null
@@ -0,0 +1,580 @@
+// PalmOS.c
+// ARM stubs for Palm OS functions
+
+#include "includes.h"
+#include "pace.h"
+
+
+MemPtr MemPtrNew(UInt32 size)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(size)
+    };
+
+    return (MemPtr) PACE_EXEC(MemPtrNew, kPceNativeWantA0);
+}
+
+
+MemPtr MemHandleLock(MemHandle h)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(h)
+    };
+
+    return (MemPtr) PACE_EXEC(MemHandleLock, kPceNativeWantA0);
+}
+
+
+Err MemHandleUnlock(MemHandle h)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(h)
+    };
+
+    return (Err) PACE_EXEC(MemHandleUnlock, 0);
+}
+
+
+UInt32 MemPtrSize(MemPtr p)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(p)
+    };
+
+    return (UInt32) PACE_EXEC(MemPtrSize, 0);
+}
+
+
+UInt32 MemHandleSize(MemHandle p)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(p)
+    };
+
+    return (UInt32) PACE_EXEC(MemHandleSize, 0);
+}
+
+
+void ClipboardAddItem(const ClipboardFormatType format, const void *ptr, UInt16 length)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD8(format)
+        PACE_PARAMS_ADD32(ptr)
+        PACE_PARAMS_ADD16(length)
+    };
+
+    PACE_EXEC(ClipboardAddItem, 0);
+}
+
+
+MemHandle ClipboardGetItem(const ClipboardFormatType format, UInt16 *length)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD8(format)
+        PACE_PARAMS_ADD32(length)
+    }; 
+    MemHandle result;
+
+    swap16P(length);
+
+    result = (MemHandle) PACE_EXEC(ClipboardGetItem, kPceNativeWantA0);
+
+    swap16P(length);
+
+    return result;
+}
+
+
+FontID FntSetFont(FontID font)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD8(font)
+    };
+
+    return (FontID) PACE_EXEC(FntSetFont, 0);
+}
+
+
+void RctGetIntersection(const RectangleType *r1P, const RectangleType *r2P, RectangleType *r3P)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(r1P)
+        PACE_PARAMS_ADD32(r2P)
+        PACE_PARAMS_ADD32(r3P)
+    };
+
+    swapRect(r1P);
+    swapRect(r2P);
+    swapRect(r3P);
+
+    PACE_EXEC(RctGetIntersection, 0);
+
+    swapRect(r1P);
+    swapRect(r2P);
+    swapRect(r3P);
+}
+
+
+Err SndDoCmd(void * /*SndChanPtr*/ channelP, SndCommandPtr cmdP, Boolean noWait)
+{
+    // SndCommandType is badly aligned for ARM. 
+    struct {
+        uint8_t cmd;
+        uint8_t reserved;
+        uint8_t param1_a;
+        uint8_t param1_b;
+        uint8_t param1_c;
+        uint8_t param1_d;
+        uint16_t param2;
+        uint16_t param3;
+    } cmd68K;
+
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(channelP)
+        PACE_PARAMS_ADD32(&cmd68K)
+        PACE_PARAMS_ADD8(noWait)
+    };
+    Err result;
+
+    cmd68K.cmd = cmdP->cmd;
+    cmd68K.reserved = cmdP->reserved;
+    cmd68K.param1_a = (cmdP->param1 & 0xff000000) >> 24;
+    cmd68K.param1_b = (cmdP->param1 & 0x00ff0000) >> 16;
+    cmd68K.param1_c = (cmdP->param1 & 0x0000ff00) >> 8;
+    cmd68K.param1_d = (cmdP->param1 & 0x000000ff) >> 0;
+    cmd68K.param2 = swap16(cmdP->param2);
+    cmd68K.param3 = swap16(cmdP->param3);
+
+    result = (Err) PACE_EXEC(SndDoCmd, 0);
+
+    // assume SndDoCmd doesn't modify cmdP
+
+    return result;
+}
+
+
+UInt16 SysTicksPerSecond(void)
+{
+    PACE_PARAMS = {
+        0
+    };
+
+    return (UInt16) PACE_EXEC(SysTicksPerSecond, 0);
+}
+
+
+UInt32 TimGetTicks(void)
+{
+    PACE_PARAMS = {
+        0
+    };
+
+    return (UInt32) PACE_EXEC(TimGetTicks, 0);
+}
+
+
+UInt32 TimGetSeconds(void)
+{
+    PACE_PARAMS = {
+        0
+    };
+
+    return (UInt32) PACE_EXEC(TimGetSeconds, 0);
+}
+
+
+void WinDrawChar (WChar theChar, Coord x, Coord y)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD16(theChar)
+        PACE_PARAMS_ADD16(x)
+        PACE_PARAMS_ADD16(y)
+    };
+
+    PACE_EXEC(WinDrawChar, 0);
+}
+
+
+void WinDrawChars (const Char *chars, Int16 len, Coord x, Coord y)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(chars)
+        PACE_PARAMS_ADD16(len)
+        PACE_PARAMS_ADD16(x)
+        PACE_PARAMS_ADD16(y)
+    };
+
+    PACE_EXEC(WinDrawChars, 0);
+}
+
+
+void WinEraseRectangle (const RectangleType *rP, UInt16 cornerDiam)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(rP)
+        PACE_PARAMS_ADD16(cornerDiam)
+    };
+
+    swapRect(rP);
+    
+    PACE_EXEC(WinEraseRectangle, 0);
+
+    swapRect(rP);
+}
+
+
+
+void WinInvertRectangle (const RectangleType *rP, UInt16 cornerDiam)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(rP)
+        PACE_PARAMS_ADD16(cornerDiam)
+    };
+
+    swapRect(rP);
+    
+    PACE_EXEC(WinInvertRectangle, 0);
+
+    swapRect(rP);
+}
+
+
+void WinPushDrawState (void)
+{
+    PACE_PARAMS = {
+        0
+    };
+
+    PACE_EXEC(WinPushDrawState, 0);
+}
+
+
+void WinPopDrawState (void)
+{
+    PACE_PARAMS = {
+        0
+    };
+
+    PACE_EXEC(WinPopDrawState, 0);
+}
+
+
+Coord WinScaleCoord(Coord coord, Boolean ceiling)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD16(coord)
+        PACE_PARAMS_ADD8(ceiling)
+    };
+
+    PACE_EXEC_SELECTOR(HDSelectorWinScaleCoord);
+    return (Coord) PACE_EXEC(HighDensityDispatch, 0);
+}
+
+
+void WinScaleRectangle(RectangleType* rectP)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(rectP)
+    };
+
+    swapRect(rectP);
+
+    PACE_EXEC_SELECTOR(HDSelectorWinScaleRectangle);
+    PACE_EXEC(HighDensityDispatch, 0);
+
+    swapRect(rectP);
+}
+
+
+Err WinScreenGetAttribute(WinScreenAttrType selector, UInt32* attrP)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD8(selector)
+        PACE_PARAMS_ADD32(attrP)
+    };
+    Err result;
+
+    swap32P(attrP);
+
+    PACE_EXEC_SELECTOR(HDSelectorWinScreenGetAttribute);
+    result = PACE_EXEC(HighDensityDispatch, 0);
+
+    swap32P(attrP);
+
+    return result;
+}
+
+
+void WinSetForeColorRGB (const RGBColorType* newRgbP, RGBColorType* prevRgbP)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(newRgbP)
+        PACE_PARAMS_ADD32(prevRgbP)
+    };
+
+    PACE_EXEC(WinSetForeColorRGB, 0);
+}
+
+
+void WinSetBackColorRGB (const RGBColorType* newRgbP, RGBColorType* prevRgbP)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(newRgbP)
+        PACE_PARAMS_ADD32(prevRgbP)
+    };
+
+    PACE_EXEC(WinSetBackColorRGB, 0);
+}
+
+
+void WinSetTextColorRGB (const RGBColorType* newRgbP, RGBColorType* prevRgbP)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(newRgbP)
+        PACE_PARAMS_ADD32(prevRgbP)
+    };
+
+    PACE_EXEC(WinSetTextColorRGB, 0);
+}
+
+
+UInt16         WinSetCoordinateSystem(UInt16 coordSys)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD16(coordSys)
+    };
+
+    PACE_EXEC_SELECTOR(HDSelectorWinSetCoordinateSystem);
+    return (UInt16) PACE_EXEC(HighDensityDispatch, 0);
+}
+
+
+Int16         StrCaselessCompare(const Char *s1, const Char *s2)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(s1)
+        PACE_PARAMS_ADD32(s2)
+    };
+    
+    return (Int16) PACE_EXEC(StrCaselessCompare, 0);
+}
+
+
+Char *StrIToA(Char *s, Int32 i)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(s)
+        PACE_PARAMS_ADD32(i)
+    };
+
+    return (Char *) PACE_EXEC(StrIToA, kPceNativeWantA0);
+}
+
+
+UInt32 PrefGetPreference(SystemPreferencesChoice choice)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD16(choice)
+    };
+
+    return (UInt32) PACE_EXEC(PrefGetPreference, 0);
+}
+
+
+void EvtAddUniqueEventToQueue(const EventType *eventP, UInt32 id, Boolean inPlace)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(eventP)
+        PACE_PARAMS_ADD32(id)
+        PACE_PARAMS_ADD8(inPlace)
+    };
+
+    PACE_EXEC(EvtAddUniqueEventToQueue, 0);
+}
+
+
+Err FtrGet(UInt32 creator, UInt16 featureNum, UInt32 *valueP)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(creator)
+        PACE_PARAMS_ADD16(featureNum)
+        PACE_PARAMS_ADD32(valueP)
+    };
+    Err result;
+
+    swap32P(valueP);
+    result = (Err) PACE_EXEC(FtrGet, 0);
+    swap32P(valueP);
+
+    return result;
+}
+
+
+Err FtrSet(UInt32 creator, UInt16 featureNum, UInt32 value)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(creator)
+        PACE_PARAMS_ADD16(featureNum)
+        PACE_PARAMS_ADD32(value)
+    };
+
+    return (Err) PACE_EXEC(FtrSet, 0);
+}
+
+
+Err FtrPtrNew(UInt32 creator, UInt16 featureNum, UInt32 size, void **newPtrP)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(creator)
+        PACE_PARAMS_ADD16(featureNum)
+        PACE_PARAMS_ADD32(size)
+        PACE_PARAMS_ADD32(newPtrP)
+    };
+    Err result;
+
+    swap32P(newPtrP);
+    result = (Err) PACE_EXEC(FtrPtrNew, 0);
+    swap32P(newPtrP);
+
+    return result;
+}
+
+
+Err FtrPtrFree(UInt32 creator, UInt16 featureNum)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(creator)
+        PACE_PARAMS_ADD16(featureNum)
+    };
+
+    return (Err) PACE_EXEC(FtrPtrFree, 0);
+}
+
+
+UInt16 FrmCustomAlert(UInt16 alertId, const Char *s1,
+                      const Char *s2, const Char *s3)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD16(alertId)
+        PACE_PARAMS_ADD32(s1)
+        PACE_PARAMS_ADD32(s2)
+        PACE_PARAMS_ADD32(s3)
+    };
+
+    return (UInt16) PACE_EXEC(FrmCustomAlert, 0);
+}
+
+
+Err DmSet(void *recordP, UInt32 offset, UInt32 bytes, UInt8 value)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(recordP)
+        PACE_PARAMS_ADD32(offset)
+        PACE_PARAMS_ADD32(bytes)
+        PACE_PARAMS_ADD8(value)
+    };
+
+    return (Err) PACE_EXEC(DmSet, 0);
+}
+
+
+UInt16 DmNumDatabases(UInt16 cardNo)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD16(cardNo)
+    };
+
+    return (UInt16) PACE_EXEC(DmNumDatabases, 0);
+}
+
+
+LocalID DmGetDatabase(UInt16 cardNo, UInt16 index)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD16(cardNo)
+        PACE_PARAMS_ADD16(index)
+    };
+
+    return (LocalID) PACE_EXEC(DmGetDatabase, 0);
+}
+
+
+Err DmDatabaseSize(UInt16 cardNo, LocalID dbID, UInt32 *numRecordsP,
+                   UInt32 *totalBytesP, UInt32 *dataBytesP)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD16(cardNo)
+        PACE_PARAMS_ADD32(dbID)
+        PACE_PARAMS_ADD32(numRecordsP)
+        PACE_PARAMS_ADD32(totalBytesP)
+        PACE_PARAMS_ADD32(dataBytesP)
+    };
+    Err result;
+
+    if (numRecordsP) swap32P(numRecordsP);
+    if (totalBytesP) swap32P(totalBytesP);
+    if (dataBytesP)  swap32P(dataBytesP);
+
+    result = (Err) PACE_EXEC(DmDatabaseSize, 0);
+
+    if (numRecordsP) swap32P(numRecordsP);
+    if (totalBytesP) swap32P(totalBytesP);
+    if (dataBytesP)  swap32P(dataBytesP);
+
+    return result;
+}
+
+
+Err DmWrite(void *recordP, UInt32 offset, const void *srcP, UInt32 bytes)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(recordP)
+        PACE_PARAMS_ADD32(offset)
+        PACE_PARAMS_ADD32(srcP)
+        PACE_PARAMS_ADD32(bytes)
+    };
+
+    return (Err) PACE_EXEC(DmWrite, 0);
+}
+
+
+MemHandle DmGetResource(DmResType type, DmResID resID)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(type)
+        PACE_PARAMS_ADD16(resID)
+    };
+    
+    return (MemHandle) PACE_EXEC(DmGetResource, kPceNativeWantA0);
+}
+
+
+UInt16 SysBatteryInfo(Boolean set, UInt16 *warnThresholdP, 
+                      UInt16 *criticalThresholdP, Int16 *maxTicksP, 
+                      SysBatteryKind* kindP, Boolean *pluggedIn, 
+                      UInt8 *percentP)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD8(set)
+        PACE_PARAMS_ADD32(warnThresholdP)
+        PACE_PARAMS_ADD32(criticalThresholdP)
+        PACE_PARAMS_ADD32(maxTicksP)
+        PACE_PARAMS_ADD32(kindP)
+        PACE_PARAMS_ADD32(pluggedIn)
+        PACE_PARAMS_ADD32(percentP)
+    };
+    UInt16 result;
+
+    if (warnThresholdP) swap16P(warnThresholdP);
+    if (criticalThresholdP) swap16P(criticalThresholdP);
+    if (maxTicksP) swap16P(maxTicksP);
+    // SysBatteryKind, Boolean, and UInt8 are 1 byte each
+    
+    result = (UInt16) PACE_EXEC(SysBatteryInfo, 0);
+
+    if (warnThresholdP) swap16P(warnThresholdP);
+    if (criticalThresholdP) swap16P(criticalThresholdP);
+    if (maxTicksP) swap16P(maxTicksP);
+
+    return result;
+}
diff --git a/arm/util/assert.h b/arm/util/assert.h
new file mode 100644 (file)
index 0000000..c231a33
--- /dev/null
@@ -0,0 +1,32 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef ASSERT_H
+#define ASSERT_H
+
+#include "includes.h"
+
+#define assert(c) do { if (!(c)) fatal("assertion failed (file %s line %d)", __FILE__, __LINE__); } while (0)
+
+#endif
diff --git a/arm/util/ctype.h b/arm/util/ctype.h
new file mode 100644 (file)
index 0000000..8acf651
--- /dev/null
@@ -0,0 +1,65 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// ctype.h replacement
+
+#ifndef CTYPE_H
+#define CTYPE_H
+
+static inline int isdigit(unsigned char c);
+static inline int isxdigit(unsigned char c);
+static inline int iscntrl(unsigned char c);
+static inline int isprint(unsigned char c);
+static inline int isspace(unsigned char c);
+
+
+static inline int isdigit(unsigned char c) {
+    return (c >= '0'  &&  c <= '9');
+}
+
+
+static inline int isxdigit(unsigned char c) {
+    return ((c >= '0'  &&  c <= '9')  ||  
+            (c >= 'a'  &&  c <= 'f')  ||  
+            (c >= 'A'  &&  c <= 'F'));
+}
+
+
+static inline int iscntrl(unsigned char c) {
+    return (c <= 037  ||  c == 0177);
+}
+
+
+static inline int isprint(unsigned char c) {
+    return (c >= 040  &&  c <= 0176);
+}
+
+
+static inline int isspace(unsigned char c) {
+    return (c == '\t'  ||  c == '\n'  ||  c == '\v'  ||  
+            c == '\f'  ||  c == '\r'  ||  c == ' ');
+}
+
+
+#endif
diff --git a/arm/util/includes.h b/arm/util/includes.h
new file mode 100644 (file)
index 0000000..f4b9fca
--- /dev/null
@@ -0,0 +1,115 @@
+/**********
+ * Copyright (c) 2004-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef INCLUDES_H
+#define INCLUDES_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdarg.h>
+
+// evil hack to avoid trap definitions
+#define _STRUCTURE_PICTURES
+#define __SPIC__(a, b, c, d)
+#include <PalmOS.h>
+#include <PceNativeCall.h>
+#undef  _STRUCTURE_PICTURES
+#undef  __SPIC__
+
+#include "assert.h"
+#include "stdlib.h"
+#include "xmalloc.h"
+
+
+// assorted types
+typedef int32_t ssize_t;
+
+
+// prototypes for gcc builtins
+extern char *strcpy(char *dst, const char *src);
+extern char *strncpy(char *dst, const char *src, size_t len);
+extern size_t strlen(const char *s);
+extern char *strchr(const char *s, int c);
+extern char *strrchr(const char *s, int c);
+extern char *strstr(const char *big, const char *little);
+extern void *memcpy(void *dst, const void *src, size_t len);
+extern void *memset(void *b, int c, size_t len);
+extern int strncmp(const char *s1, const char *s2, size_t len);
+extern void *memmove(void *dst, const void *src, size_t len);
+extern char *strcat(char *s, const char *append);
+extern char *strncat(char *s, const char *append, size_t count);
+extern int memcmp(const void *b1, const void *b2, size_t len);
+
+
+// misc definitions
+
+#define RCSID(str) /* */
+
+#ifndef MAX
+# define MAX(a,b) (((a)>(b))?(a):(b))
+# define MIN(a,b) (((a)<(b))?(a):(b))
+#endif
+
+
+// logging
+static inline void noop() { }
+
+#define fortuna_log noop
+#define rand_log noop
+#define vt100_log noop
+#define vt100_log noop
+
+
+// custom event types
+#define usrNetEvent (sysEventFirstUserEvent+0)
+#define usrDrawVT100Event (sysEventFirstUserEvent+1)
+#define usrDrawCloseBoxEvent (sysEventFirstUserEvent+2)
+#define usrSetScrollBarEvent (sysEventFirstUserEvent+3)
+
+#pragma pack(push, 2)
+typedef struct {
+    uint16_t eType;
+    Boolean penDown;
+    UInt8 tapCount;
+    Int16 screenX;
+    Int16 screenY;
+    union {
+        struct _GenericEventType generic;
+        struct {
+            void *frontend;
+            int16_t total;
+            int16_t start;
+            int16_t page;
+        } sbar;
+    } data;
+} SetScrollBarEventType;
+#pragma pack(pop)
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE (!FALSE)
+#endif
+
+
+#endif
diff --git a/arm/util/pace.h b/arm/util/pace.h
new file mode 100644 (file)
index 0000000..5ebe705
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef PACE_H
+#define PACE_H
+
+#include "includes.h"
+#include "pealstub.h"
+#include "swap.h"
+
+typedef struct EmulStateType 
+{
+    uint32_t instr;
+    uint32_t regD[8];
+    uint32_t regA[8];
+    uint32_t regPC;
+} EmulStateType;
+
+#define PACE_PARAMS \
+uint8_t params[] 
+
+#define PACE_PARAMS_ADD8(param) \
+( (uint8_t)(param) & 0xff), 0,
+
+#define PACE_PARAMS_ADD16(param) \
+(((uint16_t)(param) >> 8) & 0xff), \
+( (uint16_t)(param) & 0xff),
+
+#define PACE_PARAMS_ADD32(param) \
+(((uint32_t)(param) >> 24) & 0xff), \
+(((uint32_t)(param) >> 16) & 0xff), \
+(((uint32_t)(param) >> 8) & 0xff), \
+( (uint32_t)(param) & 0xff),
+
+
+#define PACE_EXEC_FN(fn, flag) \
+gCall68KFuncP((void *)gEmulStateP, \
+((unsigned long)fn), &params, sizeof(params) | (flag))
+
+#define PACE_EXEC(trap, flag) \
+gCall68KFuncP((void *)gEmulStateP, \
+PceNativeTrapNo(sysTrap##trap), &params, sizeof(params) | (flag))
+
+#define PACE_EXEC_SELECTOR(selector) \
+((EmulStateType *)gEmulStateP)->regD[2] = selector
+
+#endif
diff --git a/arm/util/stdlib.c b/arm/util/stdlib.c
new file mode 100644 (file)
index 0000000..92e9490
--- /dev/null
@@ -0,0 +1,147 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "stdlib.h"
+
+#include "pace.h"
+#include "ctype.h"
+#include "assert.h"
+#include "rsrc/rsrc.h"
+
+// 68K function addresses (written by 68K code)
+uintptr_t assert_failed_68K = 0;
+uintptr_t fatal_68K = 0;
+
+char *strsep(char **stringp, const char *delim)
+{
+    char *pos;
+    char *str = *stringp;
+    if (!str) return NULL;
+
+    // GrP only implemented for single-character delim
+    assert(strlen(delim) == 1);
+
+    pos = strchr(str, *delim);
+    if (pos) {
+        *pos = '\0';
+        *stringp = pos+1;
+    } else {
+        *stringp = NULL;
+    }
+    return str;
+}
+
+
+int strcasecmp(const char *s1, const char *s2)
+{
+    return StrCaselessCompare(s1, s2);
+}
+
+
+char *strcasestr(const char *big, const char *little)
+{
+    int littlelen = strlen(little);
+
+    const char *s = big;
+    for (s = big; *s != '\0'; s++) {
+        if (0 == memcmp(s, little, littlelen)) return (char *)s;
+    }
+    return NULL;
+}
+
+
+void debug_printf(const char *format, ...)
+{
+    char buf[320];
+    va_list args;
+    RectangleType r = {{0, 0}, {160, 14}};
+    WinHandle drawWindow;
+
+    va_start(args, format);
+    strcpy(buf, "ARM ");
+    vsnprintf(buf+4, sizeof(buf)-4, format, args);
+    va_end(args);
+
+    // print on top of program title box
+    // will be visible even with vt100 problems and alerts
+    // fixme this causes problems with hi-res drawing
+    // drawWindow = WinSetDrawWindow(NULL);
+    WinPushDrawState();
+    WinEraseRectangle(&r, 0);
+    WinDrawChars(buf, strlen(buf), 0, 0);
+    WinPopDrawState();
+    // WinSetDrawWindow(drawWindow);
+}
+
+
+void complain(char *err)
+{
+    WinPushDrawState();
+    WinSetCoordinateSystem(kCoordinatesStandard);
+    FrmCustomAlert(AlertFormID, err, " ", " ");
+    WinPopDrawState();
+}
+
+void complain_int(char *err, uint32_t i) 
+{
+    char intbuf[20];
+    WinPushDrawState();
+    WinSetCoordinateSystem(kCoordinatesStandard);
+    FrmCustomAlert(AlertFormID, err, StrIToA(intbuf, i), " ");
+    WinPopDrawState();
+}
+
+
+static int fatal_str(const char *s)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32("%s")
+        PACE_PARAMS_ADD32(s)
+    };
+
+    return (int) PACE_EXEC_FN(fatal_68K, 0);
+}
+
+int fatal(const char *format, ...)
+{
+    char buf[320];
+    va_list args;
+
+    va_start(args, format);
+    vsnprintf(buf, sizeof(buf), format, args);
+    va_end(args);
+
+    return fatal_str(buf);
+}
+
+
+void assert_failed(uint32_t which)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(which)
+    };
+
+    PACE_EXEC_FN(assert_failed_68K, 0);
+}
+
diff --git a/arm/util/stdlib.h b/arm/util/stdlib.h
new file mode 100644 (file)
index 0000000..150f65c
--- /dev/null
@@ -0,0 +1,44 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef STDLIB_H
+#define STDLIB_H
+
+#include "includes.h"
+#include "xmalloc.h"
+
+char *strsep(char **stringp, const char *delim);
+int strcasecmp(const char *s1, const char *s2);
+char *strcasestr(const char *big, const char *little);
+
+void debug_printf(const char *format, ...);
+int fatal(const char *format, ...);
+
+// in openssh/openbsd-compat/bsd-snprintf.c
+int vsnprintf(char *str, size_t count, const char *fmt, va_list args);
+int snprintf(char *str, size_t count, const char *fmt, ...);
+
+void assert_failed(uint32_t which);
+
+#endif
diff --git a/arm/util/swap.h b/arm/util/swap.h
new file mode 100644 (file)
index 0000000..91c005f
--- /dev/null
@@ -0,0 +1,130 @@
+#ifndef SWAP_H
+#define SWAP_H
+
+#include <stdint.h>
+
+extern inline uint16_t swap16(uint16_t v);
+extern inline uint32_t swap32(uint32_t v);
+extern inline void swap16P(const void *p);
+extern inline void swap32P(void *p);
+#ifdef __PALMTYPES_H__
+extern inline void swapRect(const struct RectangleType *r);
+#endif
+
+extern inline uint16_t read16(void *p);
+extern inline uint32_t read32(void *p);
+extern inline void write16(void *p, uint16_t value);
+extern inline void write32(void *p, uint32_t value);
+#ifdef __PALMTYPES_H__
+extern inline RectangleType readRect(void *p);
+extern inline void writeRect(void *p, RectangleType r);
+#endif
+
+extern inline uint16_t swap16(uint16_t v)
+{
+    return (((v & 0x00ff) << 8) | 
+            ((v & 0xff00) >> 8));
+    
+}
+
+
+extern inline uint32_t swap32(uint32_t v)
+{
+    return (((v & 0x000000ff) << 24) | 
+            ((v & 0x0000ff00) <<  8) | 
+            ((v & 0x00ff0000) >>  8) | 
+            ((v & 0xff000000) >> 24));
+}
+
+
+extern inline void swap16P(const void *p)
+{
+    *(uint16_t *)p = swap16(*(uint16_t *)p);
+}
+
+
+extern inline void swap32P(void *p)
+{
+    *(uint32_t *)p = swap32(*(uint32_t *)p);
+}
+
+
+#ifdef __PALMTYPES_H__
+
+// const because most rectangle parameters are const
+extern inline void swapRect(const RectangleType *r)
+{
+    swap16P(&r->topLeft.x);
+    swap16P(&r->topLeft.y);
+    swap16P(&r->extent.x);
+    swap16P(&r->extent.y);
+}
+
+#endif
+
+
+extern inline uint16_t read16(void *p)
+{
+    uint8_t *c = (uint8_t *)p;
+    return (uint16_t)( (c[0] << 8) | 
+                       (c[1] << 0) );
+}
+
+extern inline uint32_t read32(void *p)
+{
+    uint8_t *c = (uint8_t *)p;
+    return (uint32_t)( (c[0] << 24) | 
+                       (c[1] << 16) | 
+                       (c[2] <<  8) | 
+                       (c[3] <<  0) );
+}
+
+
+extern inline void write16(void *p, uint16_t value)
+{
+    uint8_t *c = (uint8_t *)p;
+    c[0] = value >> 8;
+    c[1] = value >> 0;
+}
+
+
+extern inline void write32(void *p, uint32_t value)
+{
+    uint8_t *c = (uint8_t *)p;
+    c[0] = value >> 24;
+    c[1] = value >> 16;
+    c[2] = value >>  8;
+    c[3] = value >>  0;
+}
+
+
+#ifdef __PALMTYPES_H__
+
+extern inline RectangleType readRect(void *p)
+{
+    RectangleType *r68K = (RectangleType *)p;
+    RectangleType r;
+    
+    r.topLeft.x = read16(&r68K->topLeft.x);
+    r.topLeft.y = read16(&r68K->topLeft.y);
+    r.extent.x  = read16(&r68K->extent.x);
+    r.extent.y  = read16(&r68K->extent.y);
+
+    return r;
+}
+
+
+extern inline void writeRect(void *p, RectangleType r)
+{
+    RectangleType *r68K = (RectangleType *)p;
+    
+    write16(&r68K->topLeft.x, r.topLeft.x);
+    write16(&r68K->topLeft.y, r.topLeft.y);
+    write16(&r68K->extent.x,  r.extent.x);
+    write16(&r68K->extent.y,  r.extent.y);
+}
+
+#endif
+
+
+#endif
diff --git a/arm/util/xmalloc.c b/arm/util/xmalloc.c
new file mode 100644 (file)
index 0000000..4c35a1d
--- /dev/null
@@ -0,0 +1,79 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "pace.h"
+
+// 68K function addresses (eritten by 68K code)
+uintptr_t arena_malloc_68K = 0;
+uintptr_t arena_realloc_68K = 0;
+uintptr_t arena_calloc_68K = 0;
+uintptr_t arena_free_68K = 0;
+
+void *arena_malloc(size_t s) 
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(s)
+    };
+
+    return (void *)PACE_EXEC_FN(arena_malloc_68K, kPceNativeWantA0);
+}
+
+void arena_free(void *p) 
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(p)
+    };
+
+    PACE_EXEC_FN(arena_free_68K, 0);
+}
+
+void *arena_calloc(size_t s) 
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(s)
+    };
+
+    return (void *)PACE_EXEC_FN(arena_calloc_68K, kPceNativeWantA0);
+}
+
+void *arena_realloc(void *oldp, size_t newsize)
+{
+    PACE_PARAMS = {
+        PACE_PARAMS_ADD32(oldp)
+        PACE_PARAMS_ADD32(newsize)
+    };
+
+    return (void *)PACE_EXEC_FN(arena_realloc_68K, kPceNativeWantA0);
+}
+
+char *arena_strdup(const char *s)
+{
+    size_t len = 1+strlen(s);
+    char *news;
+    news = arena_malloc(len);
+    memcpy(news, s, len);
+    return news;
+}
+
diff --git a/arm/util/xmalloc.h b/arm/util/xmalloc.h
new file mode 100644 (file)
index 0000000..4f9824a
--- /dev/null
@@ -0,0 +1,48 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef XMALLOC_H
+#define XMALLOC_H
+
+#include "includes.h"
+
+void *arena_malloc(size_t s);
+void arena_free(void *p);
+void *arena_calloc(size_t s);
+void *arena_realloc(void *oldp, size_t newsize);
+char *arena_strdup(const char *s);
+
+// non-arena versions
+#define nonarena_malloc arena_malloc
+#define nonarena_free arena_free
+#define nonarena_strdup arena_strdup
+
+// OpenSSH versions (fixme move somewhere else?)
+#define xmalloc arena_malloc
+#define xfree arena_free
+#define xrealloc arena_realloc
+#define xcalloc arena_calloc
+#define xstrdup arena_strdup
+
+#endif
diff --git a/arm/vt100/misc.c b/arm/vt100/misc.c
new file mode 100644 (file)
index 0000000..0c5606b
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+PuTTY is copyright 1997-2004 Simon Tatham.
+
+Portions copyright Robert de Bath, Joris van Rantwijk, Delian
+Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
+Justin Bradford, Ben Harris, and CORE SDI S.A.
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation files
+(the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "includes.h"
+#include "assert.h"
+
+#include "putty.h"
+
+
+/* ----------------------------------------------------------------------
+ * Base64 encoding routine. This is required in public-key writing
+ * but also in HTTP proxy handling, so it's centralised here.
+ */
+
+static const char base64_chars[] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+void base64_encode_atom(unsigned char *data, int n, char *out)
+{
+    uint32_t word;
+
+    word = (uint32_t)data[0] << 16;
+    if (n > 1)
+       word |= (uint32_t)data[1] << 8;
+    if (n > 2)
+       word |= data[2];
+    out[0] = base64_chars[(word >> 18) & 0x3F];
+    out[1] = base64_chars[(word >> 12) & 0x3F];
+    if (n > 1)
+       out[2] = base64_chars[(word >> 6) & 0x3F];
+    else
+       out[2] = '=';
+    if (n > 2)
+       out[3] = base64_chars[word & 0x3F];
+    else
+       out[3] = '=';
+}
+
+/* ----------------------------------------------------------------------
+ * Generic routines to deal with send buffers: a linked list of
+ * smallish blocks, with the operations
+ * 
+ *  - add an arbitrary amount of data to the end of the list
+ *  - remove the first N bytes from the list
+ *  - return a (pointer,length) pair giving some initial data in
+ *    the list, suitable for passing to a send or write system
+ *    call
+ *  - retrieve a larger amount of initial data from the list
+ *  - return the current size of the buffer chain in bytes
+ */
+
+#define BUFFER_GRANULE  512L
+
+struct bufchain_granule {
+    struct bufchain_granule *next;
+    size_t buflen, bufpos;
+    char buf[BUFFER_GRANULE];
+};
+
+void bufchain_init(bufchain *ch)
+{
+    ch->head = ch->tail = NULL;
+    ch->buffersize = 0;
+}
+
+void bufchain_clear(bufchain *ch)
+{
+    struct bufchain_granule *b;
+    while (ch->head) {
+       b = ch->head;
+       ch->head = ch->head->next;
+       sfree(b);
+    }
+    ch->tail = NULL;
+    ch->buffersize = 0;
+}
+
+size_t bufchain_size(bufchain *ch)
+{
+    return ch->buffersize;
+}
+
+void bufchain_add(bufchain *ch, const void *data, size_t len)
+{
+    const char *buf = (const char *)data;
+
+    if (len == 0) return;
+
+    ch->buffersize += len;
+
+    if (ch->tail && ch->tail->buflen < BUFFER_GRANULE) {
+       size_t copylen = min(len, BUFFER_GRANULE - ch->tail->buflen);
+       memcpy(ch->tail->buf + ch->tail->buflen, buf, copylen);
+       buf += copylen;
+       len -= copylen;
+       ch->tail->buflen += copylen;
+    }
+    while (len > 0) {
+       size_t grainlen = min(len, BUFFER_GRANULE);
+       struct bufchain_granule *newbuf;
+       newbuf = snew(struct bufchain_granule);
+       newbuf->bufpos = 0;
+       newbuf->buflen = grainlen;
+       memcpy(newbuf->buf, buf, grainlen);
+       buf += grainlen;
+       len -= grainlen;
+       if (ch->tail)
+           ch->tail->next = newbuf;
+       else
+           ch->head = ch->tail = newbuf;
+       newbuf->next = NULL;
+       ch->tail = newbuf;
+    }
+}
+
+void bufchain_consume(bufchain *ch, size_t len)
+{
+    struct bufchain_granule *tmp;
+
+    assert(ch->buffersize >= len);
+    while (len > 0) {
+       size_t remlen = len;
+       assert(ch->head != NULL);
+       if (remlen >= ch->head->buflen - ch->head->bufpos) {
+           remlen = ch->head->buflen - ch->head->bufpos;
+           tmp = ch->head;
+           ch->head = tmp->next;
+           sfree(tmp);
+           if (!ch->head)
+               ch->tail = NULL;
+       } else
+           ch->head->bufpos += remlen;
+       ch->buffersize -= remlen;
+       len -= remlen;
+    }
+}
+
+void bufchain_prefix(bufchain *ch, void **data, size_t *len)
+{
+    *len = ch->head->buflen - ch->head->bufpos;
+    *data = ch->head->buf + ch->head->bufpos;
+}
+
+void bufchain_fetch(bufchain *ch, void *data, size_t len)
+{
+    struct bufchain_granule *tmp;
+    char *data_c = (char *)data;
+
+    tmp = ch->head;
+
+    assert(ch->buffersize >= len);
+    while (len > 0) {
+       size_t remlen = len;
+
+       assert(tmp != NULL);
+       if (remlen >= tmp->buflen - tmp->bufpos)
+           remlen = tmp->buflen - tmp->bufpos;
+       memcpy(data_c, tmp->buf + tmp->bufpos, remlen);
+
+       tmp = tmp->next;
+       len -= remlen;
+       data_c += remlen;
+    }
+}
diff --git a/arm/vt100/misc.h b/arm/vt100/misc.h
new file mode 100644 (file)
index 0000000..5aba54d
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+PuTTY is copyright 1997-2004 Simon Tatham.
+
+Portions copyright Robert de Bath, Joris van Rantwijk, Delian
+Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
+Justin Bradford, Ben Harris, and CORE SDI S.A.
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation files
+(the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef PUTTY_MISC_H
+#define PUTTY_MISC_H
+
+#include "puttymem.h"
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+typedef struct Filename Filename;
+typedef struct FontSpec FontSpec;
+
+void base64_encode_atom(unsigned char *data, int n, char *out);
+
+struct bufchain_granule;
+typedef struct bufchain_tag {
+    struct bufchain_granule *head, *tail;
+    size_t buffersize;                /* current amount of buffered data */
+} bufchain;
+
+void bufchain_init(bufchain *ch);
+void bufchain_clear(bufchain *ch);
+size_t bufchain_size(bufchain *ch);
+void bufchain_add(bufchain *ch, const void *data, size_t len);
+void bufchain_prefix(bufchain *ch, void **data, size_t *len);
+void bufchain_consume(bufchain *ch, size_t len);
+void bufchain_fetch(bufchain *ch, void *data, size_t len);
+
+/*
+ * Debugging functions.
+ *
+ * Output goes to debug.log
+ *
+ * debug(()) (note the double brackets) is like printf().
+ *
+ * dmemdump() and dmemdumpl() both do memory dumps.  The difference
+ * is that dmemdumpl() is more suited for when where the memory is is
+ * important (say because you'll be recording pointer values later
+ * on).  dmemdump() is more concise.
+ */
+
+#define debug(x)
+#define dmemdump(buf,len)
+#define dmemdumpl(buf,len)
+
+#ifndef lenof
+#define lenof(x) ( (sizeof((x))) / (sizeof(*(x))))
+#endif
+
+#ifndef min
+#define min(x,y) ( (x) < (y) ? (x) : (y) )
+#endif
+#ifndef max
+#define max(x,y) ( (x) > (y) ? (x) : (y) )
+#endif
+
+#endif
diff --git a/arm/vt100/palm/palmprint.c b/arm/vt100/palm/palmprint.c
new file mode 100644 (file)
index 0000000..423ceb1
--- /dev/null
@@ -0,0 +1,59 @@
+/**********
+ * Portions Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// fixme someday print to PalmPrint or something else
+
+#include "putty.h"
+
+struct printer_job_tag {
+    void *empty;
+};
+
+printer_job *printer_start_job(char *printer) 
+{
+    return NULL;
+}
+
+void printer_job_data(printer_job *pj, void *data, size_t len)
+{
+}
+
+void printer_finish_job(printer_job *pj)
+{
+}
+
+printer_enum *printer_start_enum(int *nprinters_ptr) 
+{
+    *nprinters_ptr = 0;
+    return NULL;
+}
+
+char *printer_get_name(printer_enum *pe, int i) 
+{
+    return NULL;
+}
+
+void printer_finish_enum(printer_enum *pe) 
+{
+}
diff --git a/arm/vt100/palm/palmstuff.h b/arm/vt100/palm/palmstuff.h
new file mode 100644 (file)
index 0000000..ea77b1d
--- /dev/null
@@ -0,0 +1,62 @@
+/**********
+ * Portions Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+#ifndef PUTTY_PALMSTUFF_H
+#define PUTTY_PALMSTUFF_H
+
+#include <stdint.h>
+
+
+struct FontSpec {
+    uint16_t fontID;
+    // maybe more later
+};
+
+typedef void *Context; // fixme
+
+/* Multi-click events don't repeat MA_CLICK for each click */
+#define MULTICLICK_ONLY_EVENT 1
+
+/* get_clip and write_clip do not use nul-terminated characters */
+#define SELECTION_NUL_TERMINATED 0
+
+/* Palm newline is CR */
+#define SEL_NL { '\r' }
+
+unsigned long getticks(void);
+unsigned long tickspersec(void);
+#define GETTICKCOUNT getticks
+#define TICKSPERSEC tickspersec()
+#define CURSORBLINK (tickspersec() * 0.45)
+
+
+#define WCHAR wchar_t
+#define BYTE uint8_t
+
+
+#define DEFAULT_CODEPAGE 0 /* fixme CS_ISO8859_1 */
+#define CP_UTF8 14238 /* fixme CS_UTF8 */
+struct unicode_data;
+void init_ucs(struct unicode_data *ucsdata, int font_charset, int vtmode);
+
+#endif
diff --git a/arm/vt100/palm/palmucs.c b/arm/vt100/palm/palmucs.c
new file mode 100644 (file)
index 0000000..04862d1
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+PuTTY is copyright 1997-2004 Simon Tatham.
+
+Portions copyright Robert de Bath, Joris van Rantwijk, Delian
+Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
+Justin Bradford, Ben Harris, and CORE SDI S.A.
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation files
+(the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/**********
+ * Portions Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "putty.h"
+// #include "charset.h"
+#include "terminal.h"
+#include "misc.h"
+
+/*
+ * Palm Unicode-handling routines.
+ * GrP fixme ISO 8859-1 only, not really unicode
+ */
+
+int is_dbcs_leadbyte(int codepage, char byte)
+{
+    return 0;                         /* we don't do DBCS */
+}
+
+// GrP fixme assumes multibyte is really single byte
+size_t mb_to_wc(int codepage, int flags, char *mbstr, size_t mblen,
+                wchar_t *wcstr, size_t wclen)
+{
+    size_t n = 0;
+    while (mblen > 0) {
+        wcstr[n] = (mbstr[0] & 0xFF);
+        n++;
+        mbstr++;
+        mblen--;
+    }
+    return n;
+}
+
+
+// GrP fixme assumes multibyte is really single byte
+size_t wc_to_mb(int codepage, int flags, wchar_t *wcstr, size_t wclen,
+                char *mbstr, size_t mblen, char *defchr, int *defused,
+                struct unicode_data *ucsdata)
+{
+    size_t n = 0;
+
+    /* FIXME: we should remove the defused param completely... */
+    if (defused)
+       *defused = 0;
+
+    while (wclen > 0 && n < mblen) {
+        mbstr[n++] = (*wcstr & 0xFF);
+        wcstr++;
+        wclen--;
+    }
+    return n;
+}
+
+// GrP fixme use this for cut&paste
+static const wchar_t unitab_xterm_poorman[32] = {
+    '*','#','*','*','*','*','o','~','*','*','+','+','+','+','+','-',
+    '-','-','-','-','+','+','+','+','|','*','*','*','*','L','.'
+};
+/*
+ * Return value is TRUE if pterm is to run in direct-to-font mode.
+ */
+void init_ucs(struct unicode_data *ucsdata, int font_charset, int vtmode)
+{
+    int i;
+
+    /*
+     * In the platform-independent parts of the code, font_codepage
+     * is used only for system DBCS support - which we don't
+     * support at all. So we set this to something which will never
+     * be used.
+     */
+    ucsdata->font_codepage = -1;
+
+    ucsdata->line_codepage = font_charset;
+
+    // GrP stripped unitab and charset goo except for unitab_ctrl
+    // We use ISO 8859-1 only for now. 
+    // note: Palm native charset is CP1252 except for two places 
+    // (accented S and s). CP1252 is a superset of ISO-8859-1
+
+    /*
+     * Find the control characters in the line codepage. For
+     * direct-to-font mode using the D800 hack, we assume 00-1F and
+     * 7F are controls, but allow 80-9F through. (It's as good a
+     * guess as anything; and my bet is that half the weird fonts
+     * used in this way will be IBM or MS code pages anyway.)
+     */
+    // GrP no D800 hack
+    for (i = 0; i < 256; i++) {
+       unsigned int lineval = i;
+       if (lineval < ' ' || (lineval >= 0x7F && lineval < 0xA0))
+           ucsdata->unitab_ctrl[i] = i;
+       else
+           ucsdata->unitab_ctrl[i] = 0xFF;
+    }
+}
diff --git a/arm/vt100/palm/palmwindow.c b/arm/vt100/palm/palmwindow.c
new file mode 100644 (file)
index 0000000..ee25bcc
--- /dev/null
@@ -0,0 +1,473 @@
+/**********
+ * Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "data/prefs.h"
+#include "putty.h"
+#include "vt100.h"
+#include "swap.h"
+
+// Default color set
+// BOLD is more saturated, except for white and black themselves
+#define DEFAULT_COLORS \
+    {0, 0x00,0x00,0x00}, {0, 0x22,0x22,0x22},  \
+    {0, 0xdd,0x00,0x00}, {0, 0xff,0x00,0x00},  \
+    {0, 0x00,0xdd,0x00}, {0, 0x00,0xff,0x00},  \
+    {0, 0xdd,0xdd,0x00}, {0, 0xff,0xff,0x00},  \
+    {0, 0x00,0x00,0xdd}, {0, 0x00,0x00,0xff},  \
+    {0, 0xdd,0x00,0xdd}, {0, 0xff,0x00,0xff},  \
+    {0, 0x00,0xdd,0xdd}, {0, 0x00,0xff,0xff},  \
+    {0, 0xff,0xff,0xff}, {0, 0xdd,0xdd,0xdd},
+
+static RGBColorType defaultColors[16] = {
+    DEFAULT_COLORS
+};
+
+static RGBColorType colors[16] = {
+    DEFAULT_COLORS
+};
+
+static unsigned int DefaultForeColor = defaultForeColor;
+static unsigned int DefaultBackColor = defaultBackColor;
+
+
+void read_default_colors(void)
+{
+    DefaultForeColor = PrefsGetInt(prefTerminalForeColor, defaultForeColor);
+    if (DefaultForeColor >= 8) DefaultForeColor = defaultForeColor;
+    DefaultBackColor = PrefsGetInt(prefTerminalBackColor, defaultBackColor);
+    if (DefaultBackColor >= 8) DefaultBackColor = defaultBackColor;
+}
+
+void set_palm_color(int fg_color, int bg_color)
+{
+    WinSetForeColorRGB(&colors[fg_color], NULL);
+    WinSetTextColorRGB(&colors[fg_color], NULL);
+    WinSetBackColorRGB(&colors[bg_color], NULL);
+}
+
+
+
+void set_iconic(void *frontend, int iconic)
+{
+    // palm: do nothing
+}
+
+
+void move_window(void *frontend, int x, int y)
+{
+    // palm: do nothing
+}
+
+
+void set_zorder(void *frontend, int top)
+{
+    // palm: do nothing
+}
+
+
+void refresh_window(void *frontend)
+{
+    // palm: queue update event for later redraw
+    EventType e = {0};
+    e.eType = swap16(usrDrawVT100Event);
+    EvtAddUniqueEventToQueue(&e, 0, true);
+}
+
+
+void set_zoomed(void *frontend, int zoomed)
+{
+    // palm: do nothing
+}
+
+
+int is_iconic(void *frontend)
+{
+    // palm: never iconic
+    return 0;
+}
+
+
+void get_window_pos(void *frontend, int *x, int *y)
+{
+    // palm: never moves
+    if (x) *x = 0;
+    if (y) *y = 0;
+}
+
+
+void get_window_pixels(void *frontend, int *x, int *y)
+{
+    display *disp = (display *)frontend;
+
+    if (x) *x = disp->textBounds.extent.x;
+    if (y) *y = disp->textBounds.extent.y;
+}
+
+
+char *get_window_title(void *frontend, int icon)
+{
+    // palm: fixme
+    return "pssh";
+}
+
+
+void set_raw_mouse_mode(void *frontend, int activate)
+{
+    // palm: do nothing
+}
+
+
+void request_resize(void *frontend, int w, int h)
+{
+    // palm: do nothing
+}
+
+
+void palette_set(void *frontend, int n, int r, int g, int b)
+{
+    // palm: fixme
+}
+
+
+void palette_reset(void *frontend)
+{
+    int i;
+    for (i = 0; i < 16; i++) {
+        colors[i] = defaultColors[i];
+    }
+}
+
+
+void write_clip(void *frontend, char *data, size_t len, int must_deselect)
+{
+    display *disp = (display *)frontend;
+    char *newdata;
+    unsigned int i;
+    // convert newlines - Palm uses LF
+    // fixme newline conversion might not be necessary
+    newdata = snewn(len, char);
+    for (i = 0; i < len; i++) {
+        if (data[i] == 13) newdata[i] = 10;
+        else newdata[i] = (char)data[i];
+    }
+
+    ClipboardAddItem(clipboardText, newdata, len);
+    sfree(newdata);
+
+    if (must_deselect) term_deselect(disp->term);
+}
+
+
+void request_paste(void *frontend)
+{
+    // palm: do nothing (only used in response to X11 paste button)
+}
+
+
+void get_clip(void *frontend, wchar_t **p, size_t *len)
+{
+    MemHandle clipH;
+    char *clipP;
+    UInt16 clipLen;
+    static wchar_t *wclipP = NULL;
+
+    if (p) {
+        clipH = ClipboardGetItem(clipboardText, &clipLen);
+        *len = clipLen;
+        if (clipH) {
+            UInt16 i;
+            clipP = MemHandleLock(clipH);
+            wclipP = snewn(*len, wchar_t);
+            for (i = 0; i < *len; i++) {
+                wclipP[i] = (wchar_t)clipP[i];
+            }
+            *p = wclipP;
+            MemHandleUnlock(clipH);
+        } else {
+            // no clipboard to paste
+            *p = NULL;
+            if (wclipP) sfree(wclipP);
+            wclipP = NULL;
+        }
+    } else {
+        // clear previously retrieved clip
+        if (wclipP) {
+            sfree(wclipP);
+            wclipP = NULL;
+        }
+    }
+}
+
+
+void set_title(void *frontend, char *title)
+{
+    // palm: fixme do something?
+}
+
+
+void set_icon(void *frontend, char *title)
+{
+    // palm: fixme do something?
+}
+
+
+void set_sbar(void *frontend, int total, int start, int page)
+{
+    // palm: queue update event for later redraw
+    SetScrollBarEventType e = {0};
+    int16_t total16 = total;
+    int16_t start16 = start;
+    int16_t page16 = page;
+    e.eType = swap16(usrSetScrollBarEvent);
+    e.data.sbar.frontend = (void *)swap32((uintptr_t)frontend);
+    e.data.sbar.total = swap16(total16);
+    e.data.sbar.start = swap16(start16);
+    e.data.sbar.page = swap16(page16);
+    EvtAddUniqueEventToQueue((EventPtr)&e, 0, true);
+}
+
+
+void sys_cursor(void *frontend, int x, int y)
+{
+    // palm: do nothing
+}
+
+
+void beep(void *frontend, int mode)
+{
+    if (mode & BELL_AUDIBLE) {
+        // beep at 400 Hz for 100 ms
+        SndCommandType snd;
+        UInt16 volume = PrefGetPreference(prefGameSoundVolume);
+        snd.cmd = sndCmdFrqOn; // asynchronous
+        snd.reserved = 0;
+        snd.param1 = 400; // frequency in Hz
+        snd.param2 = 100; // duration in ms
+        snd.param3 = volume; // volume [0..sndMaxAmp]
+        SndDoCmd(NULL, &snd, false);
+    }
+}
+
+
+int char_width(Context ctx, unsigned int uc)
+{
+    // palm: fixme
+    return 1;
+}
+
+
+Context get_ctx(void *frontend)
+{
+    display *disp = (display *)frontend;
+
+    if (disp->inactive) return NULL;
+
+    WinPushDrawState();
+    WinSetCoordinateSystem(kCoordinatesNative);
+
+    FntSetFont(disp->fontID);
+
+    return (Context)disp;
+}
+
+
+void free_ctx(Context ctx)
+{
+    if (!ctx) return;
+    WinPopDrawState();
+}
+
+
+static int SectRect(RectangleType a, RectangleType b)
+{
+    RectangleType c;
+    RctGetIntersection(&a, &b, &c);
+    return (c.extent.x == 0  ||  c.extent.y == 0);
+}
+
+
+void do_text(Context ctx, int x, int y, char *text, int len, 
+             unsigned long attr, unsigned long lattr)
+{
+#define LEFT(rr) ((rr).topLeft.x)
+#define TOP(rr) ((rr).topLeft.y)
+#define RIGHT(rr) ((rr).topLeft.x + (rr).extent.x)
+#define BOTTOM(rr) ((rr).topLeft.y + (rr).extent.y)
+
+    display *dd = (display *)ctx;
+
+    int fg_color;
+    int bg_color;
+    int font_width = dd->font_width;
+    int font_height = dd->font_height;
+
+    RectangleType r, big, fill;
+    RectangleType closeBox;
+    int closeBoxInvalid = 0;
+
+    closeBox.topLeft.x = RIGHT(dd->gadgetBounds) - dd->closeBoxSize;
+    closeBox.topLeft.y = TOP(dd->gadgetBounds);
+    closeBox.extent.x = dd->closeBoxSize;
+    closeBox.extent.y = dd->closeBoxSize;
+
+    r.topLeft.x = dd->textBounds.topLeft.x + x * font_width;
+    r.topLeft.y = dd->textBounds.topLeft.y + y * font_height;
+    r.extent.x = len * font_width;
+    r.extent.y = font_height;
+
+    fg_color = (attr & ATTR_FGMASK) >> ATTR_FGSHIFT;
+    bg_color = (attr & ATTR_BGMASK) >> ATTR_BGSHIFT;
+
+    // handle VT100 linedraw chars
+    // 0x5f maps to space
+    // 0x60..0x7e map to 0x01..0x1f
+    if ((attr & CSET_MASK) == ATTR_LINEDRW) {
+        unsigned char *c, *end;
+        for (c = (unsigned char *)text, end = (unsigned char *)text+len; c < end; c++) {
+            if (*c == 0x5f) *c = ' ';
+            else if (*c >= 0x60  &&  *c <= 0x7e) *c = *c - 0x60 + 0x01;
+        }
+    }
+
+    // handle default colors
+    if (fg_color == (ATTR_DEFFG >> ATTR_FGSHIFT)) fg_color = DefaultForeColor;
+    if (bg_color == (ATTR_DEFBG >> ATTR_BGSHIFT)) bg_color = DefaultBackColor;
+
+    // translate into indexes into colors[]
+    fg_color *= 2;
+    bg_color *= 2;
+
+    if (attr & ATTR_REVERSE) {
+        int temp = fg_color;
+        fg_color = bg_color;
+        bg_color = temp;
+    }
+
+    // fixme can do real bold and underline with bigger fonts
+    if ((attr & ATTR_BOLD)  ||  (attr & ATTR_UNDER)) {
+        fg_color++;
+    }
+    // fixme allow optional real blink
+    if (attr & ATTR_BLINK) {
+        bg_color++;
+    }
+
+    set_palm_color(fg_color, bg_color);
+    WinDrawChars(text, len, r.topLeft.x, r.topLeft.y);
+    if (SectRect(r, closeBox)) closeBoxInvalid = 1;
+
+    // If the drawn rect extends to any edge of the text area, fill the 
+    // gap between the text area and the gadget bounds with the 
+    // background color.
+    big = r;
+    if (LEFT(r) == LEFT(dd->textBounds)) {
+        big.topLeft.x = LEFT(dd->gadgetBounds);
+        big.extent.x += LEFT(dd->textBounds) - LEFT(dd->gadgetBounds);
+    }
+    if (TOP(r) == TOP(dd->textBounds)) {
+        big.topLeft.y = TOP(dd->gadgetBounds);
+        big.extent.y += TOP(dd->textBounds) - TOP(dd->gadgetBounds);
+    }
+    if (RIGHT(r) == RIGHT(dd->textBounds)) {
+        big.extent.x += RIGHT(dd->gadgetBounds) - RIGHT(dd->textBounds);
+    }
+    if (BOTTOM(r) == BOTTOM(dd->textBounds)) {
+        big.extent.y += BOTTOM(dd->gadgetBounds) - BOTTOM(dd->textBounds);
+    }
+
+    // Fill any gaps outside big and inside r
+    if (LEFT(big) != LEFT(r)) {
+        fill.topLeft.x = LEFT(big);
+        fill.topLeft.y = TOP(big);
+        fill.extent.x = LEFT(r) - LEFT(big);
+        fill.extent.y = big.extent.y;
+        WinEraseRectangle(&fill, 0);
+        if (SectRect(fill, closeBox)) closeBoxInvalid = 1;
+    }
+    if (TOP(big) != TOP(r)) {
+        fill.topLeft.x = LEFT(big);
+        fill.topLeft.y = TOP(big);
+        fill.extent.x = big.extent.x;
+        fill.extent.y = TOP(r) - TOP(big);
+        WinEraseRectangle(&fill, 0);
+        if (SectRect(fill, closeBox)) closeBoxInvalid = 1;
+    }
+    if (RIGHT(big) != RIGHT(r)) {
+        fill.topLeft.x = RIGHT(r);
+        fill.topLeft.y = TOP(big);
+        fill.extent.x = RIGHT(big) - RIGHT(r);
+        fill.extent.y = big.extent.y;
+        WinEraseRectangle(&fill, 0);
+        if (SectRect(fill, closeBox)) closeBoxInvalid = 1;
+    }
+    if (BOTTOM(big) != BOTTOM(r)) {
+        fill.topLeft.x = LEFT(big);
+        fill.topLeft.y = BOTTOM(r);
+        fill.extent.x = big.extent.x;
+        fill.extent.y = BOTTOM(big) - BOTTOM(r);
+        WinEraseRectangle(&fill, 0);
+        if (SectRect(fill, closeBox)) closeBoxInvalid = 1;
+    }
+
+    // cursor
+    // fixme better cursor, box cursor, etc
+    if (attr & (TATTR_ACTCURS | TATTR_PASCURS | TATTR_RIGHTCURS)) {
+        WinInvertRectangle(&r, 0);
+    }
+
+    if (closeBoxInvalid) {
+        EventType e = {0};
+        e.eType = swap16(usrDrawCloseBoxEvent);
+        EvtAddUniqueEventToQueue(&e, 0, true);
+    }
+}
+
+
+void do_cursor(Context ctx, int x, int y, char *text, int len, 
+               unsigned long attr, unsigned long lattr)
+{
+    do_text(ctx, x, y, text, len, attr, lattr);
+}
+
+
+unsigned long getticks(void) 
+{
+    return TimGetTicks();
+}
+
+unsigned long tickspersec(void) 
+{
+    return SysTicksPerSecond();
+}
+
+
+
+void ldisc_update(void *frontend, int echo, int edit)
+{
+}
+
+void frontend_keypress(void *handle)
+{
+}
diff --git a/arm/vt100/putty.h b/arm/vt100/putty.h
new file mode 100644 (file)
index 0000000..690281c
--- /dev/null
@@ -0,0 +1,687 @@
+/*
+PuTTY is copyright 1997-2004 Simon Tatham.
+
+Portions copyright Robert de Bath, Joris van Rantwijk, Delian
+Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
+Justin Bradford, Ben Harris, and CORE SDI S.A.
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation files
+(the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/**********
+ * Portions Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef PUTTY_PUTTY_H
+#define PUTTY_PUTTY_H
+
+#include "includes.h"
+
+/*
+ * Global variables. Most modules declare these `extern', but
+ * window.c will do `#define PUTTY_DO_GLOBALS' before including this
+ * module, and so will get them properly defined.
+ */
+#ifndef GLOBAL
+#ifdef PUTTY_DO_GLOBALS
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+#endif
+
+#ifndef DONE_TYPEDEFS
+#define DONE_TYPEDEFS
+typedef struct config_tag Config;
+typedef struct backend_tag Backend;
+typedef struct terminal_tag Terminal;
+#endif
+
+#include "puttyps.h"
+#include "misc.h"
+
+/* Three attribute types: 
+ * The ATTRs (normal attributes) are stored with the characters in
+ * the main display arrays
+ *
+ * The TATTRs (temporary attributes) are generated on the fly, they
+ * can overlap with characters but not with normal attributes.
+ *
+ * The LATTRs (line attributes) are an entirely disjoint space of
+ * flags.
+ *
+ * ATTR_INVALID is an illegal colour combination.
+ */
+
+#define TATTR_ACTCURS      0x4UL      /* active cursor (block) */
+#define TATTR_PASCURS      0x2UL      /* passive cursor (box) */
+#define TATTR_RIGHTCURS            0x1UL      /* cursor-on-RHS */
+
+#define LATTR_NORM   0x00000000UL
+#define LATTR_WIDE   0x01000000UL
+#define LATTR_TOP    0x02000000UL
+#define LATTR_BOT    0x03000000UL
+#define LATTR_MODE   0x03000000UL
+#define LATTR_WRAPPED 0x10000000UL
+#define LATTR_WRAPPED2 0x20000000UL
+
+#define ATTR_INVALID 0x03FF0000UL
+
+/* Like Linux use the F000 page for direct to font. */
+#define ATTR_OEMCP   0x0000F000UL      /* OEM Codepage DTF */
+#define ATTR_ACP     0x0000F100UL      /* Ansi Codepage DTF */
+
+/* These are internal use overlapping with the UTF-16 surrogates */
+#define ATTR_ASCII   0x0000D800UL      /* normal ASCII charset ESC ( B */
+#define ATTR_LINEDRW 0x0000D900UL      /* line drawing charset ESC ( 0 */
+#define ATTR_SCOACS  0x0000DA00UL      /* SCO Alternate charset */
+#define ATTR_GBCHR   0x0000DB00UL      /* UK variant   charset ESC ( A */
+#define CSET_MASK    0x0000FF00UL      /* Character set mask; MUST be 0xFF00 */
+
+#define DIRECT_CHAR(c) ((c&0xFC00)==0xD800)
+#define DIRECT_FONT(c) ((c&0xFE00)==0xF000)
+
+#define UCSERR      (ATTR_LINEDRW|'a') /* UCS Format error character. */
+/*
+ * UCSWIDE is a special value used in the terminal data to signify
+ * the character cell containing the right-hand half of a CJK wide
+ * character. We use 0xDFFF because it's part of the surrogate
+ * range and hence won't be used for anything else (it's impossible
+ * to input it via UTF-8 because our UTF-8 decoder correctly
+ * rejects surrogates).
+ */
+#define UCSWIDE             0xDFFF
+
+#define ATTR_NARROW  0x80000000UL
+#define ATTR_WIDE    0x40000000UL
+#define ATTR_BOLD    0x04000000UL
+#define ATTR_UNDER   0x08000000UL
+#define ATTR_REVERSE 0x10000000UL
+#define ATTR_BLINK   0x20000000UL
+#define ATTR_FGMASK  0x001F0000UL
+#define ATTR_BGMASK  0x03E00000UL
+#define ATTR_COLOURS 0x03FF0000UL
+#define ATTR_FGSHIFT 16
+#define ATTR_BGSHIFT 21
+
+#define ATTR_DEFAULT 0x01280000UL      /* bg 9, fg 8 */
+#define ATTR_DEFFG   0x00080000UL
+#define ATTR_DEFBG   0x01200000UL
+#define ERASE_CHAR   (ATTR_DEFAULT | ATTR_ASCII | ' ')
+#define ATTR_MASK    0xFFFFFF00UL
+#define CHAR_MASK    0x000000FFUL
+
+#define ATTR_CUR_AND (~(ATTR_BOLD|ATTR_REVERSE|ATTR_BLINK|ATTR_COLOURS))
+#define ATTR_CUR_XOR 0x016A0000UL
+
+struct sesslist {
+    int nsessions;
+    char **sessions;
+    char *buffer;                     /* so memory can be freed later */
+};
+
+struct unicode_data {
+    char **uni_tbl;
+    int dbcs_screenfont;
+    int font_codepage;
+    int line_codepage;
+    wchar_t unitab_scoacs[256];
+    wchar_t unitab_line[256];
+    wchar_t unitab_font[256];
+    wchar_t unitab_xterm[256];
+    wchar_t unitab_oemcp[256];
+    unsigned char unitab_ctrl[256];
+};
+
+#define LGXF_OVR  1                   /* existing logfile overwrite */
+#define LGXF_APN  0                   /* existing logfile append */
+#define LGXF_ASK -1                   /* existing logfile ask */
+#define LGTYP_NONE  0                 /* logmode: no logging */
+#define LGTYP_ASCII 1                 /* logmode: pure ascii */
+#define LGTYP_DEBUG 2                 /* logmode: all chars of traffic */
+#define LGTYP_PACKETS 3                       /* logmode: SSH data packets */
+
+typedef enum {
+    TS_AYT, TS_BRK, TS_SYNCH, TS_EC, TS_EL, TS_GA, TS_NOP, TS_ABORT,
+    TS_AO, TS_IP, TS_SUSP, TS_EOR, TS_EOF, TS_LECHO, TS_RECHO, TS_PING,
+    TS_EOL
+} Telnet_Special;
+
+struct telnet_special {
+    const char *name;                 /* NULL==end, ""==separator */
+    int code;
+};
+
+typedef enum {
+    MBT_NOTHING,
+    MBT_LEFT, MBT_MIDDLE, MBT_RIGHT,   /* `raw' button designations */
+    MBT_SELECT, MBT_EXTEND, MBT_PASTE, /* `cooked' button designations */
+    MBT_WHEEL_UP, MBT_WHEEL_DOWN       /* mouse wheel */
+} Mouse_Button;
+
+typedef enum {
+    MA_NOTHING, MA_CLICK, MA_2CLK, MA_3CLK, MA_DRAG, MA_RELEASE
+} Mouse_Action;
+
+/* Keyboard modifiers -- keys the user is actually holding down */
+
+#define PKM_SHIFT      0x01
+#define PKM_CONTROL    0x02
+#define PKM_META       0x04
+#define PKM_ALT                0x08
+
+/* Keyboard flags that aren't really modifiers */
+#define PKF_CAPSLOCK   0x10
+#define PKF_NUMLOCK    0x20
+#define PKF_REPEAT     0x40
+
+/* Stand-alone keysyms for function keys */
+
+typedef enum {
+    PK_NULL,           /* No symbol for this key */
+    /* Main keypad keys */
+    PK_ESCAPE, PK_TAB, PK_BACKSPACE, PK_RETURN, PK_COMPOSE,
+    /* Editing keys */
+    PK_HOME, PK_INSERT, PK_DELETE, PK_END, PK_PAGEUP, PK_PAGEDOWN,
+    /* Cursor keys */
+    PK_UP, PK_DOWN, PK_RIGHT, PK_LEFT, PK_REST,
+    /* Numeric keypad */                       /* Real one looks like: */
+    PK_PF1, PK_PF2, PK_PF3, PK_PF4,            /* PF1 PF2 PF3 PF4 */
+    PK_KPCOMMA, PK_KPMINUS, PK_KPDECIMAL,      /*  7   8   9   -  */
+    PK_KP0, PK_KP1, PK_KP2, PK_KP3, PK_KP4,    /*  4   5   6   ,  */
+    PK_KP5, PK_KP6, PK_KP7, PK_KP8, PK_KP9,    /*  1   2   3  en- */
+    PK_KPBIGPLUS, PK_KPENTER,                  /*    0     .  ter */
+    /* Top row */
+    PK_F1,  PK_F2,  PK_F3,  PK_F4,  PK_F5,
+    PK_F6,  PK_F7,  PK_F8,  PK_F9,  PK_F10,
+    PK_F11, PK_F12, PK_F13, PK_F14, PK_F15,
+    PK_F16, PK_F17, PK_F18, PK_F19, PK_F20,
+    PK_PAUSE
+} Key_Sym;
+
+#define PK_ISEDITING(k)        ((k) >= PK_HOME && (k) <= PK_PAGEDOWN)
+#define PK_ISCURSOR(k) ((k) >= PK_UP && (k) <= PK_REST)
+#define PK_ISKEYPAD(k) ((k) >= PK_PF1 && (k) <= PK_KPENTER)
+#define PK_ISFKEY(k)   ((k) >= PK_F1 && (k) <= PK_F20)
+
+enum {
+    VT_XWINDOWS, VT_OEMANSI, VT_OEMONLY, VT_POORMAN, VT_UNICODE
+};
+
+enum {
+    /*
+     * SSH ciphers (both SSH1 and SSH2)
+     */
+    CIPHER_WARN,                       /* pseudo 'cipher' */
+    CIPHER_3DES,
+    CIPHER_BLOWFISH,
+    CIPHER_AES,                        /* (SSH 2 only) */
+    CIPHER_DES,
+    CIPHER_MAX                         /* no. ciphers (inc warn) */
+};
+
+enum {
+    /*
+     * Several different bits of the PuTTY configuration seem to be
+     * three-way settings whose values are `always yes', `always
+     * no', and `decide by some more complex automated means'. This
+     * is true of line discipline options (local echo and line
+     * editing), proxy DNS, Close On Exit, and SSH server bug
+     * workarounds. Accordingly I supply a single enum here to deal
+     * with them all.
+     */
+    FORCE_ON, FORCE_OFF, AUTO
+};
+
+enum {
+    /*
+     * Proxy types.
+     */
+    PROXY_NONE, PROXY_SOCKS4, PROXY_SOCKS5,
+    PROXY_HTTP, PROXY_TELNET, PROXY_CMD
+};
+
+enum {
+    /*
+     * Line discipline options which the backend might try to control.
+     */
+    LD_EDIT,                          /* local line editing */
+    LD_ECHO                           /* local echo */
+};
+
+enum {
+    /* Protocol back ends. (cfg.protocol) */
+    PROT_RAW, PROT_TELNET, PROT_RLOGIN, PROT_SSH
+};
+
+enum {
+    /* Bell settings (cfg.beep) */
+    // GrP allow audible and visible to be set simultaneously
+    BELL_AUDIBLE = 1<<0,
+    BELL_VISIBLE = 1<<1
+};
+
+enum {
+    /* Taskbar flashing indication on bell (cfg.beep_ind) */
+    B_IND_DISABLED, B_IND_FLASH, B_IND_STEADY
+};
+
+enum {
+    /* Resize actions (cfg.resize_action) */
+    RESIZE_TERM, RESIZE_DISABLED, RESIZE_FONT, RESIZE_EITHER
+};
+
+enum {
+    /* Function key types (cfg.funky_type) */
+    FUNKY_TILDE,
+    FUNKY_LINUX,
+    FUNKY_XTERM,
+    FUNKY_VT400,
+    FUNKY_VT100P,
+    FUNKY_SCO
+};
+
+struct backend_tag {
+    const char *(*init) (void *frontend_handle, void **backend_handle,
+                         Config *cfg,
+                         char *host, int port, char **realhost, int nodelay);
+    void (*free) (void *handle);
+    /* back->reconfig() passes in a replacement configuration. */
+    void (*reconfig) (void *handle, Config *cfg);
+    /* back->send() returns the current amount of buffered data. */
+    int (*send_buf) (void *handle, char *buf, int len);
+    /* back->sendbuffer() does the same thing but without attempting a send */
+    int (*sendbuffer) (void *handle);
+    void (*size) (void *handle, int width, int height);
+    void (*special) (void *handle, Telnet_Special code);
+    const struct telnet_special *(*get_specials) (void *handle);
+    // Socket(*socket) (void *handle);
+    int (*exitcode) (void *handle);
+    int (*sendok) (void *handle);
+    int (*ldisc) (void *handle, int);
+    void (*provide_ldisc) (void *handle, void *ldisc);
+    void (*provide_logctx) (void *handle, void *logctx);
+    /*                                                                          
+     * back->unthrottle() tells the back end that the front end                 
+     * buffer is clearing.                                                      
+     */
+    void (*unthrottle) (void *handle, int);
+    int default_port;
+};
+
+extern struct backend_list {
+    int protocol;
+    char *name;
+    Backend *backend;
+} backends[];
+
+/*
+ * IMPORTANT POLICY POINT: everything in this structure which wants
+ * to be treated like an integer must be an actual, honest-to-
+ * goodness `int'. No enum-typed variables. This is because parts
+ * of the code will want to pass around `int *' pointers to them
+ * and we can't run the risk of porting to some system on which the
+ * enum comes out as a different size from int.
+ */
+struct config_tag {
+    /* Basic options */
+    char host[512];
+    int port;
+    int protocol;
+    int close_on_exit;
+    int warn_on_close;
+    int ping_interval;                 /* in seconds */
+    int tcp_nodelay;
+    /* Proxy options */
+    char proxy_exclude_list[512];
+    int proxy_dns;
+    int even_proxy_localhost;
+    int proxy_type;
+    char proxy_host[512];
+    int proxy_port;
+    char proxy_username[32];
+    char proxy_password[32];
+    char proxy_telnet_command[512];
+    /* SSH options */
+    char remote_cmd[512];
+    char remote_cmd2[512];             /* fallback if the first fails
+                                        * (used internally for scp) */
+    char *remote_cmd_ptr;              /* might point to a larger command
+                                        * but never for loading/saving */
+    char *remote_cmd_ptr2;             /* might point to a larger command 
+                                        * but never for loading/saving */
+    int nopty;
+    int compression;
+    int agentfwd;
+    int change_username;               /* allow username switching in SSH2 */
+    int ssh_cipherlist[CIPHER_MAX];
+    // Filename keyfile;
+    int sshprot;                       /* use v1 or v2 when both available */
+    int ssh2_des_cbc;                  /* "des-cbc" nonstandard SSH2 cipher */
+    int try_tis_auth;
+    int try_ki_auth;
+    int ssh_subsys;                    /* run a subsystem rather than a command */
+    int ssh_subsys2;                   /* fallback to go with remote_cmd2 */
+    /* Telnet options */
+    char *termtype;
+    char termspeed[32];
+    char environmt[1024];             /* VAR\tvalue\0VAR\tvalue\0\0 */
+    char username[100];
+    char localusername[100];
+    int rfc_environ;
+    int passive_telnet;
+    /* Keyboard options */
+    int bksp_is_delete;
+    int rxvt_homeend;
+    int funky_type;
+    int no_applic_c;                  /* totally disable app cursor keys */
+    int no_applic_k;                  /* totally disable app keypad */
+    int no_mouse_rep;                 /* totally disable mouse reporting */
+    int no_remote_resize;             /* disable remote resizing */
+    int no_alt_screen;                /* disable alternate screen */
+    int no_remote_wintitle;           /* disable remote retitling */
+    int no_dbackspace;                /* disable destructive backspace */
+    int no_remote_charset;            /* disable remote charset config */
+    int no_remote_qtitle;             /* disable remote win title query */
+    int app_cursor;
+    int app_keypad;
+    int nethack_keypad;
+    int telnet_keyboard;
+    int telnet_newline;
+    int alt_f4;                               /* is it special? */
+    int alt_space;                    /* is it special? */
+    int alt_only;                     /* is it special? */
+    int localecho;
+    int localedit;
+    int alwaysontop;
+    int fullscreenonaltenter;
+    int scroll_on_key;
+    int scroll_on_disp;
+    int erase_to_scrollback;
+    int compose_key;
+    int ctrlaltkeys;
+    char wintitle[256];                       /* initial window title */
+    /* Terminal options */
+    int savelines;
+    int dec_om;
+    int wrap_mode;
+    int lfhascr;
+    int cursor_type;                  /* 0=block 1=underline 2=vertical */
+    int blink_cur;
+    int beep;
+    int beep_ind;
+    int bellovl;                      /* bell overload protection active? */
+    int bellovl_n;                    /* number of bells to cause overload */
+    int bellovl_t;                    /* time interval for overload (seconds) */
+    int bellovl_s;                    /* period of silence to re-enable bell (s) */
+    int scrollbar;
+    int scrollbar_in_fullscreen;
+    int resize_action;
+    int bce;
+    int blinktext;
+    int win_name_always;
+    int width, height;
+    FontSpec font;
+    int logtype;
+    int logxfovr;
+    int hide_mouseptr;
+    int sunken_edge;
+    int window_border;
+    char answerback[256];
+    char printer[128];
+    /* Colour options */
+    int system_colour;
+    int try_palette;
+    int bold_colour;
+    unsigned char colours[22][3];
+    /* Selection options */
+    int mouse_is_xterm;
+    int rect_select;
+    int rawcnp;
+    int rtf_paste;
+    int mouse_override;
+    short *wordness;
+    /* translations */
+    int vtmode;
+    char line_codepage[128];
+    int xlat_capslockcyr;
+    /* Options for pterm. Should split out into platform-dependent part. */
+    int stamp_utmp;
+    int login_shell;
+    int scrollbar_on_left;
+    int shadowbold;
+    FontSpec boldfont;
+    FontSpec widefont;
+    FontSpec wideboldfont;
+    int shadowboldoffset;
+};
+
+/*
+ * Exports from window.c.
+ */
+void request_resize(void *frontend, int, int);
+void do_text(Context, int, int, char *, int, unsigned long, unsigned long);
+void do_cursor(Context, int, int, char *, int, unsigned long, unsigned long);
+int char_width(Context ctx, unsigned int uc);
+#ifdef OPTIMISE_SCROLL
+void do_scroll(Context, int, int, int);
+#endif
+void set_title(void *frontend, char *);
+void set_icon(void *frontend, char *);
+void set_sbar(void *frontend, int, int, int);
+Context get_ctx(void *frontend);
+void free_ctx(Context);
+void palette_set(void *frontend, int, int, int, int);
+void palette_reset(void *frontend);
+void write_aclip(void *frontend, char *, int, int);
+void write_clip(void *frontend, char *, size_t, int);
+void get_clip(void *frontend, wchar_t **, size_t *);
+void optimised_move(void *frontend, int, int, int);
+void set_raw_mouse_mode(void *frontend, int);
+void connection_fatal(void *frontend, char *, ...);
+void fatalbox(char *, ...);
+void modalfatalbox(char *, ...);
+#ifdef macintosh
+#pragma noreturn(fatalbox)
+#pragma noreturn(modalfatalbox)
+#endif
+void beep(void *frontend, int);
+void begin_session(void *frontend);
+void sys_cursor(void *frontend, int x, int y);
+void request_paste(void *frontend);
+void frontend_keypress(void *frontend);
+void ldisc_update(void *frontend, int echo, int edit);
+void update_specials_menu(void *frontend);
+int from_backend(void *frontend, int is_stderr, const char *data, size_t len);
+#define OPTIMISE_IS_SCROLL 1
+
+void set_iconic(void *frontend, int iconic);
+void move_window(void *frontend, int x, int y);
+void set_zorder(void *frontend, int top);
+void refresh_window(void *frontend);
+void set_zoomed(void *frontend, int zoomed);
+int is_iconic(void *frontend);
+void get_window_pos(void *frontend, int *x, int *y);
+void get_window_pixels(void *frontend, int *x, int *y);
+char *get_window_title(void *frontend, int icon);
+
+void cleanup_exit(int);
+
+
+/*
+ * Exports from settings.c.
+ */
+char *save_settings(char *section, int do_host, Config * cfg);
+void save_open_settings(void *sesskey, int do_host, Config *cfg);
+void load_settings(char *section, int do_host, Config * cfg);
+void load_open_settings(void *sesskey, int do_host, Config *cfg);
+void get_sesslist(struct sesslist *, int allocate);
+void do_defaults(char *, Config *);
+void registry_cleanup(void);
+
+/*
+ * Functions used by settings.c to provide platform-specific
+ * default settings.
+ * 
+ * (The integer one is expected to return `def' if it has no clear
+ * opinion of its own. This is because there's no integer value
+ * which I can reliably set aside to indicate `nil'. The string
+ * function is perfectly all right returning NULL, of course. The
+ * Filename and FontSpec functions are _not allowed_ to fail to
+ * return, since these defaults _must_ be per-platform.)
+ */
+char *platform_default_s(const char *name);
+int platform_default_i(const char *name, int def);
+Filename platform_default_filename(const char *name);
+FontSpec platform_default_fontspec(const char *name);
+
+/*
+ * Exports from terminal.c.
+ */
+
+Terminal *term_init(Config *, struct unicode_data *, void *);
+void term_free(Terminal *);
+void term_size(Terminal *, int, int, int);
+void term_out(Terminal *);
+void term_paint(Terminal *, Context, int, int, int, int, int);
+void term_scroll(Terminal *, int, int);
+void term_pwron(Terminal *);
+void term_clrsb(Terminal *);
+void term_mouse(Terminal *, Mouse_Button, Mouse_Button, Mouse_Action,
+               int,int,int,int,int);
+void term_key(Terminal *, Key_Sym, wchar_t *, size_t, unsigned int,
+             unsigned int);
+void term_deselect(Terminal *);
+void term_update(Terminal *);
+void term_invalidate(Terminal *);
+int term_blink(Terminal *, int set_cursor);
+void term_do_paste(Terminal *);
+int term_paste_pending(Terminal *);
+void term_paste(Terminal *);
+void term_nopaste(Terminal *);
+int term_ldisc(Terminal *, int option);
+void term_copyall(Terminal *);
+void term_reconfig(Terminal *, Config *);
+void term_seen_key_event(Terminal *); 
+size_t term_data(Terminal *, int is_stderr, const char *data, size_t len);
+void term_provide_resize_fn(Terminal *term,
+                           void (*resize_fn)(void *, int, int),
+                           void *resize_ctx);
+void term_provide_logctx(Terminal *term, void *logctx);
+void term_copy(Terminal *term);
+int term_selection_exists(Terminal *term);
+int term_app_cursor_keys(Terminal *term); // fixme suck
+void term_task(Terminal *);
+
+/*
+ * Exports from ssh.c. (NB the getline variables have to be GLOBAL
+ * so that PuTTYtel will still compile - otherwise it would depend
+ * on ssh.c.)
+ */
+
+GLOBAL int (*ssh_get_line) (const char *prompt, char *str, int maxlen,
+                           int is_pw);
+GLOBAL int ssh_getline_pw_only;
+extern Backend ssh_backend;
+
+/*
+ * Exports from ldisc.c.
+ */
+void *ldisc_create(Config *, Terminal *, Backend *, void *, void *);
+void ldisc_free(void *);
+void ldisc_send(void *handle, char *buf, ssize_t len, int interactive);
+
+/*
+ * Exports from ldiscucs.c.
+ */
+void lpage_send(void *, int codepage, char *buf, size_t len, int interactive);
+void luni_send(void *, wchar_t * widebuf, size_t len, int interactive);
+
+/*
+ * Exports from unicode.c.
+ */
+#ifndef CP_UTF8
+#define CP_UTF8 65001
+#endif
+/* void init_ucs(void); -- this is now in platform-specific headers */
+int is_dbcs_leadbyte(int codepage, char byte);
+size_t mb_to_wc(int codepage, int flags, char *mbstr, size_t mblen,
+                wchar_t *wcstr, size_t wclen);
+size_t wc_to_mb(int codepage, int flags, wchar_t *wcstr, size_t wclen,
+                char *mbstr, size_t mblen, char *defchr, int *defused,
+                struct unicode_data *ucsdata);
+wchar_t xlat_uskbd2cyrllic(int ch);
+int check_compose(int first, int second);
+int decode_codepage(char *cp_name);
+const char *cp_enumerate (int index);
+const char *cp_name(int codepage);
+void get_unitab(int codepage, wchar_t * unitab, int ftype);
+
+/*
+ * Exports from wcwidth.c
+ */
+int wcwidth(wchar_t ucs);
+int wcswidth(const wchar_t *pwcs, size_t n);
+
+/*
+ * Exports from printing.c.
+ */
+typedef struct printer_enum_tag printer_enum;
+typedef struct printer_job_tag printer_job;
+printer_enum *printer_start_enum(int *nprinters);
+char *printer_get_name(printer_enum *, int);
+void printer_finish_enum(printer_enum *);
+printer_job *printer_start_job(char *printer);
+void printer_job_data(printer_job *, void *, size_t);
+void printer_finish_job(printer_job *);
+
+/*
+ * Exports from config.c.
+ */
+struct controlbox;
+void setup_config_box(struct controlbox *b, struct sesslist *sesslist,
+                     int midsession, int protocol);
+
+/*
+ * Miscellaneous exports from the platform-specific code.
+ */
+char *get_username(void);             /* return value needs freeing */
+char *get_random_data(int bytes);      /* used in cmdgen.c */
+
+#endif
diff --git a/arm/vt100/puttymem.h b/arm/vt100/puttymem.h
new file mode 100644 (file)
index 0000000..b5eaef8
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+PuTTY is copyright 1997-2004 Simon Tatham.
+
+Portions copyright Robert de Bath, Joris van Rantwijk, Delian
+Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
+Justin Bradford, Ben Harris, and CORE SDI S.A.
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation files
+(the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/**********
+ * Portions Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+/*
+ * PuTTY memory-handling header.
+ */
+
+#ifndef PUTTY_PUTTYMEM_H
+#define PUTTY_PUTTYMEM_H
+
+#include "includes.h"
+#include "xmalloc.h"
+
+#define smalloc arena_malloc
+#define srealloc arena_realloc
+#define sfree arena_free
+
+/*
+ * Direct use of smalloc within the code should be avoided where
+ * possible, in favour of these type-casting macros which ensure
+ * you don't mistakenly allocate enough space for one sort of
+ * structure and assign it to a different sort of pointer.
+ */
+#define snew(type) ((type *)smalloc(sizeof(type)))
+#define snewn(n, type) ((type *)smalloc((n)*sizeof(type)))
+#define sresize(ptr, n, type) ((type *)srealloc(ptr, (n)*sizeof(type)))
+
+#endif
diff --git a/arm/vt100/puttyps.h b/arm/vt100/puttyps.h
new file mode 100644 (file)
index 0000000..1b634a4
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+PuTTY is copyright 1997-2004 Simon Tatham.
+
+Portions copyright Robert de Bath, Joris van Rantwijk, Delian
+Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
+Justin Bradford, Ben Harris, and CORE SDI S.A.
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation files
+(the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/**********
+ * Portions Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef PUTTY_PUTTYPS_H
+#define PUTTY_PUTTYPS_H
+
+#ifdef _WINDOWS
+
+#include "winstuff.h"
+
+#elif defined(macintosh)
+
+#include "macstuff.h"
+
+#elif defined(__palmos__)
+
+#include "palmstuff.h"
+
+#else
+
+#include "unix.h"
+
+#endif
+
+#endif
diff --git a/arm/vt100/terminal.c b/arm/vt100/terminal.c
new file mode 100644 (file)
index 0000000..b92ca5b
--- /dev/null
@@ -0,0 +1,4920 @@
+/*
+PuTTY is copyright 1997-2004 Simon Tatham.
+
+Portions copyright Robert de Bath, Joris van Rantwijk, Delian
+Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
+Justin Bradford, Ben Harris, and CORE SDI S.A.
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation files
+(the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/**********
+ * Portions Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "assert.h"
+#include "ctype.h"
+
+#include "putty.h"
+#include "terminal.h"
+
+#define poslt(p1,p2) ( (p1).y < (p2).y || ( (p1).y == (p2).y && (p1).x < (p2).x ) )
+#define posle(p1,p2) ( (p1).y < (p2).y || ( (p1).y == (p2).y && (p1).x <= (p2).x ) )
+#define poseq(p1,p2) ( (p1).y == (p2).y && (p1).x == (p2).x )
+#define posdiff(p1,p2) ( ((p1).y - (p2).y) * (term->cols+1) + (p1).x - (p2).x )
+
+/* Product-order comparisons for rectangular block selection. */
+#define posPlt(p1,p2) ( (p1).y <= (p2).y && (p1).x < (p2).x )
+#define posPle(p1,p2) ( (p1).y <= (p2).y && (p1).x <= (p2).x )
+
+#define incpos(p) ( (p).x == term->cols ? ((p).x = 0, (p).y++, 1) : ((p).x++, 0) )
+#define decpos(p) ( (p).x == 0 ? ((p).x = term->cols, (p).y--, 1) : ((p).x--, 0) )
+
+#define VT52_PLUS
+
+#define CL_ANSIMIN     0x0001         /* Codes in all ANSI like terminals. */
+#define CL_VT100       0x0002         /* VT100 */
+#define CL_VT100AVO    0x0004         /* VT100 +AVO; 132x24 (not 132x14) & attrs */
+#define CL_VT102       0x0008         /* VT102 */
+#define CL_VT220       0x0010         /* VT220 */
+#define CL_VT320       0x0020         /* VT320 */
+#define CL_VT420       0x0040         /* VT420 */
+#define CL_VT510       0x0080         /* VT510, NB VT510 includes ANSI */
+#define CL_VT340TEXT   0x0100         /* VT340 extensions that appear in the VT420 */
+#define CL_SCOANSI     0x1000         /* SCOANSI not in ANSIMIN. */
+#define CL_ANSI                0x2000         /* ANSI ECMA-48 not in the VT100..VT420 */
+#define CL_OTHER       0x4000         /* Others, Xterm, linux, putty, dunno, etc */
+
+#define TM_VT100       (CL_ANSIMIN|CL_VT100)
+#define TM_VT100AVO    (TM_VT100|CL_VT100AVO)
+#define TM_VT102       (TM_VT100AVO|CL_VT102)
+#define TM_VT220       (TM_VT102|CL_VT220)
+#define TM_VTXXX       (TM_VT220|CL_VT340TEXT|CL_VT510|CL_VT420|CL_VT320)
+#define TM_SCOANSI     (CL_ANSIMIN|CL_SCOANSI)
+
+#define TM_PUTTY       (0xFFFF)
+
+#define compatibility(x) \
+    if ( ((CL_##x)&term->compatibility_level) == 0 ) {         \
+       term->termstate=TOPLEVEL;                       \
+       break;                                          \
+    }
+#define compatibility2(x,y) \
+    if ( ((CL_##x|CL_##y)&term->compatibility_level) == 0 ) { \
+       term->termstate=TOPLEVEL;                       \
+       break;                                          \
+    }
+
+#define has_compat(x) ( ((CL_##x)&term->compatibility_level) != 0 )
+
+const char sco2ansicolour[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+
+#define sel_nl_sz  (sizeof(sel_nl)/sizeof(wchar_t))
+const wchar_t sel_nl[] = SEL_NL;
+
+/*
+ * Fetch the character at a particular position in a line array,
+ * for purposes of `wordtype'. The reason this isn't just a simple
+ * array reference is that if the character we find is UCSWIDE,
+ * then we must look one space further to the left.
+ */
+#define UCSGET(a, x) \
+    ( (x)>0 && ((a)[(x)] & (CHAR_MASK | CSET_MASK)) == UCSWIDE ? \
+       (a)[(x)-1] : (a)[(x)] )
+
+/*
+ * Internal prototypes.
+ */
+static unsigned long *resizeline(unsigned long *, int);
+static int sblines(Terminal *term);
+static unsigned long *lineptr(Terminal *, int, int);
+static void power_on(Terminal *term);
+static int find_last_nonempty_line(Terminal * term, tree234 * screen);
+static void swap_screen(Terminal *term, int which, int reset, int keep_cur_pos);
+static void update_sbar(Terminal *term);
+static void check_selection(Terminal *term, pos from, pos to);
+static void scroll(Terminal *term, int topline, int botline, int lines, int sb);
+#ifdef OPTIMISE_SCROLL
+static void save_scroll(Terminal *term, int topline, int botline, int lines);
+static void scroll_display(Terminal *term, int topline, int botline, int lines);
+#endif
+static void move(Terminal *term, int x, int y, int marg_clip);
+static void save_cursor(Terminal *term, int save);
+static void check_boundary(Terminal *term, int x, int y);
+static void erase_lots(Terminal *term, int line_only, int from_begin, int to_end);
+static void insch(Terminal *term, int n);
+static void toggle_mode(Terminal *term, int mode, int query, int state);
+static void do_osc(Terminal *term);
+static void term_print_setup(Terminal *term);
+static void term_print_flush(Terminal *term);
+static void term_print_finish(Terminal *term);
+static void do_paint(Terminal *term, Context ctx, int may_optimise);
+static void clipme(Terminal *term, pos top, pos bottom, int rect, int desel);
+static int wordtype(Terminal *term, uint32_t uc) /* NOT*/;
+static pos sel_spread_half(Terminal *term, pos p, int dir);
+static void sel_spread(Terminal *term);
+static void deselect(Terminal *term);
+
+/*
+ * Resize a line to make it `cols' columns wide.
+ */
+static unsigned long *resizeline(unsigned long *line, int cols)
+{
+    int i, oldlen;
+    unsigned long lineattrs;
+
+    if (line[0] != (unsigned long)cols) {
+       /*
+        * This line is the wrong length, which probably means it
+        * hasn't been accessed since a resize. Resize it now.
+        */
+       oldlen = line[0];
+       lineattrs = line[oldlen + 1];
+       line = sresize(line, 2 + cols, TTYPE);
+       line[0] = cols;
+       for (i = oldlen; i < cols; i++)
+           line[i + 1] = ERASE_CHAR;
+       line[cols + 1] = lineattrs & LATTR_MODE;
+    }
+
+    return line;
+}
+
+/*
+ * Get the number of lines in the scrollback.
+ */
+static int sblines(Terminal *term)
+{
+    int count = count234(term->scrollback);
+    if (term->cfg.erase_to_scrollback &&
+       term->alt_which && term->alt_screen) {
+           count += term->alt_sblines;
+    }
+    return count;
+}
+
+/*
+ * Retrieve a line of the screen or of the scrollback, according to
+ * whether the y coordinate is non-negative or negative
+ * (respectively).
+ */
+static unsigned long *lineptr(Terminal *term, int y, int lineno)
+{
+    unsigned long *line, *newline;
+    tree234 *whichtree;
+    int treeindex;
+
+    if (y >= 0) {
+       whichtree = term->screen;
+       treeindex = y;
+    } else {
+       int altlines = 0;
+       if (term->cfg.erase_to_scrollback &&
+           term->alt_which && term->alt_screen) {
+           altlines = term->alt_sblines;
+       }
+       if (y < -altlines) {
+           whichtree = term->scrollback;
+           treeindex = y + altlines + count234(term->scrollback);
+       } else {
+           whichtree = term->alt_screen;
+           treeindex = y + term->alt_sblines;
+           /* treeindex = y + count234(term->alt_screen); */
+       }
+    }
+    line = index234(whichtree, treeindex);
+
+    /* We assume that we don't screw up and retrieve something out of range. */
+    assert(line != NULL);
+
+    newline = resizeline(line, term->cols);
+    if (newline != line) {
+       delpos234(whichtree, treeindex);
+       addpos234(whichtree, newline, treeindex);
+        line = newline;
+    }
+
+    return line + 1;
+}
+
+#define lineptr(x) lineptr(term,x,__LINE__)
+
+/*
+ * Set up power-on settings for the terminal.
+ */
+static void power_on(Terminal *term)
+{
+    term->curs.x = term->curs.y = 0;
+    term->alt_x = term->alt_y = 0;
+    term->savecurs.x = term->savecurs.y = 0;
+    term->alt_t = term->marg_t = 0;
+    if (term->rows != -1)
+       term->alt_b = term->marg_b = term->rows - 1;
+    else
+       term->alt_b = term->marg_b = 0;
+    if (term->cols != -1) {
+       int i;
+       for (i = 0; i < term->cols; i++)
+           term->tabs[i] = (i % 8 == 0 ? TRUE : FALSE);
+    }
+    term->alt_om = term->dec_om = term->cfg.dec_om;
+    term->alt_ins = term->insert = FALSE;
+    term->alt_wnext = term->wrapnext = term->save_wnext = FALSE;
+    term->alt_wrap = term->wrap = term->cfg.wrap_mode;
+    term->alt_cset = term->cset = term->save_cset = 0;
+    term->alt_utf = term->utf = term->save_utf = 0;
+    term->utf_state = 0;
+    term->alt_sco_acs = term->sco_acs = term->save_sco_acs = 0;
+    term->cset_attr[0] = term->cset_attr[1] = term->save_csattr = ATTR_ASCII;
+    term->rvideo = 0;
+    term->in_vbell = FALSE;
+    term->cursor_on = 1;
+    term->big_cursor = 0;
+    term->default_attr = term->save_attr = term->curr_attr = ATTR_DEFAULT;
+    term->term_editing = term->term_echoing = FALSE;
+    term->app_cursor_keys = term->cfg.app_cursor;
+    term->app_keypad_keys = term->cfg.app_keypad;
+    term->use_bce = term->cfg.bce;
+    term->blink_is_real = term->cfg.blinktext;
+    term->erase_char = ERASE_CHAR;
+    term->alt_which = 0;
+    term_print_finish(term);
+    {
+       int i;
+       for (i = 0; i < 256; i++)
+           term->wordness[i] = term->cfg.wordness[i];
+    }
+    if (term->screen) {
+       swap_screen(term, 1, FALSE, FALSE);
+       erase_lots(term, FALSE, TRUE, TRUE);
+       swap_screen(term, 0, FALSE, FALSE);
+       erase_lots(term, FALSE, TRUE, TRUE);
+    }
+}
+
+/*
+ * Force a screen update.
+ */
+void term_update(Terminal *term)
+{
+    Context ctx;
+    ctx = get_ctx(term->frontend);
+    if (ctx) {
+       int need_sbar_update = term->seen_disp_event;
+       if (term->seen_disp_event && term->cfg.scroll_on_disp) {
+           term->disptop = 0;         /* return to main screen */
+           term->seen_disp_event = 0;
+           need_sbar_update = TRUE;
+       }
+       if (need_sbar_update)
+           update_sbar(term);
+       do_paint(term, ctx, TRUE);
+       sys_cursor(term->frontend, term->curs.x, term->curs.y - term->disptop);
+       free_ctx(ctx);
+    }
+}
+
+/*
+ * Called from front end when a keypress occurs, to trigger
+ * anything magical that needs to happen in that situation.
+ */
+void term_seen_key_event(Terminal *term)
+{
+    /*
+     * On any keypress, clear the bell overload mechanism
+     * completely, on the grounds that large numbers of
+     * beeps coming from deliberate key action are likely
+     * to be intended (e.g. beeps from filename completion
+     * blocking repeatedly).
+     */
+    term->beep_overloaded = FALSE;
+    while (term->beephead) {
+       struct beeptime *tmp = term->beephead;
+       term->beephead = tmp->next;
+       sfree(tmp);
+    }
+    term->beeptail = NULL;
+    term->nbeeps = 0;
+
+    /*
+     * Reset the scrollback on keypress, if we're doing that.
+     */
+    if (term->cfg.scroll_on_key) {
+       term->disptop = 0;             /* return to main screen */
+       term->seen_disp_event = 1;
+    }
+}
+
+/*
+ * Same as power_on(), but an external function.
+ */
+void term_pwron(Terminal *term)
+{
+    power_on(term);
+    if (term->ldisc)                  /* cause ldisc to notice changes */
+       ldisc_send(term->ldisc, NULL, 0, 0);
+    fix_cpos;
+    term->disptop = 0;
+    deselect(term);
+    term_update(term);
+}
+
+/*
+ * When the user reconfigures us, we need to check the forbidden-
+ * alternate-screen config option, disable raw mouse mode if the
+ * user has disabled mouse reporting, and abandon a print job if
+ * the user has disabled printing.
+ */
+void term_reconfig(Terminal *term, Config *cfg)
+{
+    /*
+     * Before adopting the new config, check all those terminal
+     * settings which control power-on defaults; and if they've
+     * changed, we will modify the current state as well as the
+     * default one. The full list is: Auto wrap mode, DEC Origin
+     * Mode, BCE, blinking text, character classes.
+     */
+    int reset_wrap, reset_decom, reset_bce, reset_blink, reset_charclass;
+    unsigned int i;
+
+    reset_wrap = (term->cfg.wrap_mode != cfg->wrap_mode);
+    reset_decom = (term->cfg.dec_om != cfg->dec_om);
+    reset_bce = (term->cfg.bce != cfg->bce);
+    reset_blink = (term->cfg.blinktext != cfg->blinktext);
+    reset_charclass = 0;
+    for (i = 0; i < lenof(term->cfg.wordness); i++)
+       if (term->cfg.wordness[i] != cfg->wordness[i])
+           reset_charclass = 1;
+
+    term->cfg = *cfg;                 /* STRUCTURE COPY */
+
+    if (reset_wrap)
+       term->alt_wrap = term->wrap = term->cfg.wrap_mode;
+    if (reset_decom)
+       term->alt_om = term->dec_om = term->cfg.dec_om;
+    if (reset_bce) {
+       term->use_bce = term->cfg.bce;
+       if (term->use_bce)
+           term->erase_char = (' ' | ATTR_ASCII |
+                               (term->curr_attr &
+                                (ATTR_FGMASK | ATTR_BGMASK)));
+       else
+           term->erase_char = ERASE_CHAR;
+    }
+    if (reset_blink)
+       term->blink_is_real = term->cfg.blinktext;
+    if (reset_charclass)
+       for (i = 0; i < 256; i++)
+           term->wordness[i] = term->cfg.wordness[i];
+
+    if (term->cfg.no_alt_screen)
+       swap_screen(term, 0, FALSE, FALSE);
+    if (term->cfg.no_mouse_rep) {
+       term->xterm_mouse = 0;
+       set_raw_mouse_mode(term->frontend, 0);
+    }
+    if (term->cfg.no_remote_charset) {
+       term->cset_attr[0] = term->cset_attr[1] = ATTR_ASCII;
+       term->sco_acs = term->alt_sco_acs = 0;
+       term->utf = 0;
+    }
+    if (!*term->cfg.printer) {
+       term_print_finish(term);
+    }
+}
+
+/*
+ * Clear the scrollback.
+ */
+void term_clrsb(Terminal *term)
+{
+    unsigned long *line;
+    term->disptop = 0;
+    while ((line = delpos234(term->scrollback, 0)) != NULL) {
+       sfree(line);
+    }
+    term->tempsblines = 0;
+    term->alt_sblines = 0;
+    update_sbar(term);
+}
+
+/*
+ * Initialise the terminal.
+ */
+Terminal *term_init(Config *mycfg, struct unicode_data *ucsdata,
+                   void *frontend)
+{
+    Terminal *term;
+
+    /*
+     * Allocate a new Terminal structure and initialise the fields
+     * that need it.
+     */
+    term = snew(Terminal);
+    term->frontend = frontend;
+    term->ucsdata = ucsdata;
+    term->cfg = *mycfg;                       /* STRUCTURE COPY */
+    term->logctx = NULL;
+    term->compatibility_level = TM_PUTTY;
+    strcpy(term->id_string, "\033[?6c");
+    term->last_blink = term->last_tblink = 0;
+    term->paste_buffer = NULL;
+    term->paste_len = 0;
+    term->last_paste = 0;
+    bufchain_init(&term->inbuf);
+    bufchain_init(&term->printer_buf);
+    term->printing = term->only_printing = FALSE;
+    term->print_job = NULL;
+    term->vt52_mode = FALSE;
+    term->cr_lf_return = FALSE;
+    term->seen_disp_event = FALSE;
+    term->xterm_mouse = term->mouse_is_down = FALSE;
+    term->reset_132 = FALSE;
+    term->blinker = term->tblinker = 0;
+    term->has_focus = 1;
+    term->repeat_off = FALSE;
+    term->termstate = TOPLEVEL;
+    term->selstate = NO_SELECTION;
+    term->curstype = 0;
+
+    term->screen = term->alt_screen = term->scrollback = NULL;
+    term->tempsblines = 0;
+    term->alt_sblines = 0;
+    term->disptop = 0;
+    term->disptext = term->dispcurs = NULL;
+    term->tabs = NULL;
+    deselect(term);
+    term->rows = term->cols = -1;
+    power_on(term);
+    term->beephead = term->beeptail = NULL;
+#ifdef OPTIMISE_SCROLL
+    term->scrollhead = term->scrolltail = NULL;
+#endif /* OPTIMISE_SCROLL */
+    term->nbeeps = 0;
+    term->lastbeep = FALSE;
+    term->beep_overloaded = FALSE;
+    term->attr_mask = 0xffffffff;
+    term->resize_fn = NULL;
+    term->resize_ctx = NULL;
+    term->in_term_out = FALSE;
+
+    return term;
+}
+
+void term_free(Terminal *term)
+{
+    unsigned long *line;
+
+    while ((line = delpos234(term->scrollback, 0)) != NULL)
+       sfree(line);
+    freetree234(term->scrollback);
+    while ((line = delpos234(term->screen, 0)) != NULL)
+       sfree(line);
+    freetree234(term->screen);
+    while ((line = delpos234(term->alt_screen, 0)) != NULL)
+       sfree(line);
+    freetree234(term->alt_screen);
+    sfree(term->disptext);
+    while (term->beephead) {
+       struct beeptime *b = term->beephead;
+       term->beephead = b->next;
+       sfree(b);
+    }
+    bufchain_clear(&term->inbuf);
+    if(term->print_job)
+       printer_finish_job(term->print_job);
+    bufchain_clear(&term->printer_buf);
+    sfree(term->paste_buffer);
+    sfree(term);
+}
+
+/*
+ * Set up the terminal for a given size.
+ */
+void term_size(Terminal *term, int newrows, int newcols, int newsavelines)
+{
+    tree234 *newalt;
+    unsigned long *newdisp, *line;
+    int i, j;
+    int sblen;
+    int save_alt_which = term->alt_which;
+
+    if (newrows == term->rows && newcols == term->cols &&
+       newsavelines == term->savelines)
+       return;                        /* nothing to do */
+
+    deselect(term);
+    swap_screen(term, 0, FALSE, FALSE);
+
+    term->alt_t = term->marg_t = 0;
+    term->alt_b = term->marg_b = newrows - 1;
+
+    if (term->rows == -1) {
+       term->scrollback = newtree234(NULL);
+       term->screen = newtree234(NULL);
+       term->tempsblines = 0;
+       term->rows = 0;
+    }
+
+    /*
+     * Resize the screen and scrollback. We only need to shift
+     * lines around within our data structures, because lineptr()
+     * will take care of resizing each individual line if
+     * necessary. So:
+     * 
+     *  - If the new screen is longer, we shunt lines in from temporary
+     *    scrollback if possible, otherwise we add new blank lines at
+     *    the bottom.
+     *
+     *  - If the new screen is shorter, we remove any blank lines at
+     *    the bottom if possible, otherwise shunt lines above the cursor
+     *    to scrollback if possible, otherwise delete lines below the
+     *    cursor.
+     * 
+     *  - Then, if the new scrollback length is less than the
+     *    amount of scrollback we actually have, we must throw some
+     *    away.
+     */
+    sblen = count234(term->scrollback);
+    /* Do this loop to expand the screen if newrows > rows */
+    assert(term->rows == count234(term->screen));
+    while (term->rows < newrows) {
+       if (term->tempsblines > 0) {
+           /* Insert a line from the scrollback at the top of the screen. */
+           assert(sblen >= term->tempsblines);
+           line = delpos234(term->scrollback, --sblen);
+           term->tempsblines -= 1;
+           addpos234(term->screen, line, 0);
+           term->curs.y += 1;
+           term->savecurs.y += 1;
+       } else {
+           /* Add a new blank line at the bottom of the screen. */
+           line = snewn(newcols + 2, TTYPE);
+           line[0] = newcols;
+           for (j = 0; j < newcols; j++)
+               line[j + 1] = ERASE_CHAR;
+            line[newcols + 1] = LATTR_NORM;
+           addpos234(term->screen, line, count234(term->screen));
+       }
+       term->rows += 1;
+    }
+    /* Do this loop to shrink the screen if newrows < rows */
+    while (term->rows > newrows) {
+       if (term->curs.y < term->rows - 1) {
+           /* delete bottom row, unless it contains the cursor */
+           sfree(delpos234(term->screen, term->rows - 1));
+       } else {
+           /* push top row to scrollback */
+           line = delpos234(term->screen, 0);
+           addpos234(term->scrollback, line, sblen++);
+           term->tempsblines += 1;
+           term->curs.y -= 1;
+           term->savecurs.y -= 1;
+       }
+       term->rows -= 1;
+    }
+    assert(term->rows == newrows);
+    assert(count234(term->screen) == newrows);
+
+    /* Delete any excess lines from the scrollback. */
+    while (sblen > newsavelines) {
+       line = delpos234(term->scrollback, 0);
+       sfree(line);
+       sblen--;
+    }
+    if (sblen < term->tempsblines)
+       term->tempsblines = sblen;
+    assert(count234(term->scrollback) <= newsavelines);
+    assert(count234(term->scrollback) >= term->tempsblines);
+    term->disptop = 0;
+
+    /* Make a new displayed text buffer. */
+    newdisp = snewn(newrows * (newcols + 1), TTYPE);
+    for (i = 0; i < newrows * (newcols + 1); i++)
+       newdisp[i] = ATTR_INVALID;
+    sfree(term->disptext);
+    term->disptext = newdisp;
+    term->dispcurs = NULL;
+
+    /* Make a new alternate screen. */
+    newalt = newtree234(NULL);
+    for (i = 0; i < newrows; i++) {
+       line = snewn(newcols + 2, TTYPE);
+       line[0] = newcols;
+       for (j = 0; j < newcols; j++)
+           line[j + 1] = term->erase_char;
+        line[newcols + 1] = LATTR_NORM;
+       addpos234(newalt, line, i);
+    }
+    if (term->alt_screen) {
+       while (NULL != (line = delpos234(term->alt_screen, 0)))
+           sfree(line);
+       freetree234(term->alt_screen);
+    }
+    term->alt_screen = newalt;
+    term->alt_sblines = 0;
+
+    term->tabs = sresize(term->tabs, newcols, unsigned char);
+    for (i = (term->cols > 0 ? term->cols : 0); i < newcols; i++)
+       term->tabs[i] = (i % 8 == 0 ? TRUE : FALSE);
+
+    /* Check that the cursor positions are still valid. */
+    if (term->savecurs.y < 0)
+       term->savecurs.y = 0;
+    if (term->savecurs.y >= newrows)
+       term->savecurs.y = newrows - 1;
+    if (term->curs.y < 0)
+       term->curs.y = 0;
+    if (term->curs.y >= newrows)
+       term->curs.y = newrows - 1;
+    if (term->curs.x >= newcols)
+       term->curs.x = newcols - 1;
+    term->alt_x = term->alt_y = 0;
+    term->wrapnext = term->alt_wnext = FALSE;
+
+    term->rows = newrows;
+    term->cols = newcols;
+    term->savelines = newsavelines;
+    fix_cpos;
+
+    swap_screen(term, save_alt_which, FALSE, FALSE);
+
+    update_sbar(term);
+    term_update(term);
+    if (term->resize_fn)
+       term->resize_fn(term->resize_ctx, term->cols, term->rows);
+}
+
+/*
+ * Hand a function and context pointer to the terminal which it can
+ * use to notify a back end of resizes.
+ */
+void term_provide_resize_fn(Terminal *term,
+                           void (*resize_fn)(void *, int, int),
+                           void *resize_ctx)
+{
+    term->resize_fn = resize_fn;
+    term->resize_ctx = resize_ctx;
+    if (term->cols > 0 && term->rows > 0)
+       resize_fn(resize_ctx, term->cols, term->rows);
+}
+
+/* Find the bottom line on the screen that has any content.
+ * If only the top line has content, returns 0.
+ * If no lines have content, return -1.
+ */ 
+static int find_last_nonempty_line(Terminal * term, tree234 * screen)
+{
+    int i;
+    for (i = count234(screen) - 1; i >= 0; i--) {
+       unsigned long *line = index234(screen, i);
+       int j;
+       int cols = line[0];
+       for (j = 0; j < cols; j++) {
+           if (line[j + 1] != term->erase_char) break;
+       }
+       if (j != cols) break;
+    }
+    return i;
+}
+
+/*
+ * Swap screens. If `reset' is TRUE and we have been asked to
+ * switch to the alternate screen, we must bring most of its
+ * configuration from the main screen and erase the contents of the
+ * alternate screen completely. (This is even true if we're already
+ * on it! Blame xterm.)
+ */
+static void swap_screen(Terminal *term, int which, int reset, int keep_cur_pos)
+{
+    int t;
+    tree234 *ttr;
+
+    if (!which)
+       reset = FALSE;                 /* do no weird resetting if which==0 */
+
+    if (which != term->alt_which) {
+       term->alt_which = which;
+
+       ttr = term->alt_screen;
+       term->alt_screen = term->screen;
+       term->screen = ttr;
+       term->alt_sblines = find_last_nonempty_line(term, term->alt_screen) + 1;
+       t = term->curs.x;
+       if (!reset && !keep_cur_pos)
+           term->curs.x = term->alt_x;
+       term->alt_x = t;
+       t = term->curs.y;
+       if (!reset && !keep_cur_pos)
+           term->curs.y = term->alt_y;
+       term->alt_y = t;
+       t = term->marg_t;
+       if (!reset) term->marg_t = term->alt_t;
+       term->alt_t = t;
+       t = term->marg_b;
+       if (!reset) term->marg_b = term->alt_b;
+       term->alt_b = t;
+       t = term->dec_om;
+       if (!reset) term->dec_om = term->alt_om;
+       term->alt_om = t;
+       t = term->wrap;
+       if (!reset) term->wrap = term->alt_wrap;
+       term->alt_wrap = t;
+       t = term->wrapnext;
+       if (!reset) term->wrapnext = term->alt_wnext;
+       term->alt_wnext = t;
+       t = term->insert;
+       if (!reset) term->insert = term->alt_ins;
+       term->alt_ins = t;
+       t = term->cset;
+       if (!reset) term->cset = term->alt_cset;
+       term->alt_cset = t;
+       t = term->utf;
+       if (!reset) term->utf = term->alt_utf;
+       term->alt_utf = t;
+       t = term->sco_acs;
+       if (!reset) term->sco_acs = term->alt_sco_acs;
+       term->alt_sco_acs = t;
+    }
+
+    if (reset && term->screen) {
+       /*
+        * Yes, this _is_ supposed to honour background-colour-erase.
+        */
+       erase_lots(term, FALSE, TRUE, TRUE);
+    }
+
+    /*
+     * This might not be possible if we're called during
+     * initialisation.
+     */
+    if (term->screen)
+       fix_cpos;
+}
+
+/*
+ * Update the scroll bar.
+ */
+static void update_sbar(Terminal *term)
+{
+    int nscroll = sblines(term);
+    set_sbar(term->frontend, nscroll + term->rows,
+            nscroll + term->disptop, term->rows);
+}
+
+/*
+ * Check whether the region bounded by the two pointers intersects
+ * the scroll region, and de-select the on-screen selection if so.
+ */
+static void check_selection(Terminal *term, pos from, pos to)
+{
+    if (poslt(from, term->selend) && poslt(term->selstart, to))
+       deselect(term);
+}
+
+/*
+ * Scroll the screen. (`lines' is +ve for scrolling forward, -ve
+ * for backward.) `sb' is TRUE if the scrolling is permitted to
+ * affect the scrollback buffer.
+ * 
+ * NB this function invalidates all pointers into lines of the
+ * screen data structures. In particular, you MUST call fix_cpos
+ * after calling scroll() and before doing anything else that
+ * uses the cpos shortcut pointer.
+ */
+static void scroll(Terminal *term, int topline, int botline, int lines, int sb)
+{
+    unsigned long *line, *line2;
+    int i, seltop, olddisptop, shift;
+
+    if (topline != 0 || term->alt_which != 0)
+       sb = FALSE;
+
+    olddisptop = term->disptop;
+    shift = lines;
+    if (lines < 0) {
+       while (lines < 0) {
+           line = delpos234(term->screen, botline);
+            line = resizeline(line, term->cols);
+           for (i = 0; i < term->cols; i++)
+               line[i + 1] = term->erase_char;
+           line[term->cols + 1] = 0;
+           addpos234(term->screen, line, topline);
+
+           if (term->selstart.y >= topline && term->selstart.y <= botline) {
+               term->selstart.y++;
+               if (term->selstart.y > botline) {
+                   term->selstart.y = botline + 1;
+                   term->selstart.x = 0;
+               }
+           }
+           if (term->selend.y >= topline && term->selend.y <= botline) {
+               term->selend.y++;
+               if (term->selend.y > botline) {
+                   term->selend.y = botline + 1;
+                   term->selend.x = 0;
+               }
+           }
+
+           lines++;
+       }
+    } else {
+       while (lines > 0) {
+           line = delpos234(term->screen, topline);
+           if (sb && term->savelines > 0) {
+               int sblen = count234(term->scrollback);
+               /*
+                * We must add this line to the scrollback. We'll
+                * remove a line from the top of the scrollback to
+                * replace it, or allocate a new one if the
+                * scrollback isn't full.
+                */
+               if (sblen == term->savelines) {
+                   sblen--, line2 = delpos234(term->scrollback, 0);
+               } else {
+                   line2 = snewn(term->cols + 2, TTYPE);
+                   line2[0] = term->cols;
+                   term->tempsblines += 1;
+               }
+               addpos234(term->scrollback, line, sblen);
+               line = line2;
+
+               /*
+                * If the user is currently looking at part of the
+                * scrollback, and they haven't enabled any options
+                * that are going to reset the scrollback as a
+                * result of this movement, then the chances are
+                * they'd like to keep looking at the same line. So
+                * we move their viewpoint at the same rate as the
+                * scroll, at least until their viewpoint hits the
+                * top end of the scrollback buffer, at which point
+                * we don't have the choice any more.
+                * 
+                * Thanks to Jan Holmen Holsten for the idea and
+                * initial implementation.
+                */
+               if (term->disptop > -term->savelines && term->disptop < 0)
+                   term->disptop--;
+           }
+            line = resizeline(line, term->cols);
+           for (i = 0; i < term->cols; i++)
+               line[i + 1] = term->erase_char;
+           line[term->cols + 1] = LATTR_NORM;
+           addpos234(term->screen, line, botline);
+
+           /*
+            * If the selection endpoints move into the scrollback,
+            * we keep them moving until they hit the top. However,
+            * of course, if the line _hasn't_ moved into the
+            * scrollback then we don't do this, and cut them off
+            * at the top of the scroll region.
+            * 
+            * This applies to selstart and selend (for an existing
+            * selection), and also selanchor (for one being
+            * selected as we speak).
+            */
+           seltop = sb ? -term->savelines : topline;
+
+           if (term->selstate != NO_SELECTION) {
+               if (term->selstart.y >= seltop &&
+                   term->selstart.y <= botline) {
+                   term->selstart.y--;
+                   if (term->selstart.y < seltop) {
+                       term->selstart.y = seltop;
+                       term->selstart.x = 0;
+                   }
+               }
+               if (term->selend.y >= seltop && term->selend.y <= botline) {
+                   term->selend.y--;
+                   if (term->selend.y < seltop) {
+                       term->selend.y = seltop;
+                       term->selend.x = 0;
+                   }
+               }
+               if (term->selanchor.y >= seltop &&
+                   term->selanchor.y <= botline) {
+                   term->selanchor.y--;
+                   if (term->selanchor.y < seltop) {
+                       term->selanchor.y = seltop;
+                       term->selanchor.x = 0;
+                   }
+               }
+           }
+
+           lines--;
+       }
+    }
+#ifdef OPTIMISE_SCROLL
+    shift += term->disptop - olddisptop;
+    if (shift < term->rows && shift > -term->rows && shift != 0)
+       scroll_display(term, topline, botline, shift);
+#endif /* OPTIMISE_SCROLL */
+}
+
+#ifdef OPTIMISE_SCROLL
+/*
+ * Add a scroll of a region on the screen into the pending scroll list.
+ * `lines' is +ve for scrolling forward, -ve for backward.
+ *
+ * If the scroll is on the same area as the last scroll in the list,
+ * merge them.
+ */
+static void save_scroll(Terminal *term, int topline, int botline, int lines)
+{
+    struct scrollregion *newscroll;
+    if (term->scrolltail &&
+       term->scrolltail->topline == topline && 
+       term->scrolltail->botline == botline) {
+       term->scrolltail->lines += lines;
+    } else {
+       newscroll = snew(struct scrollregion);
+       newscroll->topline = topline;
+       newscroll->botline = botline;
+       newscroll->lines = lines;
+       newscroll->next = NULL;
+
+       if (!term->scrollhead)
+           term->scrollhead = newscroll;
+       else
+           term->scrolltail->next = newscroll;
+       term->scrolltail = newscroll;
+    }
+}
+
+/*
+ * Scroll the physical display, and our conception of it in disptext.
+ */
+static void scroll_display(Terminal *term, int topline, int botline, int lines)
+{
+    unsigned long *start, *end;
+    int distance, size, i;
+
+    start = term->disptext + topline * (term->cols + 1);
+    end = term->disptext + (botline + 1) * (term->cols + 1);
+    distance = (lines > 0 ? lines : -lines) * (term->cols + 1);
+    size = end - start - distance;
+    if (lines > 0) {
+       memmove(start, start + distance, size * TSIZE);
+       if (term->dispcurs >= start + distance &&
+           term->dispcurs <= start + distance + size)
+           term->dispcurs -= distance;
+       for (i = 0; i < distance; i++)
+           (start + size)[i] |= ATTR_INVALID;
+    } else {
+       memmove(start + distance, start, size * TSIZE);
+       if (term->dispcurs >= start && term->dispcurs <= start + size)
+           term->dispcurs += distance;
+       for (i = 0; i < distance; i++)
+           start[i] |= ATTR_INVALID;
+    }
+    save_scroll(term, topline, botline, lines);
+}
+#endif /* OPTIMISE_SCROLL */
+
+/*
+ * Move the cursor to a given position, clipping at boundaries. We
+ * may or may not want to clip at the scroll margin: marg_clip is 0
+ * not to, 1 to disallow _passing_ the margins, and 2 to disallow
+ * even _being_ outside the margins.
+ */
+static void move(Terminal *term, int x, int y, int marg_clip)
+{
+    if (x < 0)
+       x = 0;
+    if (x >= term->cols)
+       x = term->cols - 1;
+    if (marg_clip) {
+       if ((term->curs.y >= term->marg_t || marg_clip == 2) &&
+           y < term->marg_t)
+           y = term->marg_t;
+       if ((term->curs.y <= term->marg_b || marg_clip == 2) &&
+           y > term->marg_b)
+           y = term->marg_b;
+    }
+    if (y < 0)
+       y = 0;
+    if (y >= term->rows)
+       y = term->rows - 1;
+    term->curs.x = x;
+    term->curs.y = y;
+    fix_cpos;
+    term->wrapnext = FALSE;
+}
+
+/*
+ * Save or restore the cursor and SGR mode.
+ */
+static void save_cursor(Terminal *term, int save)
+{
+    if (save) {
+       term->savecurs = term->curs;
+       term->save_attr = term->curr_attr;
+       term->save_cset = term->cset;
+       term->save_utf = term->utf;
+       term->save_wnext = term->wrapnext;
+       term->save_csattr = term->cset_attr[term->cset];
+       term->save_sco_acs = term->sco_acs;
+    } else {
+       term->curs = term->savecurs;
+       /* Make sure the window hasn't shrunk since the save */
+       if (term->curs.x >= term->cols)
+           term->curs.x = term->cols - 1;
+       if (term->curs.y >= term->rows)
+           term->curs.y = term->rows - 1;
+
+       term->curr_attr = term->save_attr;
+       term->cset = term->save_cset;
+       term->utf = term->save_utf;
+       term->wrapnext = term->save_wnext;
+       /*
+        * wrapnext might reset to False if the x position is no
+        * longer at the rightmost edge.
+        */
+       if (term->wrapnext && term->curs.x < term->cols-1)
+           term->wrapnext = FALSE;
+       term->cset_attr[term->cset] = term->save_csattr;
+       term->sco_acs = term->save_sco_acs;
+       fix_cpos;
+       if (term->use_bce)
+           term->erase_char = (' ' | ATTR_ASCII |
+                               (term->curr_attr &
+                                (ATTR_FGMASK | ATTR_BGMASK)));
+    }
+}
+
+/*
+ * This function is called before doing _anything_ which affects
+ * only part of a line of text. It is used to mark the boundary
+ * between two character positions, and it indicates that some sort
+ * of effect is going to happen on only one side of that boundary.
+ * 
+ * The effect of this function is to check whether a CJK
+ * double-width character is straddling the boundary, and to remove
+ * it and replace it with two spaces if so. (Of course, one or
+ * other of those spaces is then likely to be replaced with
+ * something else again, as a result of whatever happens next.)
+ * 
+ * Also, if the boundary is at the right-hand _edge_ of the screen,
+ * it implies something deliberate is being done to the rightmost
+ * column position; hence we must clear LATTR_WRAPPED2.
+ * 
+ * The input to the function is the coordinates of the _second_
+ * character of the pair.
+ */
+static void check_boundary(Terminal *term, int x, int y)
+{
+    unsigned long *ldata;
+
+    /* Validate input coordinates, just in case. */
+    if (x == 0 || x > term->cols)
+       return;
+
+    ldata = lineptr(y);
+    if (x == term->cols) {
+       ldata[x] &= ~LATTR_WRAPPED2;
+    } else {
+       if ((ldata[x] & (CHAR_MASK | CSET_MASK)) == UCSWIDE) {
+           ldata[x-1] = ldata[x] =
+               (ldata[x-1] &~ (CHAR_MASK | CSET_MASK)) | ATTR_ASCII | ' ';
+       }
+    }
+}
+
+/*
+ * Erase a large portion of the screen: the whole screen, or the
+ * whole line, or parts thereof.
+ */
+static void erase_lots(Terminal *term,
+                      int line_only, int from_begin, int to_end)
+{
+    pos start, end;
+    int erase_lattr;
+    int erasing_lines_from_top = 0;
+
+    if (line_only) {
+       start.y = term->curs.y;
+       start.x = 0;
+       end.y = term->curs.y + 1;
+       end.x = 0;
+       erase_lattr = FALSE;
+    } else {
+       start.y = 0;
+       start.x = 0;
+       end.y = term->rows;
+       end.x = 0;
+       erase_lattr = TRUE;
+    }
+    if (!from_begin) {
+       start = term->curs;
+    }
+    if (!to_end) {
+       end = term->curs;
+       incpos(end);
+    }
+    if (!from_begin || !to_end)
+       check_boundary(term, term->curs.x, term->curs.y);
+    check_selection(term, start, end);
+
+    /* Clear screen also forces a full window redraw, just in case. */
+    if (start.y == 0 && start.x == 0 && end.y == term->rows)
+       term_invalidate(term);
+
+    /* Lines scrolled away shouldn't be brought back on if the terminal
+     * resizes. */
+    if (start.y == 0 && start.x == 0 && end.x == 0 && erase_lattr)
+       erasing_lines_from_top = 1;
+
+    if (term->cfg.erase_to_scrollback && erasing_lines_from_top) {
+       /* If it's a whole number of lines, starting at the top, and
+        * we're fully erasing them, erase by scrolling and keep the
+        * lines in the scrollback. */
+       int scrolllines = end.y;
+       if (end.y == term->rows) {
+           /* Shrink until we find a non-empty row.*/
+           scrolllines = find_last_nonempty_line(term, term->screen) + 1;
+       }
+       if (scrolllines > 0)
+           scroll(term, 0, scrolllines - 1, scrolllines, TRUE);
+       fix_cpos;
+    } else {
+       unsigned long *ldata = lineptr(start.y);
+       while (poslt(start, end)) {
+           if (start.x == term->cols) {
+               if (!erase_lattr)
+                   ldata[start.x] &= ~(LATTR_WRAPPED | LATTR_WRAPPED2);
+               else
+                   ldata[start.x] = LATTR_NORM;
+           } else {
+               ldata[start.x] = term->erase_char;
+           }
+           if (incpos(start) && start.y < term->rows)
+               ldata = lineptr(start.y);
+       }
+    }
+
+    /* After an erase of lines from the top of the screen, we shouldn't
+     * bring the lines back again if the terminal enlarges (since the user or
+     * application has explictly thrown them away). */
+    if (erasing_lines_from_top && !(term->alt_which))
+       term->tempsblines = 0;
+}
+
+/*
+ * Insert or delete characters within the current line. n is +ve if
+ * insertion is desired, and -ve for deletion.
+ */
+static void insch(Terminal *term, int n)
+{
+    int dir = (n < 0 ? -1 : +1);
+    int m;
+    pos cursplus;
+    unsigned long *ldata;
+
+    n = (n < 0 ? -n : n);
+    if (n > term->cols - term->curs.x)
+       n = term->cols - term->curs.x;
+    m = term->cols - term->curs.x - n;
+    cursplus.y = term->curs.y;
+    cursplus.x = term->curs.x + n;
+    check_selection(term, term->curs, cursplus);
+    check_boundary(term, term->curs.x, term->curs.y);
+    if (dir < 0)
+       check_boundary(term, term->curs.x + n, term->curs.y);
+    ldata = lineptr(term->curs.y);
+    if (dir < 0) {
+       memmove(ldata + term->curs.x, ldata + term->curs.x + n, m * TSIZE);
+       while (n--)
+           ldata[term->curs.x + m++] = term->erase_char;
+    } else {
+       memmove(ldata + term->curs.x + n, ldata + term->curs.x, m * TSIZE);
+       while (n--)
+           ldata[term->curs.x + n] = term->erase_char;
+    }
+}
+
+/*
+ * Toggle terminal mode `mode' to state `state'. (`query' indicates
+ * whether the mode is a DEC private one or a normal one.)
+ */
+static void toggle_mode(Terminal *term, int mode, int query, int state)
+{
+    unsigned long ticks;
+
+    if (query)
+       switch (mode) {
+         case 1:                      /* DECCKM: application cursor keys */
+           term->app_cursor_keys = state;
+           break;
+         case 2:                      /* DECANM: VT52 mode */
+           term->vt52_mode = !state;
+           if (term->vt52_mode) {
+               term->blink_is_real = FALSE;
+               term->vt52_bold = FALSE;
+           } else {
+               term->blink_is_real = term->cfg.blinktext;
+           }
+           break;
+         case 3:                      /* DECCOLM: 80/132 columns */
+           deselect(term);
+           if (!term->cfg.no_remote_resize)
+               request_resize(term->frontend, state ? 132 : 80, term->rows);
+           term->reset_132 = state;
+           term->alt_t = term->marg_t = 0;
+           term->alt_b = term->marg_b = term->rows - 1;
+           move(term, 0, 0, 0);
+           erase_lots(term, FALSE, TRUE, TRUE);
+           break;
+         case 5:                      /* DECSCNM: reverse video */
+           /*
+            * Toggle reverse video. If we receive an OFF within the
+            * visual bell timeout period after an ON, we trigger an
+            * effective visual bell, so that ESC[?5hESC[?5l will
+            * always be an actually _visible_ visual bell.
+            */
+           ticks = GETTICKCOUNT();
+           /* turn off a previous vbell to avoid inconsistencies */
+           if (ticks - term->vbell_startpoint >= VBELL_TIMEOUT)
+               term->in_vbell = FALSE;
+           if (term->rvideo && !state &&    /* we're turning it off... */
+               (ticks - term->rvbell_startpoint) < VBELL_TIMEOUT) {/*...soon*/
+               /* If there's no vbell timeout already, or this one lasts
+                * longer, replace vbell_timeout with ours. */
+               if (!term->in_vbell ||
+                   (term->rvbell_startpoint - term->vbell_startpoint <
+                    VBELL_TIMEOUT))
+                   term->vbell_startpoint = term->rvbell_startpoint;
+               term->in_vbell = TRUE; /* may clear rvideo but set in_vbell */
+           } else if (!term->rvideo && state) {
+               /* This is an ON, so we notice the time and save it. */
+               term->rvbell_startpoint = ticks;
+           }
+           term->rvideo = state;
+           term->seen_disp_event = TRUE;
+           if (state)
+               term_update(term);
+           break;
+         case 6:                      /* DECOM: DEC origin mode */
+           term->dec_om = state;
+           break;
+         case 7:                      /* DECAWM: auto wrap */
+           term->wrap = state;
+           break;
+         case 8:                      /* DECARM: auto key repeat */
+           term->repeat_off = !state;
+           break;
+         case 10:                     /* DECEDM: set local edit mode */
+           term->term_editing = state;
+           if (term->ldisc)           /* cause ldisc to notice changes */
+               ldisc_send(term->ldisc, NULL, 0, 0);
+           break;
+         case 25:                     /* DECTCEM: enable/disable cursor */
+           compatibility2(OTHER, VT220);
+           term->cursor_on = state;
+           term->seen_disp_event = TRUE;
+           break;
+         case 47:                     /* alternate screen */
+           compatibility(OTHER);
+           deselect(term);
+           swap_screen(term, term->cfg.no_alt_screen ? 0 : state, FALSE, FALSE);
+           term->disptop = 0;
+           break;
+         case 1000:                   /* xterm mouse 1 */
+           term->xterm_mouse = state ? 1 : 0;
+           set_raw_mouse_mode(term->frontend, state);
+           break;
+         case 1002:                   /* xterm mouse 2 */
+           term->xterm_mouse = state ? 2 : 0;
+           set_raw_mouse_mode(term->frontend, state);
+           break;
+         case 1047:                   /* alternate screen */
+           compatibility(OTHER);
+           deselect(term);
+           swap_screen(term, term->cfg.no_alt_screen ? 0 : state, TRUE, TRUE);
+           term->disptop = 0;
+           break;
+         case 1048:                   /* save/restore cursor */
+           if (!term->cfg.no_alt_screen)
+                save_cursor(term, state);
+           if (!state) term->seen_disp_event = TRUE;
+           break;
+         case 1049:                   /* cursor & alternate screen */
+           if (state && !term->cfg.no_alt_screen)
+               save_cursor(term, state);
+           if (!state) term->seen_disp_event = TRUE;
+           compatibility(OTHER);
+           deselect(term);
+           swap_screen(term, term->cfg.no_alt_screen ? 0 : state, TRUE, FALSE);
+           if (!state && !term->cfg.no_alt_screen)
+               save_cursor(term, state);
+           term->disptop = 0;
+           break;
+    } else
+       switch (mode) {
+         case 4:                      /* IRM: set insert mode */
+           compatibility(VT102);
+           term->insert = state;
+           break;
+         case 12:                     /* SRM: set echo mode */
+           term->term_echoing = !state;
+           if (term->ldisc)           /* cause ldisc to notice changes */
+               ldisc_send(term->ldisc, NULL, 0, 0);
+           break;
+         case 20:                     /* LNM: Return sends ... */
+           term->cr_lf_return = state;
+           break;
+         case 34:                     /* WYULCURM: Make cursor BIG */
+           compatibility2(OTHER, VT220);
+           term->big_cursor = !state;
+       }
+}
+
+/*
+ * Process an OSC sequence: set window title or icon name.
+ */
+static void do_osc(Terminal *term)
+{
+    if (term->osc_w) {
+       while (term->osc_strlen--)
+           term->wordness[(unsigned char)
+               term->osc_string[term->osc_strlen]] = term->esc_args[0];
+    } else {
+       term->osc_string[term->osc_strlen] = '\0';
+       switch (term->esc_args[0]) {
+         case 0:
+         case 1:
+           if (!term->cfg.no_remote_wintitle)
+               set_icon(term->frontend, term->osc_string);
+           if (term->esc_args[0] == 1)
+               break;
+           /* fall through: parameter 0 means set both */
+         case 2:
+         case 21:
+           if (!term->cfg.no_remote_wintitle)
+               set_title(term->frontend, term->osc_string);
+           break;
+       }
+    }
+}
+
+/*
+ * ANSI printing routines.
+ */
+static void term_print_setup(Terminal *term)
+{
+    bufchain_clear(&term->printer_buf);
+    term->print_job = printer_start_job(term->cfg.printer);
+}
+static void term_print_flush(Terminal *term)
+{
+    void *data;
+    size_t len;
+    size_t size;
+    while ((size = bufchain_size(&term->printer_buf)) > 5) {
+       bufchain_prefix(&term->printer_buf, &data, &len);
+       if (len > size-5)
+           len = size-5;
+       printer_job_data(term->print_job, data, len);
+       bufchain_consume(&term->printer_buf, len);
+    }
+}
+static void term_print_finish(Terminal *term)
+{
+    void *data;
+    size_t len, size;
+    char c;
+
+    if (!term->printing && !term->only_printing)
+       return;                        /* we need do nothing */
+
+    term_print_flush(term);
+    while ((size = bufchain_size(&term->printer_buf)) > 0) {
+       bufchain_prefix(&term->printer_buf, &data, &len);
+       c = *(char *)data;
+       if (c == '\033' || c == '\233') {
+           bufchain_consume(&term->printer_buf, size);
+           break;
+       } else {
+           printer_job_data(term->print_job, &c, 1);
+           bufchain_consume(&term->printer_buf, 1);
+       }
+    }
+    printer_finish_job(term->print_job);
+    term->print_job = NULL;
+    term->printing = term->only_printing = FALSE;
+}
+
+/*
+ * Remove everything currently in `inbuf' and stick it up on the
+ * in-memory display. There's a big state machine in here to
+ * process escape sequences...
+ */
+void term_out(Terminal *term)
+{
+    int unget_exists;
+    uint32_t unget_c;
+    uint32_t c;
+    unsigned char localbuf[256], *chars;
+    size_t nchars = 0;
+
+    unget_exists = FALSE;
+    unget_c = 0;
+
+    chars = NULL;                     /* placate compiler warnings */
+    while (nchars > 0 || bufchain_size(&term->inbuf) > 0) {
+       if (!unget_exists) {
+           if (nchars == 0) {
+               void *ret;
+               bufchain_prefix(&term->inbuf, &ret, &nchars);
+               if (nchars > sizeof(localbuf))
+                   nchars = sizeof(localbuf);
+               memcpy(localbuf, ret, nchars);
+               bufchain_consume(&term->inbuf, nchars);
+               chars = localbuf;
+               assert(chars != NULL);
+           }
+           c = *chars++;
+           nchars--;
+       } else {
+           c = unget_c;
+           unget_exists = FALSE;
+       }
+
+       /* Note only VT220+ are 8-bit VT102 is seven bit, it shouldn't even
+        * be able to display 8-bit characters, but I'll let that go 'cause
+        * of i18n.
+        */
+
+       /*
+        * If we're printing, add the character to the printer
+        * buffer.
+        */
+       if (term->printing) {
+           bufchain_add(&term->printer_buf, &c, 1);
+
+           /*
+            * If we're in print-only mode, we use a much simpler
+            * state machine designed only to recognise the ESC[4i
+            * termination sequence.
+            */
+           if (term->only_printing) {
+               if (c == '\033')
+                   term->print_state = 1;
+               else if (c == (unsigned char)'\233')
+                   term->print_state = 2;
+               else if (c == '[' && term->print_state == 1)
+                   term->print_state = 2;
+               else if (c == '4' && term->print_state == 2)
+                   term->print_state = 3;
+               else if (c == 'i' && term->print_state == 3)
+                   term->print_state = 4;
+               else
+                   term->print_state = 0;
+               if (term->print_state == 4) {
+                   term_print_finish(term);
+               }
+               continue;
+           }
+       }
+
+       /* First see about all those translations. */
+       if (term->termstate == TOPLEVEL) {
+           if (in_utf(term))
+               switch (term->utf_state) {
+                 case 0:
+                   if (c < 0x80) {
+                       /* UTF-8 must be stateless so we ignore iso2022. */
+                       if (term->ucsdata->unitab_ctrl[c] != 0xFF) 
+                            c = term->ucsdata->unitab_ctrl[c];
+                       else c = ((unsigned char)c) | ATTR_ASCII;
+                       break;
+                   } else if ((c & 0xe0) == 0xc0) {
+                       term->utf_size = term->utf_state = 1;
+                       term->utf_char = (c & 0x1f);
+                   } else if ((c & 0xf0) == 0xe0) {
+                       term->utf_size = term->utf_state = 2;
+                       term->utf_char = (c & 0x0f);
+                   } else if ((c & 0xf8) == 0xf0) {
+                       term->utf_size = term->utf_state = 3;
+                       term->utf_char = (c & 0x07);
+                   } else if ((c & 0xfc) == 0xf8) {
+                       term->utf_size = term->utf_state = 4;
+                       term->utf_char = (c & 0x03);
+                   } else if ((c & 0xfe) == 0xfc) {
+                       term->utf_size = term->utf_state = 5;
+                       term->utf_char = (c & 0x01);
+                   } else {
+                       c = UCSERR;
+                       break;
+                   }
+                   continue;
+                 case 1:
+                 case 2:
+                 case 3:
+                 case 4:
+                 case 5:
+                   if ((c & 0xC0) != 0x80) {
+                       unget_c = c;
+                        unget_exists = FALSE;
+                       c = UCSERR;
+                       term->utf_state = 0;
+                       break;
+                   }
+                   term->utf_char = (term->utf_char << 6) | (c & 0x3f);
+                   if (--term->utf_state)
+                       continue;
+
+                   c = term->utf_char;
+
+                   /* Is somebody trying to be evil! */
+                   if (c < 0x80 ||
+                       (c < 0x800 && term->utf_size >= 2) ||
+                       (c < 0x10000 && term->utf_size >= 3) ||
+                       (c < 0x200000 && term->utf_size >= 4) ||
+                       (c < 0x4000000 && term->utf_size >= 5))
+                       c = UCSERR;
+
+                   /* Unicode line separator and paragraph separator are CR-LF */
+                   if (c == 0x2028 || c == 0x2029)
+                       c = 0x85;
+
+                   /* High controls are probably a Baaad idea too. */
+                   if (c < 0xA0)
+                       c = 0xFFFD;
+
+                   /* The UTF-16 surrogates are not nice either. */
+                   /*       The standard give the option of decoding these: 
+                    *       I don't want to! */
+                   if (c >= 0xD800 && c < 0xE000)
+                       c = UCSERR;
+
+                   /* ISO 10646 characters now limited to UTF-16 range. */
+                   if (c > 0x10FFFF)
+                       c = UCSERR;
+
+                   /* This is currently a TagPhobic application.. */
+                   if (c >= 0xE0000 && c <= 0xE007F)
+                       continue;
+
+                   /* U+FEFF is best seen as a null. */
+                   if (c == 0xFEFF)
+                       continue;
+                   /* But U+FFFE is an error. */
+                   if (c == 0xFFFE || c == 0xFFFF)
+                       c = UCSERR;
+
+                   /* Oops this is a 16bit implementation */
+                   if (c >= 0x10000)
+                       c = 0xFFFD;
+                   break;
+           }
+           /* Are we in the nasty ACS mode? Note: no sco in utf mode. */
+           else if(term->sco_acs && 
+                   (c!='\033' && c!='\012' && c!='\015' && c!='\b'))
+           {
+              if (term->sco_acs == 2) c |= 0x80;
+              c |= ATTR_SCOACS;
+           } else {
+               switch (term->cset_attr[term->cset]) {
+                   /* 
+                    * Linedraw characters are different from 'ESC ( B'
+                    * only for a small range. For ones outside that
+                    * range, make sure we use the same font as well as
+                    * the same encoding.
+                    */
+                 case ATTR_LINEDRW:
+                      if (term->ucsdata->unitab_ctrl[c] != 0xFF)
+                       c = term->ucsdata->unitab_ctrl[c];
+                      else
+                       c = ((unsigned char) c) | ATTR_LINEDRW;
+                      break;
+
+                 case ATTR_GBCHR:
+                   /* If UK-ASCII, make the '#' a LineDraw Pound */
+                   if (c == '#') {
+                       c = '}' | ATTR_LINEDRW;
+                       break;
+                   }
+                 /*FALLTHROUGH*/ case ATTR_ASCII:
+                   if (term->ucsdata->unitab_ctrl[c] != 0xFF)
+                       c = term->ucsdata->unitab_ctrl[c];
+                   else
+                       c = ((unsigned char) c) | ATTR_ASCII;
+                   break;
+               case ATTR_SCOACS:
+                   if (c>=' ') c = ((unsigned char)c) | ATTR_SCOACS;
+                   break;
+               }
+           }
+       }
+
+       /* How about C1 controls ? */
+       if ((c & 0xffffffe0L) == 0x80 && term->termstate < DO_CTRLS &&
+           !term->vt52_mode && has_compat(VT220)) {
+           term->termstate = SEEN_ESC;
+           term->esc_query = FALSE;
+           c = '@' + (c & 0x1F);
+       }
+
+       /* Or the GL control. */
+       if (c == '\177' && term->termstate < DO_CTRLS && has_compat(OTHER)) {
+           if (term->curs.x && !term->wrapnext)
+               term->curs.x--;
+           term->wrapnext = FALSE;
+           fix_cpos;
+           if (!term->cfg.no_dbackspace)    /* destructive bksp might be disabled */
+               *term->cpos = (' ' | term->curr_attr | ATTR_ASCII);
+       } else
+           /* Or normal C0 controls. */
+       if ((c & 0xffffffe0L) == 0 && term->termstate < DO_CTRLS) {
+           switch (c) {
+             case '\005':             /* ENQ: terminal type query */
+               /* Strictly speaking this is VT100 but a VT100 defaults to
+                * no response. Other terminals respond at their option.
+                *
+                * Don't put a CR in the default string as this tends to
+                * upset some weird software.
+                *
+                * An xterm returns "xterm" (5 characters)
+                */
+               compatibility(ANSIMIN);
+               if (term->ldisc) {
+                   char abuf[256], *s, *d;
+                   int state = 0;
+                   for (s = term->cfg.answerback, d = abuf; *s; s++) {
+                       if (state) {
+                           if (*s >= 'a' && *s <= 'z')
+                               *d++ = (*s - ('a' - 1));
+                           else if ((*s >= '@' && *s <= '_') ||
+                                    *s == '?' || (*s & 0x80))
+                               *d++ = ('@' ^ *s);
+                           else if (*s == '~')
+                               *d++ = '^';
+                           state = 0;
+                       } else if (*s == '^') {
+                           state = 1;
+                       } else
+                           *d++ = *s;
+                   }
+                   lpage_send(term->ldisc, DEFAULT_CODEPAGE,
+                              abuf, d - abuf, 0);
+               }
+               break;
+             case '\007':            /* BEL: Bell */
+               {
+                   struct beeptime *newbeep;
+                   unsigned long ticks;
+
+                   ticks = GETTICKCOUNT();
+
+                   if (!term->beep_overloaded) {
+                       newbeep = snew(struct beeptime);
+                       newbeep->ticks = ticks;
+                       newbeep->next = NULL;
+                       if (!term->beephead)
+                           term->beephead = newbeep;
+                       else
+                           term->beeptail->next = newbeep;
+                       term->beeptail = newbeep;
+                       term->nbeeps++;
+                   }
+
+                   /*
+                    * Throw out any beeps that happened more than
+                    * t seconds ago.
+                    */
+                   while (term->beephead &&
+                          term->beephead->ticks < ticks - term->cfg.bellovl_t) {
+                       struct beeptime *tmp = term->beephead;
+                       term->beephead = tmp->next;
+                       sfree(tmp);
+                       if (!term->beephead)
+                           term->beeptail = NULL;
+                       term->nbeeps--;
+                   }
+
+                   if (term->cfg.bellovl && term->beep_overloaded &&
+                       ticks - term->lastbeep >= (unsigned)term->cfg.bellovl_s) {
+                       /*
+                        * If we're currently overloaded and the
+                        * last beep was more than s seconds ago,
+                        * leave overload mode.
+                        */
+                       term->beep_overloaded = FALSE;
+                   } else if (term->cfg.bellovl && !term->beep_overloaded &&
+                              term->nbeeps >= term->cfg.bellovl_n) {
+                       /*
+                        * Now, if we have n or more beeps
+                        * remaining in the queue, go into overload
+                        * mode.
+                        */
+                       term->beep_overloaded = TRUE;
+                   }
+                   term->lastbeep = ticks;
+
+                   /*
+                    * Perform an actual beep if we're not overloaded.
+                    */
+                   if (!term->cfg.bellovl || !term->beep_overloaded) {
+                       beep(term->frontend, term->cfg.beep);
+                       if (term->cfg.beep & BELL_VISIBLE) {
+                           term->in_vbell = TRUE;
+                           term->vbell_startpoint = ticks;
+                           term_update(term);
+                       }
+                   }
+                   term->seen_disp_event = TRUE;
+               }
+               break;
+             case '\b':              /* BS: Back space */
+               if (term->curs.x == 0 &&
+                   (term->curs.y == 0 || term->wrap == 0))
+                   /* do nothing */ ;
+               else if (term->curs.x == 0 && term->curs.y > 0)
+                   term->curs.x = term->cols - 1, term->curs.y--;
+               else if (term->wrapnext)
+                   term->wrapnext = FALSE;
+               else
+                   term->curs.x--;
+               fix_cpos;
+               term->seen_disp_event = TRUE;
+               break;
+             case '\016':            /* LS1: Locking-shift one */
+               compatibility(VT100);
+               term->cset = 1;
+               break;
+             case '\017':            /* LS0: Locking-shift zero */
+               compatibility(VT100);
+               term->cset = 0;
+               break;
+             case '\033':            /* ESC: Escape */
+               if (term->vt52_mode)
+                   term->termstate = VT52_ESC;
+               else {
+                   compatibility(ANSIMIN);
+                   term->termstate = SEEN_ESC;
+                   term->esc_query = FALSE;
+               }
+               break;
+             case '\015':            /* CR: Carriage return */
+               term->curs.x = 0;
+               term->wrapnext = FALSE;
+               fix_cpos;
+               term->seen_disp_event = TRUE;
+               term->paste_hold = 0;
+               break;
+             case '\014':            /* FF: Form feed */
+               if (has_compat(SCOANSI)) {
+                   move(term, 0, 0, 0);
+                   erase_lots(term, FALSE, FALSE, TRUE);
+                   term->disptop = 0;
+                   term->wrapnext = FALSE;
+                   term->seen_disp_event = 1;
+                   break;
+               }
+             case '\013':            /* VT: Line tabulation */
+               compatibility(VT100);
+             case '\012':            /* LF: Line feed */
+               if (term->curs.y == term->marg_b)
+                   scroll(term, term->marg_t, term->marg_b, 1, TRUE);
+               else if (term->curs.y < term->rows - 1)
+                   term->curs.y++;
+               if (term->cfg.lfhascr)
+                   term->curs.x = 0;
+               fix_cpos;
+               term->wrapnext = FALSE;
+               term->seen_disp_event = 1;
+               term->paste_hold = 0;
+               break;
+             case '\t':              /* HT: Character tabulation */
+               {
+                   pos old_curs = term->curs;
+                   unsigned long *ldata = lineptr(term->curs.y);
+
+                   do {
+                       term->curs.x++;
+                   } while (term->curs.x < term->cols - 1 &&
+                            !term->tabs[term->curs.x]);
+
+                   if ((ldata[term->cols] & LATTR_MODE) != LATTR_NORM) {
+                       if (term->curs.x >= term->cols / 2)
+                           term->curs.x = term->cols / 2 - 1;
+                   } else {
+                       if (term->curs.x >= term->cols)
+                           term->curs.x = term->cols - 1;
+                   }
+
+                   fix_cpos;
+                   check_selection(term, old_curs, term->curs);
+               }
+               term->seen_disp_event = TRUE;
+               break;
+           }
+       } else
+           switch (term->termstate) {
+             case TOPLEVEL:
+               /* Only graphic characters get this far;
+                * ctrls are stripped above */
+               if (term->wrapnext && term->wrap) {
+                   term->cpos[1] |= LATTR_WRAPPED;
+                   if (term->curs.y == term->marg_b)
+                       scroll(term, term->marg_t, term->marg_b, 1, TRUE);
+                   else if (term->curs.y < term->rows - 1)
+                       term->curs.y++;
+                   term->curs.x = 0;
+                   fix_cpos;
+                   term->wrapnext = FALSE;
+               }
+               if (term->insert)
+                   insch(term, 1);
+               if (term->selstate != NO_SELECTION) {
+                   pos cursplus = term->curs;
+                   incpos(cursplus);
+                   check_selection(term, term->curs, cursplus);
+               }
+               {
+                   int width = 0;
+                   if (DIRECT_CHAR(c))
+                       width = 1;
+                   if (!width)
+                       width = wcwidth((wchar_t) c);
+                   switch (width) {
+                     case 2:
+                       /*
+                        * If we're about to display a double-width
+                        * character starting in the rightmost
+                        * column, then we do something special
+                        * instead. We must print a space in the
+                        * last column of the screen, then wrap;
+                        * and we also set LATTR_WRAPPED2 which
+                        * instructs subsequent cut-and-pasting not
+                        * only to splice this line to the one
+                        * after it, but to ignore the space in the
+                        * last character position as well.
+                        * (Because what was actually output to the
+                        * terminal was presumably just a sequence
+                        * of CJK characters, and we don't want a
+                        * space to be pasted in the middle of
+                        * those just because they had the
+                        * misfortune to start in the wrong parity
+                        * column. xterm concurs.)
+                        */
+                       check_boundary(term, term->curs.x, term->curs.y);
+                       check_boundary(term, term->curs.x+2, term->curs.y);
+                       if (term->curs.x == term->cols-1) {
+                           *term->cpos++ = ATTR_ASCII | ' ' | term->curr_attr;
+                           *term->cpos |= LATTR_WRAPPED | LATTR_WRAPPED2;
+                           if (term->curs.y == term->marg_b)
+                               scroll(term, term->marg_t, term->marg_b,
+                                      1, TRUE);
+                           else if (term->curs.y < term->rows - 1)
+                               term->curs.y++;
+                           term->curs.x = 0;
+                           fix_cpos;
+                           /* Now we must check_boundary again, of course. */
+                           check_boundary(term, term->curs.x, term->curs.y);
+                           check_boundary(term, term->curs.x+2, term->curs.y);
+                       }
+                       *term->cpos++ = c | term->curr_attr;
+                       *term->cpos++ = UCSWIDE | term->curr_attr;
+                       term->curs.x++;
+                       break;
+                     case 1:
+                       check_boundary(term, term->curs.x, term->curs.y);
+                       check_boundary(term, term->curs.x+1, term->curs.y);
+                       *term->cpos++ = c | term->curr_attr;
+                       break;
+                     default:
+                       continue;
+                   }
+               }
+               term->curs.x++;
+               if (term->curs.x == term->cols) {
+                   term->cpos--;
+                   term->curs.x--;
+                   term->wrapnext = TRUE;
+                   if (term->wrap && term->vt52_mode) {
+                       term->cpos[1] |= LATTR_WRAPPED;
+                       if (term->curs.y == term->marg_b)
+                           scroll(term, term->marg_t, term->marg_b, 1, TRUE);
+                       else if (term->curs.y < term->rows - 1)
+                           term->curs.y++;
+                       term->curs.x = 0;
+                       fix_cpos;
+                       term->wrapnext = FALSE;
+                   }
+               }
+               term->seen_disp_event = 1;
+               break;
+
+             case OSC_MAYBE_ST:
+               /*
+                * This state is virtually identical to SEEN_ESC, with the
+                * exception that we have an OSC sequence in the pipeline,
+                * and _if_ we see a backslash, we process it.
+                */
+               if (c == '\\') {
+                   do_osc(term);
+                   term->termstate = TOPLEVEL;
+                   break;
+               }
+               /* else fall through */
+             case SEEN_ESC:
+               if (c >= ' ' && c <= '/') {
+                   if (term->esc_query)
+                       term->esc_query = -1;
+                   else
+                       term->esc_query = c;
+                   break;
+               }
+               term->termstate = TOPLEVEL;
+               switch (ANSI(c, term->esc_query)) {
+                 case '[':             /* enter CSI mode */
+                   term->termstate = SEEN_CSI;
+                   term->esc_nargs = 1;
+                   term->esc_args[0] = ARG_DEFAULT;
+                   term->esc_query = FALSE;
+                   break;
+                 case ']':             /* OSC: xterm escape sequences */
+                   /* Compatibility is nasty here, xterm, linux, decterm yuk! */
+                   compatibility(OTHER);
+                   term->termstate = SEEN_OSC;
+                   term->esc_args[0] = 0;
+                   break;
+                 case '7':             /* DECSC: save cursor */
+                   compatibility(VT100);
+                   save_cursor(term, TRUE);
+                   break;
+                 case '8':             /* DECRC: restore cursor */
+                   compatibility(VT100);
+                   save_cursor(term, FALSE);
+                   term->seen_disp_event = TRUE;
+                   break;
+                 case '=':             /* DECKPAM: Keypad application mode */
+                   compatibility(VT100);
+                   term->app_keypad_keys = TRUE;
+                   break;
+                 case '>':             /* DECKPNM: Keypad numeric mode */
+                   compatibility(VT100);
+                   term->app_keypad_keys = FALSE;
+                   break;
+                 case 'D':            /* IND: exactly equivalent to LF */
+                   compatibility(VT100);
+                   if (term->curs.y == term->marg_b)
+                       scroll(term, term->marg_t, term->marg_b, 1, TRUE);
+                   else if (term->curs.y < term->rows - 1)
+                       term->curs.y++;
+                   fix_cpos;
+                   term->wrapnext = FALSE;
+                   term->seen_disp_event = TRUE;
+                   break;
+                 case 'E':            /* NEL: exactly equivalent to CR-LF */
+                   compatibility(VT100);
+                   term->curs.x = 0;
+                   if (term->curs.y == term->marg_b)
+                       scroll(term, term->marg_t, term->marg_b, 1, TRUE);
+                   else if (term->curs.y < term->rows - 1)
+                       term->curs.y++;
+                   fix_cpos;
+                   term->wrapnext = FALSE;
+                   term->seen_disp_event = TRUE;
+                   break;
+                 case 'M':            /* RI: reverse index - backwards LF */
+                   compatibility(VT100);
+                   if (term->curs.y == term->marg_t)
+                       scroll(term, term->marg_t, term->marg_b, -1, TRUE);
+                   else if (term->curs.y > 0)
+                       term->curs.y--;
+                   fix_cpos;
+                   term->wrapnext = FALSE;
+                   term->seen_disp_event = TRUE;
+                   break;
+                 case 'Z':            /* DECID: terminal type query */
+                   compatibility(VT100);
+                   if (term->ldisc)
+                       ldisc_send(term->ldisc, term->id_string,
+                                  strlen(term->id_string), 0);
+                   break;
+                 case 'c':            /* RIS: restore power-on settings */
+                   compatibility(VT100);
+                   power_on(term);
+                   if (term->ldisc)   /* cause ldisc to notice changes */
+                       ldisc_send(term->ldisc, NULL, 0, 0);
+                   if (term->reset_132) {
+                       if (!term->cfg.no_remote_resize)
+                           request_resize(term->frontend, 80, term->rows);
+                       term->reset_132 = 0;
+                   }
+                   fix_cpos;
+                   term->disptop = 0;
+                   term->seen_disp_event = TRUE;
+                   break;
+                 case 'H':            /* HTS: set a tab */
+                   compatibility(VT100);
+                   term->tabs[term->curs.x] = TRUE;
+                   break;
+
+                 case ANSI('8', '#'):  /* DECALN: fills screen with Es :-) */
+                   compatibility(VT100);
+                   {
+                       unsigned long *ldata;
+                       int i, j;
+                       pos scrtop, scrbot;
+
+                       for (i = 0; i < term->rows; i++) {
+                           ldata = lineptr(i);
+                           for (j = 0; j < term->cols; j++)
+                               ldata[j] = ATTR_DEFAULT | 'E';
+                           ldata[term->cols] = 0;
+                       }
+                       term->disptop = 0;
+                       term->seen_disp_event = TRUE;
+                       scrtop.x = scrtop.y = 0;
+                       scrbot.x = 0;
+                       scrbot.y = term->rows;
+                       check_selection(term, scrtop, scrbot);
+                   }
+                   break;
+
+                 case ANSI('3', '#'):
+                 case ANSI('4', '#'):
+                 case ANSI('5', '#'):
+                 case ANSI('6', '#'):
+                   compatibility(VT100);
+                   {
+                       unsigned long nlattr;
+                       unsigned long *ldata;
+                       switch (ANSI(c, term->esc_query)) {
+                         case ANSI('3', '#'): /* DECDHL: 2*height, top */
+                           nlattr = LATTR_TOP;
+                           break;
+                         case ANSI('4', '#'): /* DECDHL: 2*height, bottom */
+                           nlattr = LATTR_BOT;
+                           break;
+                         case ANSI('5', '#'): /* DECSWL: normal */
+                           nlattr = LATTR_NORM;
+                           break;
+                         default: /* case ANSI('6', '#'): DECDWL: 2*width */
+                           nlattr = LATTR_WIDE;
+                           break;
+                       }
+                       ldata = lineptr(term->curs.y);
+                       ldata[term->cols] &= ~LATTR_MODE;
+                       ldata[term->cols] |= nlattr;
+                   }
+                   break;
+                 /* GZD4: G0 designate 94-set */
+                 case ANSI('A', '('):
+                   compatibility(VT100);
+                   if (!term->cfg.no_remote_charset)
+                       term->cset_attr[0] = ATTR_GBCHR;
+                   break;
+                 case ANSI('B', '('):
+                   compatibility(VT100);
+                   if (!term->cfg.no_remote_charset)
+                       term->cset_attr[0] = ATTR_ASCII;
+                   break;
+                 case ANSI('0', '('):
+                   compatibility(VT100);
+                   if (!term->cfg.no_remote_charset)
+                       term->cset_attr[0] = ATTR_LINEDRW;
+                   break;
+                 case ANSI('U', '('): 
+                   compatibility(OTHER);
+                   if (!term->cfg.no_remote_charset)
+                       term->cset_attr[0] = ATTR_SCOACS; 
+                   break;
+                 /* G1D4: G1-designate 94-set */
+                 case ANSI('A', ')'):
+                   compatibility(VT100);
+                   if (!term->cfg.no_remote_charset)
+                       term->cset_attr[1] = ATTR_GBCHR;
+                   break;
+                 case ANSI('B', ')'):
+                   compatibility(VT100);
+                   if (!term->cfg.no_remote_charset)
+                       term->cset_attr[1] = ATTR_ASCII;
+                   break;
+                 case ANSI('0', ')'):
+                   compatibility(VT100);
+                   if (!term->cfg.no_remote_charset)
+                       term->cset_attr[1] = ATTR_LINEDRW;
+                   break;
+                 case ANSI('U', ')'): 
+                   compatibility(OTHER);
+                   if (!term->cfg.no_remote_charset)
+                       term->cset_attr[1] = ATTR_SCOACS; 
+                   break;
+                 /* DOCS: Designate other coding system */
+                 case ANSI('8', '%'):  /* Old Linux code */
+                 case ANSI('G', '%'):
+                   compatibility(OTHER);
+                   if (!term->cfg.no_remote_charset)
+                       term->utf = 1;
+                   break;
+                 case ANSI('@', '%'):
+                   compatibility(OTHER);
+                   if (!term->cfg.no_remote_charset)
+                       term->utf = 0;
+                   break;
+               }
+               break;
+             case SEEN_CSI:
+               term->termstate = TOPLEVEL;  /* default */
+               if (isdigit(c)) {
+                   if (term->esc_nargs <= ARGS_MAX) {
+                       if (term->esc_args[term->esc_nargs - 1] == ARG_DEFAULT)
+                           term->esc_args[term->esc_nargs - 1] = 0;
+                       term->esc_args[term->esc_nargs - 1] =
+                           10 * term->esc_args[term->esc_nargs - 1] + c - '0';
+                   }
+                   term->termstate = SEEN_CSI;
+               } else if (c == ';') {
+                   if (++term->esc_nargs <= ARGS_MAX)
+                       term->esc_args[term->esc_nargs - 1] = ARG_DEFAULT;
+                   term->termstate = SEEN_CSI;
+               } else if (c < '@') {
+                   if (term->esc_query)
+                       term->esc_query = -1;
+                   else if (c == '?')
+                       term->esc_query = TRUE;
+                   else
+                       term->esc_query = c;
+                   term->termstate = SEEN_CSI;
+               } else
+                   switch (ANSI(c, term->esc_query)) {
+                     case 'A':       /* CUU: move up N lines */
+                       move(term, term->curs.x,
+                            term->curs.y - def(term->esc_args[0], 1), 1);
+                       term->seen_disp_event = TRUE;
+                       break;
+                     case 'e':         /* VPR: move down N lines */
+                       compatibility(ANSI);
+                       /* FALLTHROUGH */
+                     case 'B':         /* CUD: Cursor down */
+                       move(term, term->curs.x,
+                            term->curs.y + def(term->esc_args[0], 1), 1);
+                       term->seen_disp_event = TRUE;
+                       break;
+                     case ANSI('c', '>'):      /* DA: report xterm version */
+                       compatibility(OTHER);
+                       /* this reports xterm version 136 so that VIM can
+                          use the drag messages from the mouse reporting */
+                       if (term->ldisc)
+                           ldisc_send(term->ldisc, "\033[>0;136;0c", 11, 0);
+                       break;
+                     case 'a':         /* HPR: move right N cols */
+                       compatibility(ANSI);
+                       /* FALLTHROUGH */
+                     case 'C':         /* CUF: Cursor right */ 
+                       move(term, term->curs.x + def(term->esc_args[0], 1),
+                            term->curs.y, 1);
+                       term->seen_disp_event = TRUE;
+                       break;
+                     case 'D':       /* CUB: move left N cols */
+                       move(term, term->curs.x - def(term->esc_args[0], 1),
+                            term->curs.y, 1);
+                       term->seen_disp_event = TRUE;
+                       break;
+                     case 'E':       /* CNL: move down N lines and CR */
+                       compatibility(ANSI);
+                       move(term, 0,
+                            term->curs.y + def(term->esc_args[0], 1), 1);
+                       term->seen_disp_event = TRUE;
+                       break;
+                     case 'F':       /* CPL: move up N lines and CR */
+                       compatibility(ANSI);
+                       move(term, 0,
+                            term->curs.y - def(term->esc_args[0], 1), 1);
+                       term->seen_disp_event = TRUE;
+                       break;
+                     case 'G':       /* CHA */
+                     case '`':       /* HPA: set horizontal posn */
+                       compatibility(ANSI);
+                       move(term, def(term->esc_args[0], 1) - 1,
+                            term->curs.y, 0);
+                       term->seen_disp_event = TRUE;
+                       break;
+                     case 'd':       /* VPA: set vertical posn */
+                       compatibility(ANSI);
+                       move(term, term->curs.x,
+                            ((term->dec_om ? term->marg_t : 0) +
+                             def(term->esc_args[0], 1) - 1),
+                            (term->dec_om ? 2 : 0));
+                       term->seen_disp_event = TRUE;
+                       break;
+                     case 'H':      /* CUP */
+                     case 'f':      /* HVP: set horz and vert posns at once */
+                       if (term->esc_nargs < 2)
+                           term->esc_args[1] = ARG_DEFAULT;
+                       move(term, def(term->esc_args[1], 1) - 1,
+                            ((term->dec_om ? term->marg_t : 0) +
+                             def(term->esc_args[0], 1) - 1),
+                            (term->dec_om ? 2 : 0));
+                       term->seen_disp_event = TRUE;
+                       break;
+                     case 'J':       /* ED: erase screen or parts of it */
+                       {
+                           unsigned int i = def(term->esc_args[0], 0) + 1;
+                           if (i > 3)
+                               i = 0;
+                           erase_lots(term, FALSE, !!(i & 2), !!(i & 1));
+                       }
+                       term->disptop = 0;
+                       term->seen_disp_event = TRUE;
+                       break;
+                     case 'K':       /* EL: erase line or parts of it */
+                       {
+                           unsigned int i = def(term->esc_args[0], 0) + 1;
+                           if (i > 3)
+                               i = 0;
+                           erase_lots(term, TRUE, !!(i & 2), !!(i & 1));
+                       }
+                       term->seen_disp_event = TRUE;
+                       break;
+                     case 'L':       /* IL: insert lines */
+                       compatibility(VT102);
+                       if (term->curs.y <= term->marg_b)
+                           scroll(term, term->curs.y, term->marg_b,
+                                  -def(term->esc_args[0], 1), FALSE);
+                       fix_cpos;
+                       term->seen_disp_event = TRUE;
+                       break;
+                     case 'M':       /* DL: delete lines */
+                       compatibility(VT102);
+                       if (term->curs.y <= term->marg_b)
+                           scroll(term, term->curs.y, term->marg_b,
+                                  def(term->esc_args[0], 1),
+                                  TRUE);
+                       fix_cpos;
+                       term->seen_disp_event = TRUE;
+                       break;
+                     case '@':       /* ICH: insert chars */
+                       /* XXX VTTEST says this is vt220, vt510 manual says vt102 */
+                       compatibility(VT102);
+                       insch(term, def(term->esc_args[0], 1));
+                       term->seen_disp_event = TRUE;
+                       break;
+                     case 'P':       /* DCH: delete chars */
+                       compatibility(VT102);
+                       insch(term, -def(term->esc_args[0], 1));
+                       term->seen_disp_event = TRUE;
+                       break;
+                     case 'c':       /* DA: terminal type query */
+                       compatibility(VT100);
+                       /* This is the response for a VT102 */
+                       if (term->ldisc)
+                           ldisc_send(term->ldisc, term->id_string,
+                                      strlen(term->id_string), 0);
+                       break;
+                     case 'n':       /* DSR: cursor position query */
+                       if (term->ldisc) {
+                           if (term->esc_args[0] == 6) {
+                               char buf[32];
+                               snprintf(buf, sizeof(buf), "\033[%d;%dR", 
+                                        term->curs.y + 1, term->curs.x + 1);
+                               ldisc_send(term->ldisc, buf, strlen(buf), 0);
+                           } else if (term->esc_args[0] == 5) {
+                               ldisc_send(term->ldisc, "\033[0n", 4, 0);
+                           }
+                       }
+                       break;
+                     case 'h':       /* SM: toggle modes to high */
+                     case ANSI_QUE('h'):
+                       compatibility(VT100);
+                       {
+                           int i;
+                           for (i = 0; i < term->esc_nargs; i++)
+                               toggle_mode(term, term->esc_args[i],
+                                           term->esc_query, TRUE);
+                       }
+                       break;
+                     case 'i':         /* MC: Media copy */
+                     case ANSI_QUE('i'):
+                       compatibility(VT100);
+                       {
+                           if (term->esc_nargs != 1) break;
+                           if (term->esc_args[0] == 5 && *term->cfg.printer) {
+                               term->printing = TRUE;
+                               term->only_printing = !term->esc_query;
+                               term->print_state = 0;
+                               term_print_setup(term);
+                           } else if (term->esc_args[0] == 4 &&
+                                      term->printing) {
+                               term_print_finish(term);
+                           }
+                       }
+                       break;                  
+                     case 'l':       /* RM: toggle modes to low */
+                     case ANSI_QUE('l'):
+                       compatibility(VT100);
+                       {
+                           int i;
+                           for (i = 0; i < term->esc_nargs; i++)
+                               toggle_mode(term, term->esc_args[i],
+                                           term->esc_query, FALSE);
+                       }
+                       break;
+                     case 'g':       /* TBC: clear tabs */
+                       compatibility(VT100);
+                       if (term->esc_nargs == 1) {
+                           if (term->esc_args[0] == 0) {
+                               term->tabs[term->curs.x] = FALSE;
+                           } else if (term->esc_args[0] == 3) {
+                               int i;
+                               for (i = 0; i < term->cols; i++)
+                                   term->tabs[i] = FALSE;
+                           }
+                       }
+                       break;
+                     case 'r':       /* DECSTBM: set scroll margins */
+                       compatibility(VT100);
+                       if (term->esc_nargs <= 2) {
+                           int top, bot;
+                           top = def(term->esc_args[0], 1) - 1;
+                           bot = (term->esc_nargs <= 1
+                                  || term->esc_args[1] == 0 ?
+                                  term->rows :
+                                  def(term->esc_args[1], term->rows)) - 1;
+                           if (bot >= term->rows)
+                               bot = term->rows - 1;
+                           /* VTTEST Bug 9 - if region is less than 2 lines
+                            * don't change region.
+                            */
+                           if (bot - top > 0) {
+                               term->marg_t = top;
+                               term->marg_b = bot;
+                               term->curs.x = 0;
+                               /*
+                                * I used to think the cursor should be
+                                * placed at the top of the newly marginned
+                                * area. Apparently not: VMS TPU falls over
+                                * if so.
+                                *
+                                * Well actually it should for
+                                * Origin mode - RDB
+                                */
+                               term->curs.y = (term->dec_om ?
+                                               term->marg_t : 0);
+                               fix_cpos;
+                               term->seen_disp_event = TRUE;
+                           }
+                       }
+                       break;
+                     case 'm':       /* SGR: set graphics rendition */
+                       {
+                           /* 
+                            * A VT100 without the AVO only had one
+                            * attribute, either underline or
+                            * reverse video depending on the
+                            * cursor type, this was selected by
+                            * CSI 7m.
+                            *
+                            * case 2:
+                            *  This is sometimes DIM, eg on the
+                            *  GIGI and Linux
+                            * case 8:
+                            *  This is sometimes INVIS various ANSI.
+                            * case 21:
+                            *  This like 22 disables BOLD, DIM and INVIS
+                            *
+                            * The ANSI colours appear on any
+                            * terminal that has colour (obviously)
+                            * but the interaction between sgr0 and
+                            * the colours varies but is usually
+                            * related to the background colour
+                            * erase item. The interaction between
+                            * colour attributes and the mono ones
+                            * is also very implementation
+                            * dependent.
+                            *
+                            * The 39 and 49 attributes are likely
+                            * to be unimplemented.
+                            */
+                           int i;
+                           for (i = 0; i < term->esc_nargs; i++) {
+                               switch (def(term->esc_args[i], 0)) {
+                                 case 0:       /* restore defaults */
+                                   term->curr_attr = term->default_attr;
+                                   break;
+                                 case 1:       /* enable bold */
+                                   compatibility(VT100AVO);
+                                   term->curr_attr |= ATTR_BOLD;
+                                   break;
+                                 case 21:      /* (enable double underline) */
+                                   compatibility(OTHER);
+                                 case 4:       /* enable underline */
+                                   compatibility(VT100AVO);
+                                   term->curr_attr |= ATTR_UNDER;
+                                   break;
+                                 case 5:       /* enable blink */
+                                   compatibility(VT100AVO);
+                                   term->curr_attr |= ATTR_BLINK;
+                                   break;
+                                 case 6:       /* SCO light bkgrd */
+                                   compatibility(SCOANSI);
+                                   term->blink_is_real = FALSE;
+                                   term->curr_attr |= ATTR_BLINK;
+                                   break;
+                                 case 7:       /* enable reverse video */
+                                   term->curr_attr |= ATTR_REVERSE;
+                                   break;
+                                 case 10:      /* SCO acs off */
+                                   compatibility(SCOANSI);
+                                   if (term->cfg.no_remote_charset) break;
+                                   term->sco_acs = 0; break;
+                                 case 11:      /* SCO acs on */
+                                   compatibility(SCOANSI);
+                                   if (term->cfg.no_remote_charset) break;
+                                   term->sco_acs = 1; break;
+                                 case 12:      /* SCO acs on, |0x80 */
+                                   compatibility(SCOANSI);
+                                   if (term->cfg.no_remote_charset) break;
+                                   term->sco_acs = 2; break;
+                                 case 22:      /* disable bold */
+                                   compatibility2(OTHER, VT220);
+                                   term->curr_attr &= ~ATTR_BOLD;
+                                   break;
+                                 case 24:      /* disable underline */
+                                   compatibility2(OTHER, VT220);
+                                   term->curr_attr &= ~ATTR_UNDER;
+                                   break;
+                                 case 25:      /* disable blink */
+                                   compatibility2(OTHER, VT220);
+                                   term->curr_attr &= ~ATTR_BLINK;
+                                   break;
+                                 case 27:      /* disable reverse video */
+                                   compatibility2(OTHER, VT220);
+                                   term->curr_attr &= ~ATTR_REVERSE;
+                                   break;
+                                 case 30:
+                                 case 31:
+                                 case 32:
+                                 case 33:
+                                 case 34:
+                                 case 35:
+                                 case 36:
+                                 case 37:
+                                   /* foreground */
+                                   term->curr_attr &= ~ATTR_FGMASK;
+                                   term->curr_attr |=
+                                       (uint32_t)(term->esc_args[i] - 30) << ATTR_FGSHIFT;
+                                   break;
+                                 case 90:
+                                 case 91:
+                                 case 92:
+                                 case 93:
+                                 case 94:
+                                 case 95:
+                                 case 96:
+                                 case 97:
+                                   /* xterm-style bright foreground */
+                                   term->curr_attr &= ~ATTR_FGMASK;
+                                   term->curr_attr |=
+                                       ((uint32_t)(term->esc_args[i] - 90 + 16) << ATTR_FGSHIFT);
+                                   break;
+                                 case 39:      /* default-foreground */
+                                   term->curr_attr &= ~ATTR_FGMASK;
+                                   term->curr_attr |= ATTR_DEFFG;
+                                   break;
+                                 case 40:
+                                 case 41:
+                                 case 42:
+                                 case 43:
+                                 case 44:
+                                 case 45:
+                                 case 46:
+                                 case 47:
+                                   /* background */
+                                   term->curr_attr &= ~ATTR_BGMASK;
+                                   term->curr_attr |=
+                                       (uint32_t)(term->esc_args[i] - 40) << ATTR_BGSHIFT;
+                                   break;
+                                 case 100:
+                                 case 101:
+                                 case 102:
+                                 case 103:
+                                 case 104:
+                                 case 105:
+                                 case 106:
+                                 case 107:
+                                   /* xterm-style bright background */
+                                   term->curr_attr &= ~ATTR_BGMASK;
+                                   term->curr_attr |=
+                                       ((uint32_t)(term->esc_args[i] - 100 + 16) << ATTR_BGSHIFT);
+                                   break;
+                                 case 49:      /* default-background */
+                                   term->curr_attr &= ~ATTR_BGMASK;
+                                   term->curr_attr |= ATTR_DEFBG;
+                                   break;
+                               }
+                           }
+                           if (term->use_bce)
+                               term->erase_char = (' ' | ATTR_ASCII |
+                                                   (term->curr_attr & 
+                                                    (ATTR_FGMASK |
+                                                     ATTR_BGMASK)));
+                       }
+                       break;
+                     case 's':       /* save cursor */
+                       save_cursor(term, TRUE);
+                       break;
+                     case 'u':       /* restore cursor */
+                       save_cursor(term, FALSE);
+                       term->seen_disp_event = TRUE;
+                       break;
+                     case 't': /* DECSLPP: set page size - ie window height */
+                       /*
+                        * VT340/VT420 sequence DECSLPP, DEC only allows values
+                        *  24/25/36/48/72/144 other emulators (eg dtterm) use
+                        * illegal values (eg first arg 1..9) for window changing 
+                        * and reports.
+                        */
+                       if (term->esc_nargs <= 1
+                           && (term->esc_args[0] < 1 ||
+                               term->esc_args[0] >= 24)) {
+                           compatibility(VT340TEXT);
+                           if (!term->cfg.no_remote_resize)
+                               request_resize(term->frontend, term->cols,
+                                              def(term->esc_args[0], 24));
+                           deselect(term);
+                       } else if (term->esc_nargs >= 1 &&
+                                  term->esc_args[0] >= 1 &&
+                                  term->esc_args[0] < 24) {
+                           compatibility(OTHER);
+
+                           switch (term->esc_args[0]) {
+                               int x, y, len;
+                               char buf[80], *p;
+                             case 1:
+                               set_iconic(term->frontend, FALSE);
+                               break;
+                             case 2:
+                               set_iconic(term->frontend, TRUE);
+                               break;
+                             case 3:
+                               if (term->esc_nargs >= 3) {
+                                   if (!term->cfg.no_remote_resize)
+                                       move_window(term->frontend,
+                                                   def(term->esc_args[1], 0),
+                                                   def(term->esc_args[2], 0));
+                               }
+                               break;
+                             case 4:
+                               /* We should resize the window to a given
+                                * size in pixels here, but currently our
+                                * resizing code isn't healthy enough to
+                                * manage it. */
+                               break;
+                             case 5:
+                               /* move to top */
+                               set_zorder(term->frontend, TRUE);
+                               break;
+                             case 6:
+                               /* move to bottom */
+                               set_zorder(term->frontend, FALSE);
+                               break;
+                             case 7:
+                               refresh_window(term->frontend);
+                               break;
+                             case 8:
+                               if (term->esc_nargs >= 3) {
+                                   if (!term->cfg.no_remote_resize)
+                                       request_resize(term->frontend,
+                                                      def(term->esc_args[2], term->cfg.width),
+                                                      def(term->esc_args[1], term->cfg.height));
+                               }
+                               break;
+                             case 9:
+                               if (term->esc_nargs >= 2)
+                                   set_zoomed(term->frontend,
+                                              term->esc_args[1] ?
+                                              TRUE : FALSE);
+                               break;
+                             case 11:
+                               if (term->ldisc)
+                                   ldisc_send(term->ldisc,
+                                              is_iconic(term->frontend) ?
+                                              "\033[1t" : "\033[2t", 4, 0);
+                               break;
+                             case 13:
+                               if (term->ldisc) {
+                                   get_window_pos(term->frontend, &x, &y);
+                                   len = snprintf(buf, sizeof(buf), "\033[3;%d;%dt", x, y);
+                                   ldisc_send(term->ldisc, buf, len, 0);
+                               }
+                               break;
+                             case 14:
+                               if (term->ldisc) {
+                                   get_window_pixels(term->frontend, &x, &y);
+                                   len = snprintf(buf, sizeof(buf), "\033[4;%d;%dt", x, y);
+                                   ldisc_send(term->ldisc, buf, len, 0);
+                               }
+                               break;
+                             case 18:
+                               if (term->ldisc) {
+                                   len = snprintf(buf, sizeof(buf),
+                                                  "\033[8;%d;%dt",
+                                                  term->rows, term->cols);
+                                   ldisc_send(term->ldisc, buf, len, 0);
+                               }
+                               break;
+                             case 19:
+                               /*
+                                * Hmmm. Strictly speaking we
+                                * should return `the size of the
+                                * screen in characters', but
+                                * that's not easy: (a) window
+                                * furniture being what it is it's
+                                * hard to compute, and (b) in
+                                * resize-font mode maximising the
+                                * window wouldn't change the
+                                * number of characters. *shrug*. I
+                                * think we'll ignore it for the
+                                * moment and see if anyone
+                                * complains, and then ask them
+                                * what they would like it to do.
+                                */
+                               break;
+                             case 20:
+                               if (term->ldisc &&
+                                   !term->cfg.no_remote_qtitle) {
+                                   p = get_window_title(term->frontend, TRUE);
+                                   len = strlen(p);
+                                   ldisc_send(term->ldisc, "\033]L", 3, 0);
+                                   ldisc_send(term->ldisc, p, len, 0);
+                                   ldisc_send(term->ldisc, "\033\\", 2, 0);
+                               }
+                               break;
+                             case 21:
+                               if (term->ldisc &&
+                                   !term->cfg.no_remote_qtitle) {
+                                   p = get_window_title(term->frontend,FALSE);
+                                   len = strlen(p);
+                                   ldisc_send(term->ldisc, "\033]l", 3, 0);
+                                   ldisc_send(term->ldisc, p, len, 0);
+                                   ldisc_send(term->ldisc, "\033\\", 2, 0);
+                               }
+                               break;
+                           }
+                       }
+                       break;
+                     case 'S':         /* SU: Scroll up */
+                       compatibility(SCOANSI);
+                       scroll(term, term->marg_t, term->marg_b,
+                              def(term->esc_args[0], 1), TRUE);
+                       fix_cpos;
+                       term->wrapnext = FALSE;
+                       term->seen_disp_event = TRUE;
+                       break;
+                     case 'T':         /* SD: Scroll down */
+                       compatibility(SCOANSI);
+                       scroll(term, term->marg_t, term->marg_b,
+                              -def(term->esc_args[0], 1), TRUE);
+                       fix_cpos;
+                       term->wrapnext = FALSE;
+                       term->seen_disp_event = TRUE;
+                       break;
+                     case ANSI('|', '*'): /* DECSNLS */
+                       /* 
+                        * Set number of lines on screen
+                        * VT420 uses VGA like hardware and can
+                        * support any size in reasonable range
+                        * (24..49 AIUI) with no default specified.
+                        */
+                       compatibility(VT420);
+                       if (term->esc_nargs == 1 && term->esc_args[0] > 0) {
+                           if (!term->cfg.no_remote_resize)
+                               request_resize(term->frontend, term->cols,
+                                              def(term->esc_args[0],
+                                                  term->cfg.height));
+                           deselect(term);
+                       }
+                       break;
+                     case ANSI('|', '$'): /* DECSCPP */
+                       /*
+                        * Set number of columns per page
+                        * Docs imply range is only 80 or 132, but
+                        * I'll allow any.
+                        */
+                       compatibility(VT340TEXT);
+                       if (term->esc_nargs <= 1) {
+                           if (!term->cfg.no_remote_resize)
+                               request_resize(term->frontend,
+                                              def(term->esc_args[0],
+                                                  term->cfg.width), term->rows);
+                           deselect(term);
+                       }
+                       break;
+                     case 'X':     /* ECH: write N spaces w/o moving cursor */
+                       /* XXX VTTEST says this is vt220, vt510 manual
+                        * says vt100 */
+                       compatibility(ANSIMIN);
+                       {
+                           int n = def(term->esc_args[0], 1);
+                           pos cursplus;
+                           unsigned long *p = term->cpos;
+                           if (n > term->cols - term->curs.x)
+                               n = term->cols - term->curs.x;
+                           cursplus = term->curs;
+                           cursplus.x += n;
+                           check_boundary(term, term->curs.x, term->curs.y);
+                           check_boundary(term, term->curs.x+n, term->curs.y);
+                           check_selection(term, term->curs, cursplus);
+                           while (n--)
+                               *p++ = term->erase_char;
+                           term->seen_disp_event = TRUE;
+                       }
+                       break;
+                     case 'x':       /* DECREQTPARM: report terminal characteristics */
+                       compatibility(VT100);
+                       if (term->ldisc) {
+                           char buf[32];
+                           int i = def(term->esc_args[0], 0);
+                           if (i == 0 || i == 1) {
+                               strcpy(buf, "\033[2;1;1;112;112;1;0x");
+                               buf[2] += i;
+                               ldisc_send(term->ldisc, buf, 20, 0);
+                           }
+                       }
+                       break;
+                     case 'Z':         /* CBT: BackTab for xterm */
+                       compatibility(OTHER);
+                       {
+                           int i = def(term->esc_args[0], 1);
+                           pos old_curs = term->curs;
+
+                           for(;i>0 && term->curs.x>0; i--) {
+                               do {
+                                   term->curs.x--;
+                               } while (term->curs.x >0 &&
+                                        !term->tabs[term->curs.x]);
+                           }
+                           fix_cpos;
+                           check_selection(term, old_curs, term->curs);
+                       }
+                       break;
+                     case ANSI('c', '='):      /* Hide or Show Cursor */
+                       compatibility(SCOANSI);
+                       switch(term->esc_args[0]) {
+                         case 0:  /* hide cursor */
+                           term->cursor_on = FALSE;
+                           break;
+                         case 1:  /* restore cursor */
+                           term->big_cursor = FALSE;
+                           term->cursor_on = TRUE;
+                           break;
+                         case 2:  /* block cursor */
+                           term->big_cursor = TRUE;
+                           term->cursor_on = TRUE;
+                           break;
+                       }
+                       break;
+                     case ANSI('C', '='):
+                       /*
+                        * set cursor start on scanline esc_args[0] and
+                        * end on scanline esc_args[1].If you set
+                        * the bottom scan line to a value less than
+                        * the top scan line, the cursor will disappear.
+                        */
+                       compatibility(SCOANSI);
+                       if (term->esc_nargs >= 2) {
+                           if (term->esc_args[0] > term->esc_args[1])
+                               term->cursor_on = FALSE;
+                           else
+                               term->cursor_on = TRUE;
+                       }
+                       break;
+                     case ANSI('D', '='):
+                       compatibility(SCOANSI);
+                       term->blink_is_real = FALSE;
+                       if (term->esc_args[0]>=1)
+                           term->curr_attr |= ATTR_BLINK;
+                       else
+                           term->curr_attr &= ~ATTR_BLINK;
+                       break;
+                     case ANSI('E', '='):
+                       compatibility(SCOANSI);
+                       term->blink_is_real = (term->esc_args[0] >= 1);
+                       break;
+                     case ANSI('F', '='):      /* set normal foreground */
+                       compatibility(SCOANSI);
+                       if (term->esc_args[0] >= 0 && term->esc_args[0] < 16) {
+                           uint32_t colour =
+                               (sco2ansicolour[term->esc_args[0] & 0x7] |
+                                (uint32_t)((term->esc_args[0] & 0x8) << 1)) <<
+                               ATTR_FGSHIFT;
+                           term->curr_attr &= ~ATTR_FGMASK;
+                           term->curr_attr |= colour;
+                           term->default_attr &= ~ATTR_FGMASK;
+                           term->default_attr |= colour;
+                       }
+                       break;
+                     case ANSI('G', '='):      /* set normal background */
+                       compatibility(SCOANSI);
+                       if (term->esc_args[0] >= 0 && term->esc_args[0] < 16) {
+                           uint32_t colour =
+                               (sco2ansicolour[term->esc_args[0] & 0x7] |
+                                (uint32_t)((term->esc_args[0] & 0x8) << 1)) <<
+                               ATTR_BGSHIFT;
+                           term->curr_attr &= ~ATTR_BGMASK;
+                           term->curr_attr |= colour;
+                           term->default_attr &= ~ATTR_BGMASK;
+                           term->default_attr |= colour;
+                       }
+                       break;
+                     case ANSI('L', '='):
+                       compatibility(SCOANSI);
+                       term->use_bce = (term->esc_args[0] <= 0);
+                       term->erase_char = ERASE_CHAR;
+                       if (term->use_bce)
+                           term->erase_char = (' ' | ATTR_ASCII |
+                                               (term->curr_attr & 
+                                                (ATTR_FGMASK | ATTR_BGMASK)));
+                       break;
+                     case ANSI('p', '"'): /* DECSCL: set compat level */
+                       /*
+                        * Allow the host to make this emulator a
+                        * 'perfect' VT102. This first appeared in
+                        * the VT220, but we do need to get back to
+                        * PuTTY mode so I won't check it.
+                        *
+                        * The arg in 40..42,50 are a PuTTY extension.
+                        * The 2nd arg, 8bit vs 7bit is not checked.
+                        *
+                        * Setting VT102 mode should also change
+                        * the Fkeys to generate PF* codes as a
+                        * real VT102 has no Fkeys. The VT220 does
+                        * this, F11..F13 become ESC,BS,LF other
+                        * Fkeys send nothing.
+                        *
+                        * Note ESC c will NOT change this!
+                        */
+
+                       switch (term->esc_args[0]) {
+                         case 61:
+                           term->compatibility_level &= ~TM_VTXXX;
+                           term->compatibility_level |= TM_VT102;
+                           break;
+                         case 62:
+                           term->compatibility_level &= ~TM_VTXXX;
+                           term->compatibility_level |= TM_VT220;
+                           break;
+
+                         default:
+                           if (term->esc_args[0] > 60 &&
+                               term->esc_args[0] < 70)
+                               term->compatibility_level |= TM_VTXXX;
+                           break;
+
+                         case 40:
+                           term->compatibility_level &= TM_VTXXX;
+                           break;
+                         case 41:
+                           term->compatibility_level = TM_PUTTY;
+                           break;
+                         case 42:
+                           term->compatibility_level = TM_SCOANSI;
+                           break;
+
+                         case ARG_DEFAULT:
+                           term->compatibility_level = TM_PUTTY;
+                           break;
+                         case 50:
+                           break;
+                       }
+
+                       /* Change the response to CSI c */
+                       if (term->esc_args[0] == 50) {
+                           int i;
+                           char lbuf[64];
+                           strcpy(term->id_string, "\033[?");
+                           for (i = 1; i < term->esc_nargs; i++) {
+                               if (i != 1)
+                                   strcat(term->id_string, ";");
+                               snprintf(lbuf, sizeof(lbuf), "%d", term->esc_args[i]);
+                               strcat(term->id_string, lbuf);
+                           }
+                           strcat(term->id_string, "c");
+                       }
+#if 0
+                       /* Is this a good idea ? 
+                        * Well we should do a soft reset at this point ...
+                        */
+                       if (!has_compat(VT420) && has_compat(VT100)) {
+                           if (!term->cfg.no_remote_resize) {
+                               if (term->reset_132)
+                                   request_resize(132, 24);
+                               else
+                                   request_resize(80, 24);
+                           }
+                       }
+#endif
+                       break;
+                   }
+               break;
+             case SEEN_OSC:
+               term->osc_w = FALSE;
+               switch (c) {
+                 case 'P':            /* Linux palette sequence */
+                   term->termstate = SEEN_OSC_P;
+                   term->osc_strlen = 0;
+                   break;
+                 case 'R':            /* Linux palette reset */
+                   palette_reset(term->frontend);
+                   term_invalidate(term);
+                   term->termstate = TOPLEVEL;
+                   break;
+                 case 'W':            /* word-set */
+                   term->termstate = SEEN_OSC_W;
+                   term->osc_w = TRUE;
+                   break;
+                 case '0':
+                 case '1':
+                 case '2':
+                 case '3':
+                 case '4':
+                 case '5':
+                 case '6':
+                 case '7':
+                 case '8':
+                 case '9':
+                   term->esc_args[0] = 10 * term->esc_args[0] + c - '0';
+                   break;
+                 case 'L':
+                   /*
+                    * Grotty hack to support xterm and DECterm title
+                    * sequences concurrently.
+                    */
+                   if (term->esc_args[0] == 2) {
+                       term->esc_args[0] = 1;
+                       break;
+                   }
+                   /* else fall through */
+                 default:
+                   term->termstate = OSC_STRING;
+                   term->osc_strlen = 0;
+               }
+               break;
+             case OSC_STRING:
+               /*
+                * This OSC stuff is EVIL. It takes just one character to get into
+                * sysline mode and it's not initially obvious how to get out.
+                * So I've added CR and LF as string aborts.
+                * This shouldn't effect compatibility as I believe embedded 
+                * control characters are supposed to be interpreted (maybe?) 
+                * and they don't display anything useful anyway.
+                *
+                * -- RDB
+                */
+               if (c == '\012' || c == '\015') {
+                   term->termstate = TOPLEVEL;
+               } else if (c == 0234 || c == '\007') {
+                   /*
+                    * These characters terminate the string; ST and BEL
+                    * terminate the sequence and trigger instant
+                    * processing of it, whereas ESC goes back to SEEN_ESC
+                    * mode unless it is followed by \, in which case it is
+                    * synonymous with ST in the first place.
+                    */
+                   do_osc(term);
+                   term->termstate = TOPLEVEL;
+               } else if (c == '\033')
+                   term->termstate = OSC_MAYBE_ST;
+               else if (term->osc_strlen < OSC_STR_MAX)
+                   term->osc_string[term->osc_strlen++] = c;
+               break;
+             case SEEN_OSC_P:
+               {
+                   unsigned int max = (term->osc_strlen == 0 ? 21 : 16);
+                   int val;
+                   if (c >= '0' && c <= '9')
+                       val = c - '0';
+                   else if (c >= (unsigned char)'A' && c <= (unsigned char)'A' + max - 10)
+                       val = c - 'A' + 10;
+                   else if (c >= (unsigned char)'a' && c <= (unsigned char)'a' + max - 10)
+                       val = c - 'a' + 10;
+                   else {
+                       term->termstate = TOPLEVEL;
+                       break;
+                   }
+                   term->osc_string[term->osc_strlen++] = val;
+                   if (term->osc_strlen >= 7) {
+                       palette_set(term->frontend, term->osc_string[0],
+                                   term->osc_string[1] * 16 + term->osc_string[2],
+                                   term->osc_string[3] * 16 + term->osc_string[4],
+                                   term->osc_string[5] * 16 + term->osc_string[6]);
+                       term_invalidate(term);
+                       term->termstate = TOPLEVEL;
+                   }
+               }
+               break;
+             case SEEN_OSC_W:
+               switch (c) {
+                 case '0':
+                 case '1':
+                 case '2':
+                 case '3':
+                 case '4':
+                 case '5':
+                 case '6':
+                 case '7':
+                 case '8':
+                 case '9':
+                   term->esc_args[0] = 10 * term->esc_args[0] + c - '0';
+                   break;
+                 default:
+                   term->termstate = OSC_STRING;
+                   term->osc_strlen = 0;
+               }
+               break;
+             case VT52_ESC:
+               term->termstate = TOPLEVEL;
+               term->seen_disp_event = TRUE;
+               switch (c) {
+                 case 'A':
+                   move(term, term->curs.x, term->curs.y - 1, 1);
+                   break;
+                 case 'B':
+                   move(term, term->curs.x, term->curs.y + 1, 1);
+                   break;
+                 case 'C':
+                   move(term, term->curs.x + 1, term->curs.y, 1);
+                   break;
+                 case 'D':
+                   move(term, term->curs.x - 1, term->curs.y, 1);
+                   break;
+                   /*
+                    * From the VT100 Manual
+                    * NOTE: The special graphics characters in the VT100
+                    *       are different from those in the VT52
+                    *
+                    * From VT102 manual:
+                    *       137 _  Blank             - Same
+                    *       140 `  Reserved          - Humm.
+                    *       141 a  Solid rectangle   - Similar
+                    *       142 b  1/                - Top half of fraction for the
+                    *       143 c  3/                - subscript numbers below.
+                    *       144 d  5/
+                    *       145 e  7/
+                    *       146 f  Degrees           - Same
+                    *       147 g  Plus or minus     - Same
+                    *       150 h  Right arrow
+                    *       151 i  Ellipsis (dots)
+                    *       152 j  Divide by
+                    *       153 k  Down arrow
+                    *       154 l  Bar at scan 0
+                    *       155 m  Bar at scan 1
+                    *       156 n  Bar at scan 2
+                    *       157 o  Bar at scan 3     - Similar
+                    *       160 p  Bar at scan 4     - Similar
+                    *       161 q  Bar at scan 5     - Similar
+                    *       162 r  Bar at scan 6     - Same
+                    *       163 s  Bar at scan 7     - Similar
+                    *       164 t  Subscript 0
+                    *       165 u  Subscript 1
+                    *       166 v  Subscript 2
+                    *       167 w  Subscript 3
+                    *       170 x  Subscript 4
+                    *       171 y  Subscript 5
+                    *       172 z  Subscript 6
+                    *       173 {  Subscript 7
+                    *       174 |  Subscript 8
+                    *       175 }  Subscript 9
+                    *       176 ~  Paragraph
+                    *
+                    */
+                 case 'F':
+                   term->cset_attr[term->cset = 0] = ATTR_LINEDRW;
+                   break;
+                 case 'G':
+                   term->cset_attr[term->cset = 0] = ATTR_ASCII;
+                   break;
+                 case 'H':
+                   move(term, 0, 0, 0);
+                   break;
+                 case 'I':
+                   if (term->curs.y == 0)
+                       scroll(term, 0, term->rows - 1, -1, TRUE);
+                   else if (term->curs.y > 0)
+                       term->curs.y--;
+                   fix_cpos;
+                   term->wrapnext = FALSE;
+                   break;
+                 case 'J':
+                   erase_lots(term, FALSE, FALSE, TRUE);
+                   term->disptop = 0;
+                   break;
+                 case 'K':
+                   erase_lots(term, TRUE, FALSE, TRUE);
+                   break;
+#if 0
+                 case 'V':
+                   /* XXX Print cursor line */
+                   break;
+                 case 'W':
+                   /* XXX Start controller mode */
+                   break;
+                 case 'X':
+                   /* XXX Stop controller mode */
+                   break;
+#endif
+                 case 'Y':
+                   term->termstate = VT52_Y1;
+                   break;
+                 case 'Z':
+                   if (term->ldisc)
+                       ldisc_send(term->ldisc, "\033/Z", 3, 0);
+                   break;
+                 case '=':
+                   term->app_keypad_keys = TRUE;
+                   break;
+                 case '>':
+                   term->app_keypad_keys = FALSE;
+                   break;
+                 case '<':
+                   /* XXX This should switch to VT100 mode not current or default
+                    *     VT mode. But this will only have effect in a VT220+
+                    *     emulation.
+                    */
+                   term->vt52_mode = FALSE;
+                   term->blink_is_real = term->cfg.blinktext;
+                   break;
+#if 0
+                 case '^':
+                   /* XXX Enter auto print mode */
+                   break;
+                 case '_':
+                   /* XXX Exit auto print mode */
+                   break;
+                 case ']':
+                   /* XXX Print screen */
+                   break;
+#endif
+
+#ifdef VT52_PLUS
+                 case 'E':
+                   /* compatibility(ATARI) */
+                   move(term, 0, 0, 0);
+                   erase_lots(term, FALSE, FALSE, TRUE);
+                   term->disptop = 0;
+                   break;
+                 case 'L':
+                   /* compatibility(ATARI) */
+                   if (term->curs.y <= term->marg_b)
+                       scroll(term, term->curs.y, term->marg_b, -1, FALSE);
+                   break;
+                 case 'M':
+                   /* compatibility(ATARI) */
+                   if (term->curs.y <= term->marg_b)
+                       scroll(term, term->curs.y, term->marg_b, 1, TRUE);
+                   break;
+                 case 'b':
+                   /* compatibility(ATARI) */
+                   term->termstate = VT52_FG;
+                   break;
+                 case 'c':
+                   /* compatibility(ATARI) */
+                   term->termstate = VT52_BG;
+                   break;
+                 case 'd':
+                   /* compatibility(ATARI) */
+                   erase_lots(term, FALSE, TRUE, FALSE);
+                   term->disptop = 0;
+                   break;
+                 case 'e':
+                   /* compatibility(ATARI) */
+                   term->cursor_on = TRUE;
+                   break;
+                 case 'f':
+                   /* compatibility(ATARI) */
+                   term->cursor_on = FALSE;
+                   break;
+                   /* case 'j': Save cursor position - broken on ST */
+                   /* case 'k': Restore cursor position */
+                 case 'l':
+                   /* compatibility(ATARI) */
+                   erase_lots(term, TRUE, TRUE, TRUE);
+                   term->curs.x = 0;
+                   term->wrapnext = FALSE;
+                   fix_cpos;
+                   break;
+                 case 'o':
+                   /* compatibility(ATARI) */
+                   erase_lots(term, TRUE, TRUE, FALSE);
+                   break;
+                 case 'p':
+                   /* compatibility(ATARI) */
+                   term->curr_attr |= ATTR_REVERSE;
+                   break;
+                 case 'q':
+                   /* compatibility(ATARI) */
+                   term->curr_attr &= ~ATTR_REVERSE;
+                   break;
+                 case 'v':            /* wrap Autowrap on - Wyse style */
+                   /* compatibility(ATARI) */
+                   term->wrap = 1;
+                   break;
+                 case 'w':            /* Autowrap off */
+                   /* compatibility(ATARI) */
+                   term->wrap = 0;
+                   break;
+
+                 case 'R':
+                   /* compatibility(OTHER) */
+                   term->vt52_bold = FALSE;
+                   term->curr_attr = ATTR_DEFAULT;
+                   if (term->use_bce)
+                       term->erase_char = (' ' | ATTR_ASCII |
+                                           (term->curr_attr & 
+                                            (ATTR_FGMASK | ATTR_BGMASK)));
+                   break;
+                 case 'S':
+                   /* compatibility(VI50) */
+                   term->curr_attr |= ATTR_UNDER;
+                   break;
+                 case 'W':
+                   /* compatibility(VI50) */
+                   term->curr_attr &= ~ATTR_UNDER;
+                   break;
+                 case 'U':
+                   /* compatibility(VI50) */
+                   term->vt52_bold = TRUE;
+                   term->curr_attr |= ATTR_BOLD;
+                   break;
+                 case 'T':
+                   /* compatibility(VI50) */
+                   term->vt52_bold = FALSE;
+                   term->curr_attr &= ~ATTR_BOLD;
+                   break;
+#endif
+               }
+               break;
+             case VT52_Y1:
+               term->termstate = VT52_Y2;
+               move(term, term->curs.x, c - ' ', 0);
+               break;
+             case VT52_Y2:
+               term->termstate = TOPLEVEL;
+               move(term, c - ' ', term->curs.y, 0);
+               break;
+
+#ifdef VT52_PLUS
+             case VT52_FG:
+               term->termstate = TOPLEVEL;
+               term->curr_attr &= ~ATTR_FGMASK;
+               term->curr_attr &= ~ATTR_BOLD;
+               term->curr_attr |= (c & 0x7) << ATTR_FGSHIFT;
+               if ((c & 0x8) || term->vt52_bold)
+                   term->curr_attr |= ATTR_BOLD;
+
+               if (term->use_bce)
+                   term->erase_char = (' ' | ATTR_ASCII |
+                                       (term->curr_attr &
+                                        (ATTR_FGMASK | ATTR_BGMASK)));
+               break;
+             case VT52_BG:
+               term->termstate = TOPLEVEL;
+               term->curr_attr &= ~ATTR_BGMASK;
+               term->curr_attr &= ~ATTR_BLINK;
+               term->curr_attr |= (c & 0x7) << ATTR_BGSHIFT;
+
+               /* Note: bold background */
+               if (c & 0x8)
+                   term->curr_attr |= ATTR_BLINK;
+
+               if (term->use_bce)
+                   term->erase_char = (' ' | ATTR_ASCII |
+                                       (term->curr_attr &
+                                        (ATTR_FGMASK | ATTR_BGMASK)));
+               break;
+#endif
+             default: break;          /* placate gcc warning about enum use */
+           }
+       if (term->selstate != NO_SELECTION) {
+           pos cursplus = term->curs;
+           incpos(cursplus);
+           check_selection(term, term->curs, cursplus);
+       }
+    }
+
+    term_print_flush(term);
+}
+
+#if 0
+/*
+ * Compare two lines to determine whether they are sufficiently
+ * alike to scroll-optimise one to the other. Return the degree of
+ * similarity.
+ */
+static int linecmp(Terminal *term, unsigned long *a, unsigned long *b)
+{
+    int i, n;
+
+    for (i = n = 0; i < term->cols; i++)
+       n += (*a++ == *b++);
+    return n;
+}
+#endif
+
+/*
+ * Given a context, update the window. Out of paranoia, we don't
+ * allow WM_PAINT responses to do scrolling optimisations.
+ */
+static void do_paint(Terminal *term, Context ctx, int may_optimise)
+{
+    int i, j, our_curs_y, our_curs_x;
+    unsigned long rv, cursor;
+    pos scrpos;
+    char ch[1024];
+    long cursor_background = ERASE_CHAR;
+    unsigned long ticks;
+#ifdef OPTIMISE_SCROLL
+    struct scrollregion *sr;
+#endif /* OPTIMISE_SCROLL */
+
+    /*
+     * Check the visual bell state.
+     */
+    if (term->in_vbell) {
+       ticks = GETTICKCOUNT();
+       if (ticks - term->vbell_startpoint >= VBELL_TIMEOUT)
+           term->in_vbell = FALSE; 
+    }
+
+    rv = (!term->rvideo ^ !term->in_vbell ? ATTR_REVERSE : 0);
+
+    /* Depends on:
+     * screen array, disptop, scrtop,
+     * selection, rv, 
+     * cfg.blinkpc, blink_is_real, tblinker, 
+     * curs.y, curs.x, blinker, cfg.blink_cur, cursor_on, has_focus, wrapnext
+     */
+
+    /* Has the cursor position or type changed ? */
+    if (term->cursor_on) {
+       if (term->has_focus) {
+           if (term->blinker || !term->cfg.blink_cur)
+               cursor = TATTR_ACTCURS;
+           else
+               cursor = 0;
+       } else
+           cursor = TATTR_PASCURS;
+       if (term->wrapnext)
+           cursor |= TATTR_RIGHTCURS;
+    } else
+       cursor = 0;
+    our_curs_y = term->curs.y - term->disptop;
+    {
+       /*
+        * Adjust the cursor position in the case where it's
+        * resting on the right-hand half of a CJK wide character.
+        * xterm's behaviour here, which seems adequate to me, is
+        * to display the cursor covering the _whole_ character,
+        * exactly as if it were one space to the left.
+        */
+       unsigned long *ldata = lineptr(term->curs.y);
+       our_curs_x = term->curs.x;
+       if (our_curs_x > 0 &&
+           (ldata[our_curs_x] & (CHAR_MASK | CSET_MASK)) == UCSWIDE)
+           our_curs_x--;
+    }
+
+    if (term->dispcurs && (term->curstype != cursor ||
+                          term->dispcurs !=
+                          term->disptext + our_curs_y * (term->cols + 1) +
+                          our_curs_x)) {
+       if (term->dispcurs > term->disptext && 
+           (*term->dispcurs & (CHAR_MASK | CSET_MASK)) == UCSWIDE)
+           term->dispcurs[-1] |= ATTR_INVALID;
+       if ( (term->dispcurs[1] & (CHAR_MASK | CSET_MASK)) == UCSWIDE)
+           term->dispcurs[1] |= ATTR_INVALID;
+       *term->dispcurs |= ATTR_INVALID;
+       term->curstype = 0;
+    }
+    term->dispcurs = NULL;
+
+#ifdef OPTIMISE_SCROLL
+    /* Do scrolls */
+    sr = term->scrollhead;
+    while (sr) {
+       struct scrollregion *next = sr->next;
+       do_scroll(ctx, sr->topline, sr->botline, sr->lines);
+       sfree(sr);
+       sr = next;
+    }
+    term->scrollhead = term->scrolltail = NULL;
+#endif /* OPTIMISE_SCROLL */
+
+    /* The normal screen data */
+    for (i = 0; i < term->rows; i++) {
+       unsigned long *ldata;
+       unsigned long lattr;
+       int idx, dirty_line, dirty_run, selected;
+       unsigned long attr = 0;
+       int updated_line = 0;
+       int start = 0;
+       int ccount = 0;
+       int last_run_dirty = 0;
+
+       scrpos.y = i + term->disptop;
+       ldata = lineptr(scrpos.y);
+       lattr = (ldata[term->cols] & LATTR_MODE);
+
+       idx = i * (term->cols + 1);
+       dirty_run = dirty_line = (ldata[term->cols] !=
+                                 term->disptext[idx + term->cols]);
+       term->disptext[idx + term->cols] = ldata[term->cols];
+
+       for (j = 0; j < term->cols; j++, idx++) {
+           unsigned long tattr, tchar;
+           unsigned long *d = ldata + j;
+           int break_run;
+           scrpos.x = j;
+
+           tchar = (*d & (CHAR_MASK | CSET_MASK));
+           tattr = (*d & (ATTR_MASK ^ CSET_MASK));
+            // GrP fixme Don't remap any characters here for now.
+            /*
+           switch (tchar & CSET_MASK) {
+             case ATTR_ASCII:
+                tchar = term->ucsdata->unitab_line[tchar & 0xFF];
+               break;
+             case ATTR_LINEDRW:
+                tchar = term->ucsdata->unitab_xterm[tchar & 0xFF];
+               break;
+             case ATTR_SCOACS:  
+                tchar = term->ucsdata->unitab_scoacs[tchar&0xFF]; 
+               break;
+           }
+            */
+           tattr |= (tchar & CSET_MASK);
+           tchar &= CHAR_MASK;
+           if ((d[1] & (CHAR_MASK | CSET_MASK)) == UCSWIDE)
+                   tattr |= ATTR_WIDE;
+
+           /* Video reversing things */
+           if (term->selstate == DRAGGING || term->selstate == SELECTED) {
+               if (term->seltype == LEXICOGRAPHIC)
+                   selected = (posle(term->selstart, scrpos) &&
+                               poslt(scrpos, term->selend));
+               else
+                   selected = (posPle(term->selstart, scrpos) &&
+                               posPlt(scrpos, term->selend));
+           } else
+               selected = FALSE;
+           tattr = (tattr ^ rv
+                    ^ (selected ? ATTR_REVERSE : 0UL));
+
+           /* 'Real' blinking ? */
+           if (term->blink_is_real && (tattr & ATTR_BLINK)) {
+               if (term->has_focus && term->tblinker) {
+                   tchar = ' '; // term->ucsdata->unitab_line[(unsigned char)' '];
+               }
+               tattr &= ~ATTR_BLINK;
+           }
+
+           /*
+            * Check the font we'll _probably_ be using to see if 
+            * the character is wide when we don't want it to be.
+            */
+           if ((tchar | tattr) != (term->disptext[idx]& ~ATTR_NARROW)) {
+               if ((tattr & ATTR_WIDE) == 0 && 
+                   char_width(ctx, (tchar | tattr) & 0xFFFF) == 2)
+                   tattr |= ATTR_NARROW;
+           } else if (term->disptext[idx]&ATTR_NARROW)
+               tattr |= ATTR_NARROW;
+
+           /* Cursor here ? Save the 'background' */
+           if (i == our_curs_y && j == our_curs_x) {
+               cursor_background = tattr | tchar;
+               term->dispcurs = term->disptext + idx;
+           }
+
+           if ((term->disptext[idx] ^ tattr) & ATTR_WIDE)
+               dirty_line = TRUE;
+
+           break_run = (((tattr ^ attr) & term->attr_mask) ||
+               j - start >= sizeof(ch));
+
+           /* Special hack for VT100 Linedraw glyphs */
+            // GrP vt100 horizontal linedraw causes break_run to be set? (why?)
+           if ((attr & CSET_MASK) == 0x2300 && tchar >= 0xBA && tchar <= 0xBD)
+            {
+                break_run = TRUE;
+            }
+
+           if (!term->ucsdata->dbcs_screenfont && !dirty_line) {
+               if ((tchar | tattr) == term->disptext[idx])
+                   break_run = TRUE;
+               else if (!dirty_run && ccount == 1)
+                   break_run = TRUE;
+           }
+
+           if (break_run) {
+               if ((dirty_run || last_run_dirty) && ccount > 0) {
+                   do_text(ctx, start, i, ch, ccount, attr, lattr);
+                   updated_line = 1;
+               }
+               start = j;
+               ccount = 0;
+               attr = tattr;
+               if (term->ucsdata->dbcs_screenfont)
+                   last_run_dirty = dirty_run;
+               dirty_run = dirty_line;
+           }
+
+           if ((tchar | tattr) != term->disptext[idx])
+               dirty_run = TRUE;
+           ch[ccount++] = (char) tchar;
+           term->disptext[idx] = tchar | tattr;
+
+           /* If it's a wide char step along to the next one. */
+           if (tattr & ATTR_WIDE) {
+               if (++j < term->cols) {
+                   idx++;
+                   d++;
+                   /*
+                    * By construction above, the cursor should not
+                    * be on the right-hand half of this character.
+                    * Ever.
+                    */
+                   assert(!(i == our_curs_y && j == our_curs_x));
+                   if (term->disptext[idx] != *d)
+                       dirty_run = TRUE;
+                   term->disptext[idx] = *d;
+               }
+           }
+       }
+       if (dirty_run && ccount > 0) {
+           do_text(ctx, start, i, ch, ccount, attr, lattr);
+           updated_line = 1;
+       }
+
+       /* Cursor on this line ? (and changed) */
+       if (i == our_curs_y && (term->curstype != cursor || updated_line)) {
+           ch[0] = (char) (cursor_background & CHAR_MASK);
+           attr = (cursor_background & ATTR_MASK) | cursor;
+           do_cursor(ctx, our_curs_x, i, ch, 1, attr, lattr);
+           term->curstype = cursor;
+       }
+    }
+}
+
+/*
+ * Flick the switch that says if blinking things should be shown or hidden.
+ * flg=TRUE means blinking text & cursor should be set to ON
+ * Returns TRUE if terminal needs to be redrawn.
+ */
+
+int term_blink(Terminal *term, int flg)
+{
+    long now, blink_diff;
+
+    now = GETTICKCOUNT();
+    blink_diff = now - term->last_tblink;
+
+    /* Make sure the text blinks no more than 2Hz; we'll use 0.45 s period. */
+    if (blink_diff < 0 || blink_diff > (TICKSPERSEC * 9 / 20)) {
+       term->last_tblink = now;
+       term->tblinker = !term->tblinker;
+    }
+
+    if (flg) {
+       term->blinker = 1;
+       term->last_blink = now;
+       return TRUE;
+    }
+
+    blink_diff = now - term->last_blink;
+
+    /* Make sure the cursor blinks no faster than system blink rate */
+    if (blink_diff >= 0 && blink_diff < (long) CURSORBLINK)
+       return FALSE;
+
+    term->last_blink = now;
+    term->blinker = !term->blinker;
+    return TRUE;
+}
+
+
+void term_task(Terminal *term)
+{
+    int redraw = 0;
+
+    /* Blink stuff */
+    // fixme need to optimize term_update
+    // if (term_blink(term, 0)) redraw = TRUE;
+
+    /* Paste stuff */
+    term_paste(term);
+
+    /* Clear visual bell */
+    if (term->in_vbell) {
+       unsigned long ticks = GETTICKCOUNT();
+       if (ticks - term->vbell_startpoint >= VBELL_TIMEOUT) {
+           term->in_vbell = FALSE; 
+            redraw = TRUE;
+        }
+    }
+
+    if (redraw) {
+        refresh_window(term->frontend);
+    }
+}
+
+
+/*
+ * Invalidate the whole screen so it will be repainted in full.
+ */
+void term_invalidate(Terminal *term)
+{
+    int i;
+
+    for (i = 0; i < term->rows * (term->cols + 1); i++)
+       term->disptext[i] = ATTR_INVALID;
+}
+
+/*
+ * Paint the window in response to a WM_PAINT message.
+ */
+void term_paint(Terminal *term, Context ctx,
+               int left, int top, int right, int bottom, int immediately)
+{
+    int i, j;
+    if (left < 0) left = 0;
+    if (top < 0) top = 0;
+    if (right >= term->cols) right = term->cols-1;
+    if (bottom >= term->rows) bottom = term->rows-1;
+
+    for (i = top; i <= bottom && i < term->rows; i++) {
+       if ((term->disptext[i * (term->cols + 1) + term->cols] &
+            LATTR_MODE) == LATTR_NORM)
+           for (j = left; j <= right && j < term->cols; j++)
+               term->disptext[i * (term->cols + 1) + j] = ATTR_INVALID;
+       else
+           for (j = left / 2; j <= right / 2 + 1 && j < term->cols; j++)
+               term->disptext[i * (term->cols + 1) + j] = ATTR_INVALID;
+    }
+
+    /* This should happen soon enough, also for some reason it sometimes 
+     * fails to actually do anything when re-sizing ... painting the wrong
+     * window perhaps ?
+     */
+    if (immediately)
+        do_paint (term, ctx, FALSE);
+}
+
+/*
+ * Attempt to scroll the scrollback. The second parameter gives the
+ * position we want to scroll to; the first is +1 to denote that
+ * this position is relative to the beginning of the scrollback, -1
+ * to denote it is relative to the end, and 0 to denote that it is
+ * relative to the current position.
+ */
+void term_scroll(Terminal *term, int rel, int where)
+{
+    int sbtop = -sblines(term);
+#ifdef OPTIMISE_SCROLL
+    int olddisptop = term->disptop;
+    int shift;
+#endif /* OPTIMISE_SCROLL */
+
+    term->disptop = (rel < 0 ? 0 : rel > 0 ? sbtop : term->disptop) + where;
+    if (term->disptop < sbtop)
+       term->disptop = sbtop;
+    if (term->disptop > 0)
+       term->disptop = 0;
+    update_sbar(term);
+#ifdef OPTIMISE_SCROLL
+    shift = (term->disptop - olddisptop);
+    if (shift < term->rows && shift > -term->rows)
+       scroll_display(term, 0, term->rows - 1, shift);
+#endif /* OPTIMISE_SCROLL */
+    term_update(term);
+}
+
+static void clipme(Terminal *term, pos top, pos bottom, int rect, int desel)
+{
+    // GrP fixme wide char support stripped
+    char *workbuf;
+    char *wbptr;                      /* where next char goes within workbuf */
+    int old_top_x;
+    int wblen = 0;                    /* workbuf len */
+    int buflen;                               /* amount of memory allocated to workbuf */
+
+    buflen = 5120;                    /* Default size */
+    workbuf = snewn(buflen, char);
+    wbptr = workbuf;                  /* start filling here */
+    old_top_x = top.x;                /* needed for rect==1 */
+
+    while (poslt(top, bottom)) {
+       int nl = FALSE;
+       unsigned long *ldata = lineptr(top.y);
+       pos nlpos;
+
+       /*
+        * nlpos will point at the maximum position on this line we
+        * should copy up to. So we start it at the end of the
+        * line...
+        */
+       nlpos.y = top.y;
+       nlpos.x = term->cols;
+
+       /*
+        * ... move it backwards if there's unused space at the end
+        * of the line (and also set `nl' if this is the case,
+        * because in normal selection mode this means we need a
+        * newline at the end)...
+        */
+       if (!(ldata[term->cols] & LATTR_WRAPPED)) {
+           while (((ldata[nlpos.x - 1] & 0xFF) == 0x20 ||
+                   (DIRECT_CHAR(ldata[nlpos.x - 1]) &&
+                    (ldata[nlpos.x - 1] & CHAR_MASK) == 0x20))
+                  && poslt(top, nlpos))
+               decpos(nlpos);
+           if (poslt(nlpos, bottom))
+               nl = TRUE;
+       } else if (ldata[term->cols] & LATTR_WRAPPED2) {
+           /* Ignore the last char on the line in a WRAPPED2 line. */
+           decpos(nlpos);
+       }
+
+       /*
+        * ... and then clip it to the terminal x coordinate if
+        * we're doing rectangular selection. (In this case we
+        * still did the above, so that copying e.g. the right-hand
+        * column from a table doesn't fill with spaces on the
+        * right.)
+        */
+       if (rect) {
+           if (nlpos.x > bottom.x)
+               nlpos.x = bottom.x;
+           nl = (top.y < bottom.y);
+       }
+
+       while (poslt(top, bottom) && poslt(top, nlpos)) {
+           unsigned int uc = (ldata[top.x] & 0xFFFF);
+
+           if (uc == UCSWIDE) {
+               top.x++;
+               continue;
+           }
+
+            // GrP fixme No character remapping on cut&paste for now
+            /*
+           switch (uc & CSET_MASK) {
+             case ATTR_LINEDRW:
+               if (!term->cfg.rawcnp) {
+                   uc = term->ucsdata->unitab_xterm[uc & 0xFF];
+                   break;
+               }
+             case ATTR_ASCII:
+               uc = term->ucsdata->unitab_line[uc & 0xFF];
+               break;
+             case ATTR_SCOACS:  
+               uc = term->ucsdata->unitab_scoacs[uc&0xFF]; 
+               break;
+           }
+           switch (uc & CSET_MASK) {
+             case ATTR_ACP:
+               uc = term->ucsdata->unitab_font[uc & 0xFF];
+               break;
+             case ATTR_OEMCP:
+               uc = term->ucsdata->unitab_oemcp[uc & 0xFF];
+               break;
+            }
+            */
+
+            // GrP fixme stripped multibyte handling
+            if (wblen >= buflen - 16) {
+                buflen += 100;
+                workbuf = sresize(workbuf, buflen, wchar_t);
+                wbptr = workbuf + wblen;
+            }
+            wblen++;
+            *wbptr++ = uc & 0xff;
+
+           top.x++;
+       }
+       if (nl) {
+           unsigned int i;
+           for (i = 0; i < sel_nl_sz; i++) {
+               wblen++;
+               *wbptr++ = sel_nl[i];
+           }
+       }
+       top.y++;
+       top.x = rect ? old_top_x : 0;
+    }
+#if SELECTION_NUL_TERMINATED
+    wblen++;
+    *wbptr++ = 0;
+#endif
+    write_clip(term->frontend, workbuf, wblen, desel); /* transfer to clipbd */
+    if (buflen > 0)                   /* indicates we allocated this buffer */
+       sfree(workbuf);
+}
+
+void term_copyall(Terminal *term)
+{
+    pos top;
+    top.y = -sblines(term);
+    top.x = 0;
+    clipme(term, top, term->curs, 0, TRUE);
+}
+
+/*
+ * The wordness array is mainly for deciding the disposition of the
+ * US-ASCII characters.
+ */
+static int wordtype(Terminal *term, uint32_t uc)
+{
+    struct ucsword {
+       unsigned int start, end, ctype;
+    };
+    static const struct ucsword ucs_words[] = {
+       {
+       128, 160, 0}, {
+       161, 191, 1}, {
+       215, 215, 1}, {
+       247, 247, 1}, {
+       0x037e, 0x037e, 1},            /* Greek question mark */
+       {
+       0x0387, 0x0387, 1},            /* Greek ano teleia */
+       {
+       0x055a, 0x055f, 1},            /* Armenian punctuation */
+       {
+       0x0589, 0x0589, 1},            /* Armenian full stop */
+       {
+       0x0700, 0x070d, 1},            /* Syriac punctuation */
+       {
+       0x104a, 0x104f, 1},            /* Myanmar punctuation */
+       {
+       0x10fb, 0x10fb, 1},            /* Georgian punctuation */
+       {
+       0x1361, 0x1368, 1},            /* Ethiopic punctuation */
+       {
+       0x166d, 0x166e, 1},            /* Canadian Syl. punctuation */
+       {
+       0x17d4, 0x17dc, 1},            /* Khmer punctuation */
+       {
+       0x1800, 0x180a, 1},            /* Mongolian punctuation */
+       {
+       0x2000, 0x200a, 0},            /* Various spaces */
+       {
+       0x2070, 0x207f, 2},            /* superscript */
+       {
+       0x2080, 0x208f, 2},            /* subscript */
+       {
+       0x200b, 0x27ff, 1},            /* punctuation and symbols */
+       {
+       0x3000, 0x3000, 0},            /* ideographic space */
+       {
+       0x3001, 0x3020, 1},            /* ideographic punctuation */
+       {
+       0x303f, 0x309f, 3},            /* Hiragana */
+       {
+       0x30a0, 0x30ff, 3},            /* Katakana */
+       {
+       0x3300, 0x9fff, 3},            /* CJK Ideographs */
+       {
+       0xac00, 0xd7a3, 3},            /* Hangul Syllables */
+       {
+       0xf900, 0xfaff, 3},            /* CJK Ideographs */
+       {
+       0xfe30, 0xfe6b, 1},            /* punctuation forms */
+       {
+       0xff00, 0xff0f, 1},            /* half/fullwidth ASCII */
+       {
+       0xff1a, 0xff20, 1},            /* half/fullwidth ASCII */
+       {
+       0xff3b, 0xff40, 1},            /* half/fullwidth ASCII */
+       {
+       0xff5b, 0xff64, 1},            /* half/fullwidth ASCII */
+       {
+       0xfff0, 0xffff, 0},            /* half/fullwidth ASCII */
+       {
+       0, 0, 0}
+    };
+    const struct ucsword *wptr;
+
+    uc &= (CSET_MASK | CHAR_MASK);
+
+    // GrP fixme No character remapping on cut&paste for now
+    /* 
+    switch (uc & CSET_MASK) {
+      case ATTR_LINEDRW:
+       uc = term->ucsdata->unitab_xterm[uc & 0xFF];
+       break;
+      case ATTR_ASCII:
+       uc = term->ucsdata->unitab_line[uc & 0xFF];
+       break;
+      case ATTR_SCOACS:  
+       uc = term->ucsdata->unitab_scoacs[uc&0xFF]; 
+       break;
+    }
+    switch (uc & CSET_MASK) {
+      case ATTR_ACP:
+       uc = term->ucsdata->unitab_font[uc & 0xFF];
+       break;
+      case ATTR_OEMCP:
+       uc = term->ucsdata->unitab_oemcp[uc & 0xFF];
+       break;
+    }
+    */
+
+    /* For DBCS font's I can't do anything usefull. Even this will sometimes
+     * fail as there's such a thing as a double width space. :-(
+     */
+    if (term->ucsdata->dbcs_screenfont &&
+       term->ucsdata->font_codepage == term->ucsdata->line_codepage)
+       return (uc != ' ');
+
+    if (uc < 0x80)
+       return term->wordness[uc];
+
+    for (wptr = ucs_words; wptr->start; wptr++) {
+       if (uc >= wptr->start && uc <= wptr->end)
+           return wptr->ctype;
+    }
+
+    return 2;
+}
+
+/*
+ * Spread the selection outwards according to the selection mode.
+ */
+static pos sel_spread_half(Terminal *term, pos p, int dir)
+{
+    unsigned long *ldata;
+    short wvalue;
+    int topy = -sblines(term);
+
+    ldata = lineptr(p.y);
+
+    switch (term->selmode) {
+      case SM_CHAR:
+       /*
+        * In this mode, every character is a separate unit, except
+        * for runs of spaces at the end of a non-wrapping line.
+        */
+       if (!(ldata[term->cols] & LATTR_WRAPPED)) {
+           unsigned long *q = ldata + term->cols;
+           while (q > ldata && (q[-1] & CHAR_MASK) == 0x20)
+               q--;
+           if (q == ldata + term->cols)
+               q--;
+           if (p.x >= q - ldata)
+               p.x = (dir == -1 ? q - ldata : term->cols - 1);
+       }
+       break;
+      case SM_WORD:
+       /*
+        * In this mode, the units are maximal runs of characters
+        * whose `wordness' has the same value.
+        */
+       wvalue = wordtype(term, UCSGET(ldata, p.x));
+       if (dir == +1) {
+           while (1) {
+               int maxcols = (ldata[term->cols] & LATTR_WRAPPED2 ?
+                              term->cols-1 : term->cols);
+               if (p.x < maxcols-1) {
+                   if (wordtype(term, UCSGET(ldata, p.x + 1)) == wvalue)
+                       p.x++;
+                   else
+                       break;
+               } else {
+                   if (ldata[term->cols] & LATTR_WRAPPED) {
+                       unsigned long *ldata2;
+                       ldata2 = lineptr(p.y+1);
+                       if (wordtype(term, UCSGET(ldata2, 0)) == wvalue) {
+                           p.x = 0;
+                           p.y++;
+                           ldata = ldata2;
+                       } else
+                           break;
+                   } else
+                       break;
+               }
+           }
+       } else {
+           while (1) {
+               if (p.x > 0) {
+                   if (wordtype(term, UCSGET(ldata, p.x - 1)) == wvalue)
+                       p.x--;
+                   else
+                       break;
+               } else {
+                   unsigned long *ldata2;
+                   int maxcols;
+                   if (p.y <= topy)
+                       break;
+                   ldata2 = lineptr(p.y-1);
+                   maxcols = (ldata2[term->cols] & LATTR_WRAPPED2 ?
+                             term->cols-1 : term->cols);
+                   if (ldata2[term->cols] & LATTR_WRAPPED) {
+                       if (wordtype(term, UCSGET(ldata2, maxcols-1))
+                           == wvalue) {
+                           p.x = maxcols-1;
+                           p.y--;
+                           ldata = ldata2;
+                       } else
+                           break;
+                   } else
+                       break;
+               }
+           }
+       }
+       break;
+      case SM_LINE:
+       /*
+        * In this mode, every line is a unit.
+        */
+       p.x = (dir == -1 ? 0 : term->cols - 1);
+       break;
+    }
+    return p;
+}
+
+static void sel_spread(Terminal *term)
+{
+    if (term->seltype == LEXICOGRAPHIC) {
+       term->selstart = sel_spread_half(term, term->selstart, -1);
+       decpos(term->selend);
+       term->selend = sel_spread_half(term, term->selend, +1);
+       incpos(term->selend);
+    }
+}
+
+void term_do_paste(Terminal *term)
+{
+    wchar_t *data;
+    size_t len;
+
+    get_clip(term->frontend, &data, &len);
+    if (data && len > 0) {
+        wchar_t *p, *q;
+
+       term_seen_key_event(term);     /* pasted data counts */
+
+        if (term->paste_buffer)
+            sfree(term->paste_buffer);
+        term->paste_pos = term->paste_hold = term->paste_len = 0;
+        term->paste_buffer = snewn(len, wchar_t);
+
+        p = q = data;
+        while (p < data + len) {
+            while (p < data + len &&
+                   !(p <= data + len - sel_nl_sz &&
+                     !memcmp(p, sel_nl, sizeof(sel_nl))))
+                p++;
+
+            {
+                int i;
+                for (i = 0; i < p - q; i++) {
+                    term->paste_buffer[term->paste_len++] = q[i];
+                }
+            }
+
+            if (p <= data + len - sel_nl_sz &&
+                !memcmp(p, sel_nl, sizeof(sel_nl))) {
+                term->paste_buffer[term->paste_len++] = '\015';
+                p += sel_nl_sz;
+            }
+            q = p;
+        }
+
+        /* Assume a small paste will be OK in one go. */
+        if (term->paste_len < 256) {
+            if (term->ldisc)
+               luni_send(term->ldisc, term->paste_buffer, term->paste_len, 0);
+            if (term->paste_buffer)
+                sfree(term->paste_buffer);
+            term->paste_buffer = 0;
+            term->paste_pos = term->paste_hold = term->paste_len = 0;
+        }
+    }
+    get_clip(term->frontend, NULL, NULL);
+}
+
+void term_mouse(Terminal *term, Mouse_Button braw, Mouse_Button bcooked,
+               Mouse_Action a, int x, int y, int shift, int ctrl, int alt)
+{
+    pos selpoint;
+    unsigned long *ldata;
+    int raw_mouse = (term->xterm_mouse &&
+                    !term->cfg.no_mouse_rep &&
+                    !(term->cfg.mouse_override && shift));
+    int default_seltype;
+
+    if (y < 0) {
+       y = 0;
+       if (a == MA_DRAG && !raw_mouse)
+           term_scroll(term, 0, -1);
+    }
+    if (y >= term->rows) {
+       y = term->rows - 1;
+       if (a == MA_DRAG && !raw_mouse)
+           term_scroll(term, 0, +1);
+    }
+    if (x < 0) {
+       if (y > 0) {
+           x = term->cols - 1;
+           y--;
+       } else
+           x = 0;
+    }
+    if (x >= term->cols)
+       x = term->cols - 1;
+
+    selpoint.y = y + term->disptop;
+    selpoint.x = x;
+    ldata = lineptr(selpoint.y);
+    if ((ldata[term->cols] & LATTR_MODE) != LATTR_NORM)
+       selpoint.x /= 2;
+
+    if (raw_mouse) {
+       int encstate = 0, r, c;
+       char abuf[16];
+
+       if (term->ldisc) {
+
+           switch (braw) {
+             case MBT_LEFT:
+               encstate = 0x20;               /* left button down */
+               break;
+             case MBT_MIDDLE:
+               encstate = 0x21;
+               break;
+             case MBT_RIGHT:
+               encstate = 0x22;
+               break;
+             case MBT_WHEEL_UP:
+               encstate = 0x60;
+               break;
+             case MBT_WHEEL_DOWN:
+               encstate = 0x61;
+               break;
+             default: break;          /* placate gcc warning about enum use */
+           }
+           switch (a) {
+             case MA_DRAG:
+               if (term->xterm_mouse == 1)
+                   return;
+               encstate += 0x20;
+               break;
+             case MA_RELEASE:
+               encstate = 0x23;
+               term->mouse_is_down = 0;
+               break;
+             case MA_CLICK:
+               if (term->mouse_is_down == braw)
+                   return;
+               term->mouse_is_down = braw;
+               break;
+             default: break;          /* placate gcc warning about enum use */
+           }
+           if (shift)
+               encstate += 0x04;
+           if (ctrl)
+               encstate += 0x10;
+           r = y + 33;
+           c = x + 33;
+
+           snprintf(abuf, sizeof(abuf), "\033[M%c%c%c", encstate, c, r);
+           ldisc_send(term->ldisc, abuf, 6, 0);
+       }
+       return;
+    }
+
+    /*
+     * Set the selection type (rectangular or normal) at the start
+     * of a selection attempt, from the state of Alt.
+     */
+    if (!alt ^ !term->cfg.rect_select)
+       default_seltype = RECTANGULAR;
+    else
+       default_seltype = LEXICOGRAPHIC;
+       
+    if (term->selstate == NO_SELECTION) {
+       term->seltype = default_seltype;
+    }
+
+    if (bcooked == MBT_SELECT && a == MA_CLICK) {
+       deselect(term);
+       term->selstate = ABOUT_TO;
+       term->seltype = default_seltype;
+       term->selanchor = selpoint;
+       term->selmode = SM_CHAR;
+    } else if (bcooked == MBT_SELECT && (a == MA_2CLK || a == MA_3CLK)) {
+       deselect(term);
+       term->selmode = (a == MA_2CLK ? SM_WORD : SM_LINE);
+       term->selstate = DRAGGING;
+       term->selstart = term->selanchor = selpoint;
+       term->selend = term->selstart;
+       incpos(term->selend);
+       sel_spread(term);
+    } else if ((bcooked == MBT_SELECT && a == MA_DRAG) ||
+              (bcooked == MBT_EXTEND && a != MA_RELEASE)) {
+       if (term->selstate == ABOUT_TO && poseq(term->selanchor, selpoint))
+           return;
+       if (bcooked == MBT_EXTEND && a != MA_DRAG &&
+           term->selstate == SELECTED) {
+           if (term->seltype == LEXICOGRAPHIC) {
+               /*
+                * For normal selection, we extend by moving
+                * whichever end of the current selection is closer
+                * to the mouse.
+                */
+               if (posdiff(selpoint, term->selstart) <
+                   posdiff(term->selend, term->selstart) / 2) {
+                   term->selanchor = term->selend;
+                   decpos(term->selanchor);
+               } else {
+                   term->selanchor = term->selstart;
+               }
+           } else {
+               /*
+                * For rectangular selection, we have a choice of
+                * _four_ places to put selanchor and selpoint: the
+                * four corners of the selection.
+                */
+               if (2*selpoint.x < term->selstart.x + term->selend.x)
+                   term->selanchor.x = term->selend.x-1;
+               else
+                   term->selanchor.x = term->selstart.x;
+
+               if (2*selpoint.y < term->selstart.y + term->selend.y)
+                   term->selanchor.y = term->selend.y;
+               else
+                   term->selanchor.y = term->selstart.y;
+           }
+           term->selstate = DRAGGING;
+       }
+       if (term->selstate != ABOUT_TO && term->selstate != DRAGGING)
+           term->selanchor = selpoint;
+       term->selstate = DRAGGING;
+       if (term->seltype == LEXICOGRAPHIC) {
+           /*
+            * For normal selection, we set (selstart,selend) to
+            * (selpoint,selanchor) in some order.
+            */
+           if (poslt(selpoint, term->selanchor)) {
+               term->selstart = selpoint;
+               term->selend = term->selanchor;
+               incpos(term->selend);
+           } else {
+               term->selstart = term->selanchor;
+               term->selend = selpoint;
+               incpos(term->selend);
+           }
+       } else {
+           /*
+            * For rectangular selection, we may need to
+            * interchange x and y coordinates (if the user has
+            * dragged in the -x and +y directions, or vice versa).
+            */
+           term->selstart.x = min(term->selanchor.x, selpoint.x);
+           term->selend.x = 1+max(term->selanchor.x, selpoint.x);
+           term->selstart.y = min(term->selanchor.y, selpoint.y);
+           term->selend.y =   max(term->selanchor.y, selpoint.y);
+       }
+       sel_spread(term);
+    } else if ((bcooked == MBT_SELECT || bcooked == MBT_EXTEND) &&
+              a == MA_RELEASE) {
+       if (term->selstate == DRAGGING) {
+           /*
+            * We've completed a selection. We now transfer the
+            * data to the clipboard.
+            */
+            /* GrP no we don't, we use term_copy to grab it later */
+            /* GrP Only set SELECTED if selection isn't empty */
+           if (poseq(term->selstart, term->selend)) deselect(term);
+           else term->selstate = SELECTED;
+       } else
+           deselect(term); /* GrP fix deselection */
+    } else if (bcooked == MBT_PASTE
+              && (a == MA_CLICK
+#if MULTICLICK_ONLY_EVENT
+                  || a == MA_2CLK || a == MA_3CLK
+#endif
+                  )) {
+       request_paste(term->frontend);
+    }
+
+    term_update(term);
+}
+
+
+#if 0
+static char const scocodes[] =
+            "MNOPQRSTUVWX" "YZabcdefghij" "klmnopqrstuv" "wxyz@[\\]^_`{";
+
+void term_key(Terminal *term, Key_Sym keysym, wchar_t *text, size_t tlen,
+             unsigned int modifiers, unsigned int flags)
+{
+    char output[10];
+    char *p = output;
+    int prependesc = FALSE;
+#if 0
+    int i;
+
+    fprintf(stderr, "keysym = %d, %d chars:", keysym, tlen);
+    for (i = 0; i < tlen; i++)
+       fprintf(stderr, " %04x", (unsigned)text[i]);
+    fprintf(stderr, "\n");
+#endif
+
+    /* XXX Num Lock */
+    if ((flags & PKF_REPEAT) && term->repeat_off)
+       return;
+
+    /* Currently, Meta always just prefixes everything with ESC. */
+    if (modifiers & PKM_META)
+       prependesc = TRUE;
+    modifiers &= ~PKM_META;
+
+    /*
+     * Alt is only used for Alt+keypad, which isn't supported yet, so
+     * ignore it.
+     */
+    modifiers &= ~PKM_ALT;
+
+    /* Standard local function keys */
+    switch (modifiers & (PKM_SHIFT | PKM_CONTROL)) {
+      case PKM_SHIFT:
+       if (keysym == PK_PAGEUP) { 
+           /* scroll up one page */ 
+       }
+       if (keysym == PK_PAGEDOWN) { 
+           /* scroll down on page */ 
+       }
+       if (keysym == PK_INSERT) { 
+           term_do_paste(term);
+       }
+       break;
+      case PKM_CONTROL:
+       if (keysym == PK_PAGEUP) { 
+           /* scroll up one line */ 
+       }
+       if (keysym == PK_PAGEDOWN) { 
+           /* scroll down one line */ 
+       }
+       if (keysym == PK_PF1) {
+           /* Control-Numlock for app-keypad mode switch */
+           term->app_keypad_keys ^= 1;
+       }
+       break;
+    }
+
+    if (modifiers & PKM_ALT) {
+       /* Alt+F4 (close) */
+       /* Alt+Return (full screen) */
+       /* Alt+Space (system menu) */
+    }
+
+    if (keysym == PK_NULL && (modifiers & PKM_CONTROL) && tlen == 1 &&
+       text[0] >= 0x20 && text[0] <= 0x7e) {
+       /* ASCII chars + Control */
+       if ((text[0] >= 0x40 && text[0] <= 0x5f) ||
+           (text[0] >= 0x61 && text[0] <= 0x7a))
+           text[0] &= 0x1f;
+       else {
+           /*
+            * Control-2 should return ^@ (0x00), Control-6 should return
+            * ^^ (0x1E), and Control-Minus should return ^_ (0x1F). Since
+            * the DOS keyboard handling did it, and we have nothing better
+            * to do with the key combo in question, we'll also map
+            * Control-Backquote to ^\ (0x1C).
+            */
+           switch (text[0]) {
+             case ' ': text[0] = 0x00; break;
+             case '-': text[0] = 0x1f; break;
+             case '/': text[0] = 0x1f; break;
+             case '2': text[0] = 0x00; break;
+             case '3': text[0] = 0x1b; break;
+             case '4': text[0] = 0x1c; break;
+             case '5': text[0] = 0x1d; break;
+             case '6': text[0] = 0x1e; break;
+             case '7': text[0] = 0x1f; break;
+             case '8': text[0] = 0x7f; break;
+             case '`': text[0] = 0x1c; break;
+           }
+       }
+    }
+
+    /* Nethack keypad */
+    if (term->cfg.nethack_keypad) {
+       char c = 0;
+       switch (keysym) {
+         case PK_KP1: c = 'b'; break;
+         case PK_KP2: c = 'j'; break;
+         case PK_KP3: c = 'n'; break;
+         case PK_KP4: c = 'h'; break;
+         case PK_KP5: c = '.'; break;
+         case PK_KP6: c = 'l'; break;
+         case PK_KP7: c = 'y'; break;
+         case PK_KP8: c = 'k'; break;
+         case PK_KP9: c = 'u'; break;
+         default: break; /* else gcc warns `enum value not used' */
+       }
+       if (c != 0) {
+           if (c != '.') {
+               if (modifiers & PKM_CONTROL)
+                   c &= 0x1f;
+               else if (modifiers & PKM_SHIFT)
+                   c = toupper(c);
+           }
+           *p++ = c;
+           goto done;
+       }
+    }
+
+    /* Numeric Keypad */
+    if (PK_ISKEYPAD(keysym)) {
+       int xkey = 0;
+
+       /*
+        * In VT400 mode, PFn always emits an escape sequence.  In
+        * Linux and tilde modes, this only happens in app keypad mode.
+        */
+       if (term->cfg.funky_type == FUNKY_VT400 ||
+           ((term->cfg.funky_type == FUNKY_LINUX ||
+             term->cfg.funky_type == FUNKY_TILDE) &&
+            term->app_keypad_keys && !term->cfg.no_applic_k)) {
+           switch (keysym) {
+             case PK_PF1: xkey = 'P'; break;
+             case PK_PF2: xkey = 'Q'; break;
+             case PK_PF3: xkey = 'R'; break;
+             case PK_PF4: xkey = 'S'; break;
+             default: break; /* else gcc warns `enum value not used' */
+           }
+       }
+       if (term->app_keypad_keys && !term->cfg.no_applic_k) {
+           switch (keysym) {
+             case PK_KP0: xkey = 'p'; break;
+             case PK_KP1: xkey = 'q'; break;
+             case PK_KP2: xkey = 'r'; break;
+             case PK_KP3: xkey = 's'; break;
+             case PK_KP4: xkey = 't'; break;
+             case PK_KP5: xkey = 'u'; break;
+             case PK_KP6: xkey = 'v'; break;
+             case PK_KP7: xkey = 'w'; break;
+             case PK_KP8: xkey = 'x'; break;
+             case PK_KP9: xkey = 'y'; break;
+             case PK_KPDECIMAL: xkey = 'n'; break;
+             case PK_KPENTER: xkey = 'M'; break;
+             default: break; /* else gcc warns `enum value not used' */
+           }
+           if (term->cfg.funky_type == FUNKY_XTERM && tlen > 0) {
+               /*
+                * xterm can't see the layout of the keypad, so it has
+                * to rely on the X keysyms returned by the keys.
+                * Hence, we look at the strings here, not the PuTTY
+                * keysyms (which describe the layout).
+                */
+               switch (text[0]) {
+                 case '+':
+                   if (modifiers & PKM_SHIFT)
+                       xkey = 'l';
+                   else
+                       xkey = 'k';
+                   break;
+                 case '/': xkey = 'o'; break;
+                 case '*': xkey = 'j'; break;
+                 case '-': xkey = 'm'; break;
+               }
+           } else {
+               /*
+                * In all other modes, we try to retain the layout of
+                * the DEC keypad in application mode.
+                */
+               switch (keysym) {
+                 case PK_KPBIGPLUS:
+                   /* This key covers the '-' and ',' keys on a VT220 */
+                   if (modifiers & PKM_SHIFT)
+                       xkey = 'm'; /* VT220 '-' */
+                   else
+                       xkey = 'l'; /* VT220 ',' */
+                   break;
+                 case PK_KPMINUS: xkey = 'm'; break;
+                 case PK_KPCOMMA: xkey = 'l'; break;
+                 default: break; /* else gcc warns `enum value not used' */
+               }
+           }
+       }
+       if (xkey) {
+           if (term->vt52_mode) {
+               if (xkey >= 'P' && xkey <= 'S')
+                   p += snprintf((char *) p, sizeof(output)-(p-output), "\x1B%c", xkey);
+               else
+                   p += snprintf((char *) p, sizeof(output)-(p-output), "\x1B?%c", xkey);
+           } else
+               p += snprintf((char *) p, sizeof(output)-(p-output), "\x1BO%c", xkey);
+           goto done;
+       }
+       /* Not in application mode -- treat the number pad as arrow keys? */
+       if ((flags & PKF_NUMLOCK) == 0) {
+           switch (keysym) {
+             case PK_KP0: keysym = PK_INSERT; break;
+             case PK_KP1: keysym = PK_END; break;
+             case PK_KP2: keysym = PK_DOWN; break;
+             case PK_KP3: keysym = PK_PAGEDOWN; break;
+             case PK_KP4: keysym = PK_LEFT; break;
+             case PK_KP5: keysym = PK_REST; break;
+             case PK_KP6: keysym = PK_RIGHT; break;
+             case PK_KP7: keysym = PK_HOME; break;
+             case PK_KP8: keysym = PK_UP; break;
+             case PK_KP9: keysym = PK_PAGEUP; break;
+             default: break; /* else gcc warns `enum value not used' */
+           }
+       }
+    }
+
+    /* Miscellaneous keys */
+    switch (keysym) {
+      case PK_ESCAPE:
+       *p++ = 0x1b;
+       goto done;
+      case PK_BACKSPACE:
+           if (modifiers == 0)
+               *p++ = (term->cfg.bksp_is_delete ? 0x7F : 0x08);
+           else if (modifiers == PKM_SHIFT)
+               /* We do the opposite of what is configured */
+               *p++ = (term->cfg.bksp_is_delete ? 0x08 : 0x7F);
+           else break;
+           goto done;
+      case PK_TAB:
+       if (modifiers == 0)
+           *p++ = 0x09;
+       else if (modifiers == PKM_SHIFT)
+           *p++ = 0x1B, *p++ = '[', *p++ = 'Z';
+       else break;
+       goto done;
+       /* XXX window.c has ctrl+shift+space sending 0xa0 */
+      case PK_PAUSE:
+       if (modifiers == PKM_CONTROL)
+           *p++ = 26;
+       else break;
+       goto done;
+      case PK_RETURN:
+      case PK_KPENTER: /* Odd keypad modes handled above */
+       if (modifiers == 0) {
+           *p++ = 0x0d;
+           if (term->cr_lf_return)
+               *p++ = 0x0a;
+           goto done;
+       }
+      default: break; /* else gcc warns `enum value not used' */
+    }
+
+    /* SCO function keys and editing keys */
+    if (term->cfg.funky_type == FUNKY_SCO) {
+       if (PK_ISFKEY(keysym) && keysym <= PK_F12) {
+           int index = keysym - PK_F1;
+
+           if (modifiers & PKM_SHIFT) index += 12;
+           if (modifiers & PKM_CONTROL) index += 24;
+           p += snprintf((char *) p, sizeof(output)-(p-output), "\x1B[%c", scocodes[index]);
+           goto done;
+       }
+       if (PK_ISEDITING(keysym)) {
+           int xkey = 0;
+
+           switch (keysym) {
+             case PK_DELETE:   *p++ = 0x7f; goto done;
+             case PK_HOME:     xkey = 'H'; break;
+             case PK_INSERT:   xkey = 'L'; break;
+             case PK_END:      xkey = 'F'; break;
+             case PK_PAGEUP:   xkey = 'I'; break;
+             case PK_PAGEDOWN: xkey = 'G'; break;
+             default: break; /* else gcc warns `enum value not used' */
+           }
+           p += snprintf((char *) p, sizeof(output)-(p-output), "\x1B[%c", xkey);
+       }
+    }
+
+    if (PK_ISEDITING(keysym) && (modifiers & PKM_SHIFT) == 0) {
+       int code;
+
+       if (term->cfg.funky_type == FUNKY_XTERM) {
+           /* Xterm shuffles these keys, apparently. */
+           switch (keysym) {
+             case PK_HOME:     keysym = PK_INSERT;   break;
+             case PK_INSERT:   keysym = PK_HOME;     break;
+             case PK_DELETE:   keysym = PK_END;      break;
+             case PK_END:      keysym = PK_PAGEUP;   break;
+             case PK_PAGEUP:   keysym = PK_DELETE;   break;
+             case PK_PAGEDOWN: keysym = PK_PAGEDOWN; break;
+             default: break; /* else gcc warns `enum value not used' */
+           }
+       }
+
+       /* RXVT Home/End */
+       if (term->cfg.rxvt_homeend &&
+           (keysym == PK_HOME || keysym == PK_END)) {
+           p += snprintf((char *) p, sizeof(output)-(p-output), keysym == PK_HOME ? "\x1B[H" : "\x1BOw");
+           goto done;
+       }
+
+       if (term->vt52_mode) {
+           int xkey;
+
+           /*
+            * A real VT52 doesn't have these, and a VT220 doesn't
+            * send anything for them in VT52 mode.
+            */
+           switch (keysym) {
+             case PK_HOME:     xkey = 'H'; break;
+             case PK_INSERT:   xkey = 'L'; break;
+             case PK_DELETE:   xkey = 'M'; break;
+             case PK_END:      xkey = 'E'; break;
+             case PK_PAGEUP:   xkey = 'I'; break;
+             case PK_PAGEDOWN: xkey = 'G'; break;
+             default: xkey=0; break; /* else gcc warns `enum value not used'*/
+           }
+           p += snprintf((char *) p, sizeof(output)-(p-output), "\x1B%c", xkey);
+           goto done;
+       }
+
+       switch (keysym) {
+         case PK_HOME:     code = 1; break;
+         case PK_INSERT:   code = 2; break;
+         case PK_DELETE:   code = 3; break;
+         case PK_END:      code = 4; break;
+         case PK_PAGEUP:   code = 5; break;
+         case PK_PAGEDOWN: code = 6; break;
+         default: code = 0; break; /* else gcc warns `enum value not used' */
+       }
+       p += snprintf((char *) p, sizeof(output)-(p-output), "\x1B[%d~", code);
+       goto done;
+    }
+
+    if (PK_ISFKEY(keysym)) {
+       /* Map Shift+F1-F10 to F11-F20 */
+       if (keysym >= PK_F1 && keysym <= PK_F10 && (modifiers & PKM_SHIFT))
+           keysym += 10;
+       if ((term->vt52_mode || term->cfg.funky_type == FUNKY_VT100P) &&
+           keysym <= PK_F14) {
+           /* XXX This overrides the XTERM/VT52 mode below */
+           int offt = 0;
+           if (keysym >= PK_F6)  offt++;
+           if (keysym >= PK_F12) offt++;
+           p += snprintf((char *) p, sizeof(output)-(p-output), term->vt52_mode ? "\x1B%c" : "\x1BO%c",
+                        'P' + keysym - PK_F1 - offt);
+           goto done;
+       }
+       if (term->cfg.funky_type == FUNKY_LINUX && keysym <= PK_F5) {
+           p += snprintf((char *) p, sizeof(output)-(p-output), "\x1B[[%c", 'A' + keysym - PK_F1);
+           goto done;
+       }
+       if (term->cfg.funky_type == FUNKY_XTERM && keysym <= PK_F4) {
+           if (term->vt52_mode)
+               p += snprintf((char *) p, sizeof(output)-(p-output), "\x1B%c", 'P' + keysym - PK_F1);
+           else
+               p += snprintf((char *) p, sizeof(output)-(p-output), "\x1BO%c", 'P' + keysym - PK_F1);
+           goto done;
+       }
+       p += snprintf((char *) p, sizeof(output)-(p-output), "\x1B[%d~", 11 + keysym - PK_F1);
+       goto done;
+    }
+
+    if (PK_ISCURSOR(keysym)) {
+       int xkey;
+
+       switch (keysym) {
+         case PK_UP:    xkey = 'A'; break;
+         case PK_DOWN:  xkey = 'B'; break;
+         case PK_RIGHT: xkey = 'C'; break;
+         case PK_LEFT:  xkey = 'D'; break;
+         case PK_REST:  xkey = 'G'; break; /* centre key on number pad */
+         default: xkey = 0; break; /* else gcc warns `enum value not used' */
+       }
+       if (term->vt52_mode)
+           p += snprintf((char *) p, sizeof(output)-(p-output), "\x1B%c", xkey);
+       else {
+           int app_flg = (term->app_cursor_keys && !term->cfg.no_applic_c);
+
+           /* Useful mapping of Ctrl-arrows */
+           if (modifiers == PKM_CONTROL)
+               app_flg = !app_flg;
+
+           if (app_flg)
+               p += snprintf((char *) p, sizeof(output)-(p-output), "\x1BO%c", xkey);
+           else
+               p += snprintf((char *) p, sizeof(output)-(p-output), "\x1B[%c", xkey);
+       }
+       goto done;
+    }
+
+  done:
+    if (p > output || tlen > 0) {
+       /*
+        * Interrupt an ongoing paste. I'm not sure
+        * this is sensible, but for the moment it's
+        * preferable to having to faff about buffering
+        * things.
+        */
+       term_nopaste(term);
+
+       /*
+        * We need not bother about stdin backlogs
+        * here, because in GUI PuTTY we can't do
+        * anything about it anyway; there's no means
+        * of asking Windows to hold off on KEYDOWN
+        * messages. We _have_ to buffer everything
+        * we're sent.
+        */
+       term_seen_key_event(term);
+
+       if (prependesc) {
+#if 0
+           fprintf(stderr, "sending ESC\n");
+#endif
+           ldisc_send(term->ldisc, "\x1b", 1, 1);
+       }
+
+       if (p > output) {
+#if 0
+           fprintf(stderr, "sending %d bytes:", p - output);
+           for (i = 0; i < p - output; i++)
+               fprintf(stderr, " %02x", output[i]);
+           fprintf(stderr, "\n");
+#endif
+           ldisc_send(term->ldisc, output, p - output, 1);
+       } else if (tlen > 0) {
+#if 0
+           fprintf(stderr, "sending %d unichars:", tlen);
+           for (i = 0; i < tlen; i++)
+               fprintf(stderr, " %04x", (unsigned) text[i]);
+           fprintf(stderr, "\n");
+#endif
+           luni_send(term->ldisc, text, tlen, 1);
+       }
+    }
+}
+#endif
+
+void term_copy(Terminal *term)
+{
+    if (term->selstate == SELECTED) {
+       clipme(term, term->selstart, term->selend, 
+              (term->seltype == RECTANGULAR), FALSE);
+    }
+}
+
+void term_nopaste(Terminal *term)
+{
+    if (term->paste_len == 0)
+       return;
+    sfree(term->paste_buffer);
+    term->paste_buffer = NULL;
+    term->paste_len = 0;
+}
+
+int term_paste_pending(Terminal *term)
+{
+    return term->paste_len != 0;
+}
+
+void term_paste(Terminal *term)
+{
+    long now, paste_diff;
+
+    if (term->paste_len == 0)
+       return;
+
+    /* Don't wait forever to paste */
+    if (term->paste_hold) {
+       now = GETTICKCOUNT();
+       paste_diff = now - term->last_paste;
+       if (paste_diff >= 0 && paste_diff < 450)
+           return;
+    }
+    term->paste_hold = 0;
+
+    while (term->paste_pos < term->paste_len) {
+       int n = 0;
+       while (n + term->paste_pos < term->paste_len) {
+           if (term->paste_buffer[term->paste_pos + n++] == '\015')
+               break;
+       }
+       if (term->ldisc)
+           luni_send(term->ldisc, term->paste_buffer + term->paste_pos, n, 0);
+       term->paste_pos += n;
+
+       if (term->paste_pos < term->paste_len) {
+           term->paste_hold = 1;
+           return;
+       }
+    }
+    sfree(term->paste_buffer);
+    term->paste_buffer = NULL;
+    term->paste_len = 0;
+}
+
+static void deselect(Terminal *term)
+{
+    term->selstate = NO_SELECTION;
+    term->selstart.x = term->selstart.y = term->selend.x = term->selend.y = 0;
+}
+
+int term_selection_exists(Terminal *term)
+{
+    return (term->selstate == SELECTED);
+}
+
+void term_deselect(Terminal *term)
+{
+    deselect(term);
+    term_update(term);
+}
+
+int term_ldisc(Terminal *term, int option)
+{
+    if (option == LD_ECHO)
+       return term->term_echoing;
+    if (option == LD_EDIT)
+       return term->term_editing;
+    return FALSE;
+}
+
+size_t term_data(Terminal *term, int is_stderr, const char *data, size_t len)
+{
+    bufchain_add(&term->inbuf, data, len);
+
+    if (!term->in_term_out) {
+       term->in_term_out = TRUE;
+       term_blink(term, 1);
+       term_out(term);
+       term->in_term_out = FALSE;
+    }
+
+    /*
+     * term_out() always completely empties inbuf. Therefore,
+     * there's no reason at all to return anything other than zero
+     * from this function, because there _can't_ be a question of
+     * the remote side needing to wait until term_out() has cleared
+     * a backlog.
+     *
+     * This is a slightly suboptimal way to deal with SSH2 - in
+     * principle, the window mechanism would allow us to continue
+     * to accept data on forwarded ports and X connections even
+     * while the terminal processing was going slowly - but we
+     * can't do the 100% right thing without moving the terminal
+     * processing into a separate thread, and that might hurt
+     * portability. So we manage stdout buffering the old SSH1 way:
+     * if the terminal processing goes slowly, the whole SSH
+     * connection stops accepting data until it's ready.
+     *
+     * In practice, I can't imagine this causing serious trouble.
+     */
+    return 0;
+}
+
+void term_provide_logctx(Terminal *term, void *logctx)
+{
+    term->logctx = logctx;
+}
+
+int term_app_cursor_keys(Terminal *term)
+{
+    return term->app_cursor_keys;
+}
diff --git a/arm/vt100/terminal.h b/arm/vt100/terminal.h
new file mode 100644 (file)
index 0000000..b7f0ff9
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+PuTTY is copyright 1997-2004 Simon Tatham.
+
+Portions copyright Robert de Bath, Joris van Rantwijk, Delian
+Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
+Justin Bradford, Ben Harris, and CORE SDI S.A.
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation files
+(the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+/*
+ * Internals of the Terminal structure, for those other modules
+ * which need to look inside it. It would be nice if this could be
+ * folded back into terminal.c in future, with an abstraction layer
+ * to handle everything that other modules need to know about it;
+ * but for the moment, this will do.
+ */
+
+#ifndef PUTTY_TERMINAL_H
+#define PUTTY_TERMINAL_H
+
+#include "tree234.h"
+
+struct beeptime {
+    struct beeptime *next;
+    unsigned long ticks;
+};
+
+typedef struct {
+    int y, x;
+} pos;
+
+#ifdef OPTIMISE_SCROLL
+struct scrollregion {
+    struct scrollregion *next;
+    int topline; /* Top line of scroll region. */
+    int botline; /* Bottom line of scroll region. */
+    int lines; /* Number of lines to scroll by - +ve is forwards. */
+};
+#endif /* OPTIMISE_SCROLL */
+
+struct terminal_tag {
+
+    int compatibility_level;
+
+    tree234 *scrollback;              /* lines scrolled off top of screen */
+    tree234 *screen;                  /* lines on primary screen */
+    tree234 *alt_screen;              /* lines on alternate screen */
+    int disptop;                      /* distance scrolled back (0 or -ve) */
+    int tempsblines;                  /* number of lines in temporary
+                                         scrollback */
+
+    unsigned long *cpos;              /* cursor position (convenience) */
+
+    unsigned long *disptext;          /* buffer of text on real screen */
+    unsigned long *dispcurs;          /* location of cursor on real screen */
+    unsigned long curstype;           /* type of cursor on real screen */
+
+#define VBELL_TIMEOUT (TICKSPERSEC/10) /* visual bell lasts 1/10 sec */
+
+    struct beeptime *beephead, *beeptail;
+    int nbeeps;
+    int beep_overloaded;
+    long lastbeep;
+
+#define TTYPE unsigned long
+#define TSIZE (sizeof(TTYPE))
+#define fix_cpos do { \
+    term->cpos = lineptr(term->curs.y) + term->curs.x; \
+} while(0)
+
+#ifdef OPTIMISE_SCROLL
+    struct scrollregion *scrollhead, *scrolltail;
+#endif /* OPTIMISE_SCROLL */
+
+    unsigned long default_attr, curr_attr, save_attr;
+    unsigned long erase_char;
+
+    bufchain inbuf;                   /* terminal input buffer */
+    pos curs;                         /* cursor */
+    pos savecurs;                     /* saved cursor position */
+    int marg_t, marg_b;                       /* scroll margins */
+    int dec_om;                               /* DEC origin mode flag */
+    int wrap, wrapnext;                       /* wrap flags */
+    int insert;                               /* insert-mode flag */
+    int cset;                         /* 0 or 1: which char set */
+    int save_cset, save_csattr;               /* saved with cursor position */
+    int save_utf, save_wnext;         /* saved with cursor position */
+    int rvideo;                               /* global reverse video flag */
+    unsigned long rvbell_startpoint;   /* for ESC[?5hESC[?5l vbell */
+    int cursor_on;                    /* cursor enabled flag */
+    int reset_132;                    /* Flag ESC c resets to 80 cols */
+    int use_bce;                      /* Use Background coloured erase */
+    int blinker;                      /* When blinking is the cursor on ? */
+    int tblinker;                     /* When the blinking text is on */
+    int blink_is_real;                /* Actually blink blinking text */
+    int term_echoing;                 /* Does terminal want local echo? */
+    int term_editing;                 /* Does terminal want local edit? */
+    int sco_acs, save_sco_acs;        /* CSI 10,11,12m -> OEM charset */
+    int vt52_bold;                    /* Force bold on non-bold colours */
+    int utf;                          /* Are we in toggleable UTF-8 mode? */
+    int utf_state;                    /* Is there a pending UTF-8 character */
+    uint32_t utf_char;                /* and what is it so far. */
+    int utf_size;                     /* The size of the UTF character. */
+    int printing, only_printing;       /* Are we doing ANSI printing? */
+    int print_state;                  /* state of print-end-sequence scan */
+    bufchain printer_buf;             /* buffered data for printer */
+    printer_job *print_job;
+
+    int rows, cols, savelines;
+    int has_focus;
+    int in_vbell;
+    unsigned long vbell_startpoint;
+    int app_cursor_keys, app_keypad_keys, vt52_mode;
+    int repeat_off, cr_lf_return;
+    int seen_disp_event;
+    int big_cursor;
+
+    long last_blink;                  /* used for real blinking control */
+    long last_tblink;
+
+    int xterm_mouse;                  /* send mouse messages to app */
+    int mouse_is_down;                /* used while tracking mouse buttons */
+
+    unsigned long cset_attr[2];
+
+/*
+ * Saved settings on the alternate screen.
+ */
+    int alt_x, alt_y, alt_om, alt_wrap, alt_wnext, alt_ins;
+    int alt_cset, alt_sco_acs, alt_utf;
+    int alt_t, alt_b;
+    int alt_which;
+    int alt_sblines; /* # of lines on alternate screen that should be used for scrollback. */
+
+#define ARGS_MAX 32                   /* max # of esc sequence arguments */
+#define ARG_DEFAULT 0                 /* if an arg isn't specified */
+#define def(a,d) ( (a) == ARG_DEFAULT ? (d) : (a) )
+    int esc_args[ARGS_MAX];
+    int esc_nargs;
+    int esc_query;
+#define ANSI(x,y)      ((x)+((y)<<8))
+#define ANSI_QUE(x)    ANSI(x,TRUE)
+
+#define OSC_STR_MAX 2048
+    int osc_strlen;
+    char osc_string[OSC_STR_MAX + 1];
+    int osc_w;
+
+    char id_string[1024];
+
+    unsigned char *tabs;
+
+    enum {
+       TOPLEVEL,
+       SEEN_ESC,
+       SEEN_CSI,
+       SEEN_OSC,
+       SEEN_OSC_W,
+
+       DO_CTRLS,
+
+       SEEN_OSC_P,
+       OSC_STRING, OSC_MAYBE_ST,
+       VT52_ESC,
+       VT52_Y1,
+       VT52_Y2,
+       VT52_FG,
+       VT52_BG
+    } termstate;
+
+    enum {
+       NO_SELECTION, ABOUT_TO, DRAGGING, SELECTED
+    } selstate;
+    enum {
+       LEXICOGRAPHIC, RECTANGULAR
+    } seltype;
+    enum {
+       SM_CHAR, SM_WORD, SM_LINE
+    } selmode;
+    pos selstart, selend, selanchor;
+
+    short wordness[256];
+
+    /* Mask of attributes to pay attention to when painting. */
+    unsigned long attr_mask;
+
+    wchar_t *paste_buffer;
+    int paste_len, paste_pos, paste_hold;
+    long last_paste;
+
+    void (*resize_fn)(void *, int, int);
+    void *resize_ctx;
+
+    void *ldisc;
+
+    void *frontend;
+
+    void *logctx;
+
+    struct unicode_data *ucsdata;
+
+    /*
+     * We maintain a full _copy_ of a Config structure here, not
+     * merely a pointer to it. That way, when we're passed a new
+     * one for reconfiguration, we can check the differences and
+     * adjust the _current_ setting of (e.g.) auto wrap mode rather
+     * than only the default.
+     */
+    Config cfg;
+
+    /*
+     * from_backend calls term_out, but it can also be called from
+     * the ldisc if the ldisc is called _within_ term_out. So we
+     * have to guard against re-entrancy - if from_backend is
+     * called recursively like this, it will simply add data to the
+     * end of the buffer term_out is in the process of working
+     * through.
+     */
+    int in_term_out;
+};
+
+#define in_utf(term) ((term)->utf || (term)->ucsdata->line_codepage==CP_UTF8)
+
+#endif
diff --git a/arm/vt100/tree234.c b/arm/vt100/tree234.c
new file mode 100644 (file)
index 0000000..34c799e
--- /dev/null
@@ -0,0 +1,1483 @@
+/*
+ * tree234.c: reasonably generic counted 2-3-4 tree routines.
+ * 
+ * This file is copyright 1999-2001 Simon Tatham.
+ * 
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL SIMON TATHAM BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "includes.h"
+#include "assert.h"
+
+#include "puttymem.h"
+#include "tree234.h"
+
+#ifdef TEST_TREE234
+#define LOG(x) (printf x)
+#else
+#define LOG(x)
+#endif
+
+typedef struct node234_Tag node234;
+
+struct tree234_Tag {
+    node234 *root;
+    cmpfn234 cmp;
+};
+
+struct node234_Tag {
+    node234 *parent;
+    node234 *kids[4];
+    int counts[4];
+    void *elems[3];
+};
+
+static void freenode234(node234 * n);
+static int countnode234(node234 * n);
+static void *add234_internal(tree234 * t, void *e, int index);
+static void *delpos234_internal(tree234 * t, int index);
+
+
+/*
+ * Create a 2-3-4 tree.
+ */
+tree234 *newtree234(cmpfn234 cmp)
+{
+    tree234 *ret = snew(tree234);
+    LOG(("created tree %p\n", ret));
+    ret->root = NULL;
+    ret->cmp = cmp;
+    return ret;
+}
+
+/*
+ * Free a 2-3-4 tree (not including freeing the elements).
+ */
+static void freenode234(node234 * n)
+{
+    if (!n)
+       return;
+    freenode234(n->kids[0]);
+    freenode234(n->kids[1]);
+    freenode234(n->kids[2]);
+    freenode234(n->kids[3]);
+    sfree(n);
+}
+
+void freetree234(tree234 * t)
+{
+    freenode234(t->root);
+    sfree(t);
+}
+
+/*
+ * Internal function to count a node.
+ */
+static int countnode234(node234 * n)
+{
+    int count = 0;
+    int i;
+    if (!n)
+       return 0;
+    for (i = 0; i < 4; i++)
+       count += n->counts[i];
+    for (i = 0; i < 3; i++)
+       if (n->elems[i])
+           count++;
+    return count;
+}
+
+/*
+ * Count the elements in a tree.
+ */
+int count234(tree234 * t)
+{
+    if (t->root)
+       return countnode234(t->root);
+    else
+       return 0;
+}
+
+/*
+ * Add an element e to a 2-3-4 tree t. Returns e on success, or if
+ * an existing element compares equal, returns that.
+ */
+static void *add234_internal(tree234 * t, void *e, int index)
+{
+    node234 *n, **np, *left, *right;
+    void *orig_e = e;
+    int c, lcount, rcount;
+
+    LOG(("adding node %p to tree %p\n", e, t));
+    if (t->root == NULL) {
+       t->root = snew(node234);
+       t->root->elems[1] = t->root->elems[2] = NULL;
+       t->root->kids[0] = t->root->kids[1] = NULL;
+       t->root->kids[2] = t->root->kids[3] = NULL;
+       t->root->counts[0] = t->root->counts[1] = 0;
+       t->root->counts[2] = t->root->counts[3] = 0;
+       t->root->parent = NULL;
+       t->root->elems[0] = e;
+       LOG(("  created root %p\n", t->root));
+       return orig_e;
+    }
+
+    np = &t->root;
+    while (*np) {
+       int childnum;
+       n = *np;
+       LOG(("  node %p: %p/%d [%p] %p/%d [%p] %p/%d [%p] %p/%d\n",
+            n,
+            n->kids[0], n->counts[0], n->elems[0],
+            n->kids[1], n->counts[1], n->elems[1],
+            n->kids[2], n->counts[2], n->elems[2],
+            n->kids[3], n->counts[3]));
+       if (index >= 0) {
+           if (!n->kids[0]) {
+               /*
+                * Leaf node. We want to insert at kid position
+                * equal to the index:
+                * 
+                *   0 A 1 B 2 C 3
+                */
+               childnum = index;
+           } else {
+               /*
+                * Internal node. We always descend through it (add
+                * always starts at the bottom, never in the
+                * middle).
+                */
+               do {                   /* this is a do ... while (0) to allow `break' */
+                   if (index <= n->counts[0]) {
+                       childnum = 0;
+                       break;
+                   }
+                   index -= n->counts[0] + 1;
+                   if (index <= n->counts[1]) {
+                       childnum = 1;
+                       break;
+                   }
+                   index -= n->counts[1] + 1;
+                   if (index <= n->counts[2]) {
+                       childnum = 2;
+                       break;
+                   }
+                   index -= n->counts[2] + 1;
+                   if (index <= n->counts[3]) {
+                       childnum = 3;
+                       break;
+                   }
+                   return NULL;       /* error: index out of range */
+               } while (0);
+           }
+       } else {
+           if ((c = t->cmp(e, n->elems[0])) < 0)
+               childnum = 0;
+           else if (c == 0)
+               return n->elems[0];    /* already exists */
+           else if (n->elems[1] == NULL
+                    || (c = t->cmp(e, n->elems[1])) < 0) childnum = 1;
+           else if (c == 0)
+               return n->elems[1];    /* already exists */
+           else if (n->elems[2] == NULL
+                    || (c = t->cmp(e, n->elems[2])) < 0) childnum = 2;
+           else if (c == 0)
+               return n->elems[2];    /* already exists */
+           else
+               childnum = 3;
+       }
+       np = &n->kids[childnum];
+       LOG(("  moving to child %d (%p)\n", childnum, *np));
+    }
+
+    /*
+     * We need to insert the new element in n at position np.
+     */
+    left = NULL;
+    lcount = 0;
+    right = NULL;
+    rcount = 0;
+    while (n) {
+       LOG(("  at %p: %p/%d [%p] %p/%d [%p] %p/%d [%p] %p/%d\n",
+            n,
+            n->kids[0], n->counts[0], n->elems[0],
+            n->kids[1], n->counts[1], n->elems[1],
+            n->kids[2], n->counts[2], n->elems[2],
+            n->kids[3], n->counts[3]));
+       LOG(("  need to insert %p/%d [%p] %p/%d at position %d\n",
+            left, lcount, e, right, rcount, np - n->kids));
+       if (n->elems[1] == NULL) {
+           /*
+            * Insert in a 2-node; simple.
+            */
+           if (np == &n->kids[0]) {
+               LOG(("  inserting on left of 2-node\n"));
+               n->kids[2] = n->kids[1];
+               n->counts[2] = n->counts[1];
+               n->elems[1] = n->elems[0];
+               n->kids[1] = right;
+               n->counts[1] = rcount;
+               n->elems[0] = e;
+               n->kids[0] = left;
+               n->counts[0] = lcount;
+           } else {                   /* np == &n->kids[1] */
+               LOG(("  inserting on right of 2-node\n"));
+               n->kids[2] = right;
+               n->counts[2] = rcount;
+               n->elems[1] = e;
+               n->kids[1] = left;
+               n->counts[1] = lcount;
+           }
+           if (n->kids[0])
+               n->kids[0]->parent = n;
+           if (n->kids[1])
+               n->kids[1]->parent = n;
+           if (n->kids[2])
+               n->kids[2]->parent = n;
+           LOG(("  done\n"));
+           break;
+       } else if (n->elems[2] == NULL) {
+           /*
+            * Insert in a 3-node; simple.
+            */
+           if (np == &n->kids[0]) {
+               LOG(("  inserting on left of 3-node\n"));
+               n->kids[3] = n->kids[2];
+               n->counts[3] = n->counts[2];
+               n->elems[2] = n->elems[1];
+               n->kids[2] = n->kids[1];
+               n->counts[2] = n->counts[1];
+               n->elems[1] = n->elems[0];
+               n->kids[1] = right;
+               n->counts[1] = rcount;
+               n->elems[0] = e;
+               n->kids[0] = left;
+               n->counts[0] = lcount;
+           } else if (np == &n->kids[1]) {
+               LOG(("  inserting in middle of 3-node\n"));
+               n->kids[3] = n->kids[2];
+               n->counts[3] = n->counts[2];
+               n->elems[2] = n->elems[1];
+               n->kids[2] = right;
+               n->counts[2] = rcount;
+               n->elems[1] = e;
+               n->kids[1] = left;
+               n->counts[1] = lcount;
+           } else {                   /* np == &n->kids[2] */
+               LOG(("  inserting on right of 3-node\n"));
+               n->kids[3] = right;
+               n->counts[3] = rcount;
+               n->elems[2] = e;
+               n->kids[2] = left;
+               n->counts[2] = lcount;
+           }
+           if (n->kids[0])
+               n->kids[0]->parent = n;
+           if (n->kids[1])
+               n->kids[1]->parent = n;
+           if (n->kids[2])
+               n->kids[2]->parent = n;
+           if (n->kids[3])
+               n->kids[3]->parent = n;
+           LOG(("  done\n"));
+           break;
+       } else {
+           node234 *m = snew(node234);
+           m->parent = n->parent;
+           LOG(("  splitting a 4-node; created new node %p\n", m));
+           /*
+            * Insert in a 4-node; split into a 2-node and a
+            * 3-node, and move focus up a level.
+            * 
+            * I don't think it matters which way round we put the
+            * 2 and the 3. For simplicity, we'll put the 3 first
+            * always.
+            */
+           if (np == &n->kids[0]) {
+               m->kids[0] = left;
+               m->counts[0] = lcount;
+               m->elems[0] = e;
+               m->kids[1] = right;
+               m->counts[1] = rcount;
+               m->elems[1] = n->elems[0];
+               m->kids[2] = n->kids[1];
+               m->counts[2] = n->counts[1];
+               e = n->elems[1];
+               n->kids[0] = n->kids[2];
+               n->counts[0] = n->counts[2];
+               n->elems[0] = n->elems[2];
+               n->kids[1] = n->kids[3];
+               n->counts[1] = n->counts[3];
+           } else if (np == &n->kids[1]) {
+               m->kids[0] = n->kids[0];
+               m->counts[0] = n->counts[0];
+               m->elems[0] = n->elems[0];
+               m->kids[1] = left;
+               m->counts[1] = lcount;
+               m->elems[1] = e;
+               m->kids[2] = right;
+               m->counts[2] = rcount;
+               e = n->elems[1];
+               n->kids[0] = n->kids[2];
+               n->counts[0] = n->counts[2];
+               n->elems[0] = n->elems[2];
+               n->kids[1] = n->kids[3];
+               n->counts[1] = n->counts[3];
+           } else if (np == &n->kids[2]) {
+               m->kids[0] = n->kids[0];
+               m->counts[0] = n->counts[0];
+               m->elems[0] = n->elems[0];
+               m->kids[1] = n->kids[1];
+               m->counts[1] = n->counts[1];
+               m->elems[1] = n->elems[1];
+               m->kids[2] = left;
+               m->counts[2] = lcount;
+               /* e = e; */
+               n->kids[0] = right;
+               n->counts[0] = rcount;
+               n->elems[0] = n->elems[2];
+               n->kids[1] = n->kids[3];
+               n->counts[1] = n->counts[3];
+           } else {                   /* np == &n->kids[3] */
+               m->kids[0] = n->kids[0];
+               m->counts[0] = n->counts[0];
+               m->elems[0] = n->elems[0];
+               m->kids[1] = n->kids[1];
+               m->counts[1] = n->counts[1];
+               m->elems[1] = n->elems[1];
+               m->kids[2] = n->kids[2];
+               m->counts[2] = n->counts[2];
+               n->kids[0] = left;
+               n->counts[0] = lcount;
+               n->elems[0] = e;
+               n->kids[1] = right;
+               n->counts[1] = rcount;
+               e = n->elems[2];
+           }
+           m->kids[3] = n->kids[3] = n->kids[2] = NULL;
+           m->counts[3] = n->counts[3] = n->counts[2] = 0;
+           m->elems[2] = n->elems[2] = n->elems[1] = NULL;
+           if (m->kids[0])
+               m->kids[0]->parent = m;
+           if (m->kids[1])
+               m->kids[1]->parent = m;
+           if (m->kids[2])
+               m->kids[2]->parent = m;
+           if (n->kids[0])
+               n->kids[0]->parent = n;
+           if (n->kids[1])
+               n->kids[1]->parent = n;
+           LOG(("  left (%p): %p/%d [%p] %p/%d [%p] %p/%d\n", m,
+                m->kids[0], m->counts[0], m->elems[0],
+                m->kids[1], m->counts[1], m->elems[1],
+                m->kids[2], m->counts[2]));
+           LOG(("  right (%p): %p/%d [%p] %p/%d\n", n,
+                n->kids[0], n->counts[0], n->elems[0],
+                n->kids[1], n->counts[1]));
+           left = m;
+           lcount = countnode234(left);
+           right = n;
+           rcount = countnode234(right);
+       }
+       if (n->parent)
+           np = (n->parent->kids[0] == n ? &n->parent->kids[0] :
+                 n->parent->kids[1] == n ? &n->parent->kids[1] :
+                 n->parent->kids[2] == n ? &n->parent->kids[2] :
+                 &n->parent->kids[3]);
+       n = n->parent;
+    }
+
+    /*
+     * If we've come out of here by `break', n will still be
+     * non-NULL and all we need to do is go back up the tree
+     * updating counts. If we've come here because n is NULL, we
+     * need to create a new root for the tree because the old one
+     * has just split into two. */
+    if (n) {
+       while (n->parent) {
+           int count = countnode234(n);
+           int childnum;
+           childnum = (n->parent->kids[0] == n ? 0 :
+                       n->parent->kids[1] == n ? 1 :
+                       n->parent->kids[2] == n ? 2 : 3);
+           n->parent->counts[childnum] = count;
+           n = n->parent;
+       }
+    } else {
+       LOG(("  root is overloaded, split into two\n"));
+       t->root = snew(node234);
+       t->root->kids[0] = left;
+       t->root->counts[0] = lcount;
+       t->root->elems[0] = e;
+       t->root->kids[1] = right;
+       t->root->counts[1] = rcount;
+       t->root->elems[1] = NULL;
+       t->root->kids[2] = NULL;
+       t->root->counts[2] = 0;
+       t->root->elems[2] = NULL;
+       t->root->kids[3] = NULL;
+       t->root->counts[3] = 0;
+       t->root->parent = NULL;
+       if (t->root->kids[0])
+           t->root->kids[0]->parent = t->root;
+       if (t->root->kids[1])
+           t->root->kids[1]->parent = t->root;
+       LOG(("  new root is %p/%d [%p] %p/%d\n",
+            t->root->kids[0], t->root->counts[0],
+            t->root->elems[0], t->root->kids[1], t->root->counts[1]));
+    }
+
+    return orig_e;
+}
+
+void *add234(tree234 * t, void *e)
+{
+    if (!t->cmp)                      /* tree is unsorted */
+       return NULL;
+
+    return add234_internal(t, e, -1);
+}
+void *addpos234(tree234 * t, void *e, int index)
+{
+    if (index < 0 ||                  /* index out of range */
+       t->cmp)                        /* tree is sorted */
+       return NULL;                   /* return failure */
+
+    return add234_internal(t, e, index);       /* this checks the upper bound */
+}
+
+/*
+ * Look up the element at a given numeric index in a 2-3-4 tree.
+ * Returns NULL if the index is out of range.
+ */
+void *index234(tree234 * t, int index)
+{
+    node234 *n;
+
+    if (!t->root)
+       return NULL;                   /* tree is empty */
+
+    if (index < 0 || index >= countnode234(t->root))
+       return NULL;                   /* out of range */
+
+    n = t->root;
+
+    while (n) {
+       if (index < n->counts[0])
+           n = n->kids[0];
+       else if (index -= n->counts[0] + 1, index < 0)
+           return n->elems[0];
+       else if (index < n->counts[1])
+           n = n->kids[1];
+       else if (index -= n->counts[1] + 1, index < 0)
+           return n->elems[1];
+       else if (index < n->counts[2])
+           n = n->kids[2];
+       else if (index -= n->counts[2] + 1, index < 0)
+           return n->elems[2];
+       else
+           n = n->kids[3];
+    }
+
+    /* We shouldn't ever get here. I wonder how we did. */
+    return NULL;
+}
+
+/*
+ * Find an element e in a sorted 2-3-4 tree t. Returns NULL if not
+ * found. e is always passed as the first argument to cmp, so cmp
+ * can be an asymmetric function if desired. cmp can also be passed
+ * as NULL, in which case the compare function from the tree proper
+ * will be used.
+ */
+void *findrelpos234(tree234 * t, void *e, cmpfn234 cmp,
+                   int relation, int *index)
+{
+    node234 *n;
+    void *ret;
+    int c;
+    int idx, ecount, kcount, cmpret;
+
+    if (t->root == NULL)
+       return NULL;
+
+    if (cmp == NULL)
+       cmp = t->cmp;
+
+    n = t->root;
+    /*
+     * Attempt to find the element itself.
+     */
+    idx = 0;
+    ecount = -1;
+    /*
+     * Prepare a fake `cmp' result if e is NULL.
+     */
+    cmpret = 0;
+    if (e == NULL) {
+       assert(relation == REL234_LT || relation == REL234_GT);
+       if (relation == REL234_LT)
+           cmpret = +1;               /* e is a max: always greater */
+       else if (relation == REL234_GT)
+           cmpret = -1;               /* e is a min: always smaller */
+    }
+    while (1) {
+       for (kcount = 0; kcount < 4; kcount++) {
+           if (kcount >= 3 || n->elems[kcount] == NULL ||
+               (c = cmpret ? cmpret : cmp(e, n->elems[kcount])) < 0) {
+               break;
+           }
+           if (n->kids[kcount])
+               idx += n->counts[kcount];
+           if (c == 0) {
+               ecount = kcount;
+               break;
+           }
+           idx++;
+       }
+       if (ecount >= 0)
+           break;
+       if (n->kids[kcount])
+           n = n->kids[kcount];
+       else
+           break;
+    }
+
+    if (ecount >= 0) {
+       /*
+        * We have found the element we're looking for. It's
+        * n->elems[ecount], at tree index idx. If our search
+        * relation is EQ, LE or GE we can now go home.
+        */
+       if (relation != REL234_LT && relation != REL234_GT) {
+           if (index)
+               *index = idx;
+           return n->elems[ecount];
+       }
+
+       /*
+        * Otherwise, we'll do an indexed lookup for the previous
+        * or next element. (It would be perfectly possible to
+        * implement these search types in a non-counted tree by
+        * going back up from where we are, but far more fiddly.)
+        */
+       if (relation == REL234_LT)
+           idx--;
+       else
+           idx++;
+    } else {
+       /*
+        * We've found our way to the bottom of the tree and we
+        * know where we would insert this node if we wanted to:
+        * we'd put it in in place of the (empty) subtree
+        * n->kids[kcount], and it would have index idx
+        * 
+        * But the actual element isn't there. So if our search
+        * relation is EQ, we're doomed.
+        */
+       if (relation == REL234_EQ)
+           return NULL;
+
+       /*
+        * Otherwise, we must do an index lookup for index idx-1
+        * (if we're going left - LE or LT) or index idx (if we're
+        * going right - GE or GT).
+        */
+       if (relation == REL234_LT || relation == REL234_LE) {
+           idx--;
+       }
+    }
+
+    /*
+     * We know the index of the element we want; just call index234
+     * to do the rest. This will return NULL if the index is out of
+     * bounds, which is exactly what we want.
+     */
+    ret = index234(t, idx);
+    if (ret && index)
+       *index = idx;
+    return ret;
+}
+void *find234(tree234 * t, void *e, cmpfn234 cmp)
+{
+    return findrelpos234(t, e, cmp, REL234_EQ, NULL);
+}
+void *findrel234(tree234 * t, void *e, cmpfn234 cmp, int relation)
+{
+    return findrelpos234(t, e, cmp, relation, NULL);
+}
+void *findpos234(tree234 * t, void *e, cmpfn234 cmp, int *index)
+{
+    return findrelpos234(t, e, cmp, REL234_EQ, index);
+}
+
+/*
+ * Delete an element e in a 2-3-4 tree. Does not free the element,
+ * merely removes all links to it from the tree nodes.
+ */
+static void *delpos234_internal(tree234 * t, int index)
+{
+    node234 *n;
+    void *retval;
+    int ei = -1;
+
+    retval = 0;
+
+    n = t->root;
+    LOG(("deleting item %d from tree %p\n", index, t));
+    while (1) {
+       while (n) {
+           int ki;
+           node234 *sub;
+
+           LOG(
+               ("  node %p: %p/%d [%p] %p/%d [%p] %p/%d [%p] %p/%d index=%d\n",
+                n, n->kids[0], n->counts[0], n->elems[0], n->kids[1],
+                n->counts[1], n->elems[1], n->kids[2], n->counts[2],
+                n->elems[2], n->kids[3], n->counts[3], index));
+           if (index < n->counts[0]) {
+               ki = 0;
+           } else if (index -= n->counts[0] + 1, index < 0) {
+               ei = 0;
+               break;
+           } else if (index < n->counts[1]) {
+               ki = 1;
+           } else if (index -= n->counts[1] + 1, index < 0) {
+               ei = 1;
+               break;
+           } else if (index < n->counts[2]) {
+               ki = 2;
+           } else if (index -= n->counts[2] + 1, index < 0) {
+               ei = 2;
+               break;
+           } else {
+               ki = 3;
+           }
+           /*
+            * Recurse down to subtree ki. If it has only one element,
+            * we have to do some transformation to start with.
+            */
+           LOG(("  moving to subtree %d\n", ki));
+           sub = n->kids[ki];
+           if (!sub->elems[1]) {
+               LOG(("  subtree has only one element!\n", ki));
+               if (ki > 0 && n->kids[ki - 1]->elems[1]) {
+                   /*
+                    * Case 3a, left-handed variant. Child ki has
+                    * only one element, but child ki-1 has two or
+                    * more. So we need to move a subtree from ki-1
+                    * to ki.
+                    * 
+                    *                . C .                     . B .
+                    *               /     \     ->            /     \
+                    * [more] a A b B c   d D e      [more] a A b   c C d D e
+                    */
+                   node234 *sib = n->kids[ki - 1];
+                   int lastelem = (sib->elems[2] ? 2 :
+                                   sib->elems[1] ? 1 : 0);
+                   sub->kids[2] = sub->kids[1];
+                   sub->counts[2] = sub->counts[1];
+                   sub->elems[1] = sub->elems[0];
+                   sub->kids[1] = sub->kids[0];
+                   sub->counts[1] = sub->counts[0];
+                   sub->elems[0] = n->elems[ki - 1];
+                   sub->kids[0] = sib->kids[lastelem + 1];
+                   sub->counts[0] = sib->counts[lastelem + 1];
+                   if (sub->kids[0])
+                       sub->kids[0]->parent = sub;
+                   n->elems[ki - 1] = sib->elems[lastelem];
+                   sib->kids[lastelem + 1] = NULL;
+                   sib->counts[lastelem + 1] = 0;
+                   sib->elems[lastelem] = NULL;
+                   n->counts[ki] = countnode234(sub);
+                   LOG(("  case 3a left\n"));
+                   LOG(
+                       ("  index and left subtree count before adjustment: %d, %d\n",
+                        index, n->counts[ki - 1]));
+                   index += n->counts[ki - 1];
+                   n->counts[ki - 1] = countnode234(sib);
+                   index -= n->counts[ki - 1];
+                   LOG(
+                       ("  index and left subtree count after adjustment: %d, %d\n",
+                        index, n->counts[ki - 1]));
+               } else if (ki < 3 && n->kids[ki + 1]
+                          && n->kids[ki + 1]->elems[1]) {
+                   /*
+                    * Case 3a, right-handed variant. ki has only
+                    * one element but ki+1 has two or more. Move a
+                    * subtree from ki+1 to ki.
+                    * 
+                    *      . B .                             . C .
+                    *     /     \                ->         /     \
+                    *  a A b   c C d D e [more]      a A b B c   d D e [more]
+                    */
+                   node234 *sib = n->kids[ki + 1];
+                   int j;
+                   sub->elems[1] = n->elems[ki];
+                   sub->kids[2] = sib->kids[0];
+                   sub->counts[2] = sib->counts[0];
+                   if (sub->kids[2])
+                       sub->kids[2]->parent = sub;
+                   n->elems[ki] = sib->elems[0];
+                   sib->kids[0] = sib->kids[1];
+                   sib->counts[0] = sib->counts[1];
+                   for (j = 0; j < 2 && sib->elems[j + 1]; j++) {
+                       sib->kids[j + 1] = sib->kids[j + 2];
+                       sib->counts[j + 1] = sib->counts[j + 2];
+                       sib->elems[j] = sib->elems[j + 1];
+                   }
+                   sib->kids[j + 1] = NULL;
+                   sib->counts[j + 1] = 0;
+                   sib->elems[j] = NULL;
+                   n->counts[ki] = countnode234(sub);
+                   n->counts[ki + 1] = countnode234(sib);
+                   LOG(("  case 3a right\n"));
+               } else {
+                   /*
+                    * Case 3b. ki has only one element, and has no
+                    * neighbour with more than one. So pick a
+                    * neighbour and merge it with ki, taking an
+                    * element down from n to go in the middle.
+                    *
+                    *      . B .                .
+                    *     /     \     ->        |
+                    *  a A b   c C d      a A b B c C d
+                    * 
+                    * (Since at all points we have avoided
+                    * descending to a node with only one element,
+                    * we can be sure that n is not reduced to
+                    * nothingness by this move, _unless_ it was
+                    * the very first node, ie the root of the
+                    * tree. In that case we remove the now-empty
+                    * root and replace it with its single large
+                    * child as shown.)
+                    */
+                   node234 *sib;
+                   int j;
+
+                   if (ki > 0) {
+                       ki--;
+                       index += n->counts[ki] + 1;
+                   }
+                   sib = n->kids[ki];
+                   sub = n->kids[ki + 1];
+
+                   sub->kids[3] = sub->kids[1];
+                   sub->counts[3] = sub->counts[1];
+                   sub->elems[2] = sub->elems[0];
+                   sub->kids[2] = sub->kids[0];
+                   sub->counts[2] = sub->counts[0];
+                   sub->elems[1] = n->elems[ki];
+                   sub->kids[1] = sib->kids[1];
+                   sub->counts[1] = sib->counts[1];
+                   if (sub->kids[1])
+                       sub->kids[1]->parent = sub;
+                   sub->elems[0] = sib->elems[0];
+                   sub->kids[0] = sib->kids[0];
+                   sub->counts[0] = sib->counts[0];
+                   if (sub->kids[0])
+                       sub->kids[0]->parent = sub;
+
+                   n->counts[ki + 1] = countnode234(sub);
+
+                   sfree(sib);
+
+                   /*
+                    * That's built the big node in sub. Now we
+                    * need to remove the reference to sib in n.
+                    */
+                   for (j = ki; j < 3 && n->kids[j + 1]; j++) {
+                       n->kids[j] = n->kids[j + 1];
+                       n->counts[j] = n->counts[j + 1];
+                       n->elems[j] = j < 2 ? n->elems[j + 1] : NULL;
+                   }
+                   n->kids[j] = NULL;
+                   n->counts[j] = 0;
+                   if (j < 3)
+                       n->elems[j] = NULL;
+                   LOG(("  case 3b ki=%d\n", ki));
+
+                   if (!n->elems[0]) {
+                       /*
+                        * The root is empty and needs to be
+                        * removed.
+                        */
+                       LOG(("  shifting root!\n"));
+                       t->root = sub;
+                       sub->parent = NULL;
+                       sfree(n);
+                   }
+               }
+           }
+           n = sub;
+       }
+       if (!retval)
+           retval = n->elems[ei];
+
+       if (ei == -1)
+           return NULL;               /* although this shouldn't happen */
+
+       /*
+        * Treat special case: this is the one remaining item in
+        * the tree. n is the tree root (no parent), has one
+        * element (no elems[1]), and has no kids (no kids[0]).
+        */
+       if (!n->parent && !n->elems[1] && !n->kids[0]) {
+           LOG(("  removed last element in tree\n"));
+           sfree(n);
+           t->root = NULL;
+           return retval;
+       }
+
+       /*
+        * Now we have the element we want, as n->elems[ei], and we
+        * have also arranged for that element not to be the only
+        * one in its node. So...
+        */
+
+       if (!n->kids[0] && n->elems[1]) {
+           /*
+            * Case 1. n is a leaf node with more than one element,
+            * so it's _really easy_. Just delete the thing and
+            * we're done.
+            */
+           int i;
+           LOG(("  case 1\n"));
+           for (i = ei; i < 2 && n->elems[i + 1]; i++)
+               n->elems[i] = n->elems[i + 1];
+           n->elems[i] = NULL;
+           /*
+            * Having done that to the leaf node, we now go back up
+            * the tree fixing the counts.
+            */
+           while (n->parent) {
+               int childnum;
+               childnum = (n->parent->kids[0] == n ? 0 :
+                           n->parent->kids[1] == n ? 1 :
+                           n->parent->kids[2] == n ? 2 : 3);
+               n->parent->counts[childnum]--;
+               n = n->parent;
+           }
+           return retval;             /* finished! */
+       } else if (n->kids[ei]->elems[1]) {
+           /*
+            * Case 2a. n is an internal node, and the root of the
+            * subtree to the left of e has more than one element.
+            * So find the predecessor p to e (ie the largest node
+            * in that subtree), place it where e currently is, and
+            * then start the deletion process over again on the
+            * subtree with p as target.
+            */
+           node234 *m = n->kids[ei];
+           void *target;
+           LOG(("  case 2a\n"));
+           while (m->kids[0]) {
+               m = (m->kids[3] ? m->kids[3] :
+                    m->kids[2] ? m->kids[2] :
+                    m->kids[1] ? m->kids[1] : m->kids[0]);
+           }
+           target = (m->elems[2] ? m->elems[2] :
+                     m->elems[1] ? m->elems[1] : m->elems[0]);
+           n->elems[ei] = target;
+           index = n->counts[ei] - 1;
+           n = n->kids[ei];
+       } else if (n->kids[ei + 1]->elems[1]) {
+           /*
+            * Case 2b, symmetric to 2a but s/left/right/ and
+            * s/predecessor/successor/. (And s/largest/smallest/).
+            */
+           node234 *m = n->kids[ei + 1];
+           void *target;
+           LOG(("  case 2b\n"));
+           while (m->kids[0]) {
+               m = m->kids[0];
+           }
+           target = m->elems[0];
+           n->elems[ei] = target;
+           n = n->kids[ei + 1];
+           index = 0;
+       } else {
+           /*
+            * Case 2c. n is an internal node, and the subtrees to
+            * the left and right of e both have only one element.
+            * So combine the two subnodes into a single big node
+            * with their own elements on the left and right and e
+            * in the middle, then restart the deletion process on
+            * that subtree, with e still as target.
+            */
+           node234 *a = n->kids[ei], *b = n->kids[ei + 1];
+           int j;
+
+           LOG(("  case 2c\n"));
+           a->elems[1] = n->elems[ei];
+           a->kids[2] = b->kids[0];
+           a->counts[2] = b->counts[0];
+           if (a->kids[2])
+               a->kids[2]->parent = a;
+           a->elems[2] = b->elems[0];
+           a->kids[3] = b->kids[1];
+           a->counts[3] = b->counts[1];
+           if (a->kids[3])
+               a->kids[3]->parent = a;
+           sfree(b);
+           n->counts[ei] = countnode234(a);
+           /*
+            * That's built the big node in a, and destroyed b. Now
+            * remove the reference to b (and e) in n.
+            */
+           for (j = ei; j < 2 && n->elems[j + 1]; j++) {
+               n->elems[j] = n->elems[j + 1];
+               n->kids[j + 1] = n->kids[j + 2];
+               n->counts[j + 1] = n->counts[j + 2];
+           }
+           n->elems[j] = NULL;
+           n->kids[j + 1] = NULL;
+           n->counts[j + 1] = 0;
+           /*
+            * It's possible, in this case, that we've just removed
+            * the only element in the root of the tree. If so,
+            * shift the root.
+            */
+           if (n->elems[0] == NULL) {
+               LOG(("  shifting root!\n"));
+               t->root = a;
+               a->parent = NULL;
+               sfree(n);
+           }
+           /*
+            * Now go round the deletion process again, with n
+            * pointing at the new big node and e still the same.
+            */
+           n = a;
+           index = a->counts[0] + a->counts[1] + 1;
+       }
+    }
+}
+void *delpos234(tree234 * t, int index)
+{
+    if (index < 0 || index >= countnode234(t->root))
+       return NULL;
+    return delpos234_internal(t, index);
+}
+void *del234(tree234 * t, void *e)
+{
+    int index;
+    if (!findrelpos234(t, e, NULL, REL234_EQ, &index))
+       return NULL;                   /* it wasn't in there anyway */
+    return delpos234_internal(t, index);       /* it's there; delete it. */
+}
+
+#ifdef TEST_TREE234
+
+/*
+ * Test code for the 2-3-4 tree. This code maintains an alternative
+ * representation of the data in the tree, in an array (using the
+ * obvious and slow insert and delete functions). After each tree
+ * operation, the verify() function is called, which ensures all
+ * the tree properties are preserved:
+ *  - node->child->parent always equals node
+ *  - tree->root->parent always equals NULL
+ *  - number of kids == 0 or number of elements + 1;
+ *  - tree has the same depth everywhere
+ *  - every node has at least one element
+ *  - subtree element counts are accurate
+ *  - any NULL kid pointer is accompanied by a zero count
+ *  - in a sorted tree: ordering property between elements of a
+ *    node and elements of its children is preserved
+ * and also ensures the list represented by the tree is the same
+ * list it should be. (This last check also doubly verifies the
+ * ordering properties, because the `same list it should be' is by
+ * definition correctly ordered. It also ensures all nodes are
+ * distinct, because the enum functions would get caught in a loop
+ * if not.)
+ */
+
+#include <stdarg.h>
+
+/*
+ * Error reporting function.
+ */
+void error(char *fmt, ...)
+{
+    va_list ap;
+    printf("ERROR: ");
+    va_start(ap, fmt);
+    vfprintf(stdout, fmt, ap);
+    va_end(ap);
+    printf("\n");
+}
+
+/* The array representation of the data. */
+void **array;
+int arraylen, arraysize;
+cmpfn234 cmp;
+
+/* The tree representation of the same data. */
+tree234 *tree;
+
+typedef struct {
+    int treedepth;
+    int elemcount;
+} chkctx;
+
+int chknode(chkctx * ctx, int level, node234 * node,
+           void *lowbound, void *highbound)
+{
+    int nkids, nelems;
+    int i;
+    int count;
+
+    /* Count the non-NULL kids. */
+    for (nkids = 0; nkids < 4 && node->kids[nkids]; nkids++);
+    /* Ensure no kids beyond the first NULL are non-NULL. */
+    for (i = nkids; i < 4; i++)
+       if (node->kids[i]) {
+           error("node %p: nkids=%d but kids[%d] non-NULL",
+                 node, nkids, i);
+       } else if (node->counts[i]) {
+           error("node %p: kids[%d] NULL but count[%d]=%d nonzero",
+                 node, i, i, node->counts[i]);
+       }
+
+    /* Count the non-NULL elements. */
+    for (nelems = 0; nelems < 3 && node->elems[nelems]; nelems++);
+    /* Ensure no elements beyond the first NULL are non-NULL. */
+    for (i = nelems; i < 3; i++)
+       if (node->elems[i]) {
+           error("node %p: nelems=%d but elems[%d] non-NULL",
+                 node, nelems, i);
+       }
+
+    if (nkids == 0) {
+       /*
+        * If nkids==0, this is a leaf node; verify that the tree
+        * depth is the same everywhere.
+        */
+       if (ctx->treedepth < 0)
+           ctx->treedepth = level;    /* we didn't know the depth yet */
+       else if (ctx->treedepth != level)
+           error("node %p: leaf at depth %d, previously seen depth %d",
+                 node, level, ctx->treedepth);
+    } else {
+       /*
+        * If nkids != 0, then it should be nelems+1, unless nelems
+        * is 0 in which case nkids should also be 0 (and so we
+        * shouldn't be in this condition at all).
+        */
+       int shouldkids = (nelems ? nelems + 1 : 0);
+       if (nkids != shouldkids) {
+           error("node %p: %d elems should mean %d kids but has %d",
+                 node, nelems, shouldkids, nkids);
+       }
+    }
+
+    /*
+     * nelems should be at least 1.
+     */
+    if (nelems == 0) {
+       error("node %p: no elems", node, nkids);
+    }
+
+    /*
+     * Add nelems to the running element count of the whole tree.
+     */
+    ctx->elemcount += nelems;
+
+    /*
+     * Check ordering property: all elements should be strictly >
+     * lowbound, strictly < highbound, and strictly < each other in
+     * sequence. (lowbound and highbound are NULL at edges of tree
+     * - both NULL at root node - and NULL is considered to be <
+     * everything and > everything. IYSWIM.)
+     */
+    if (cmp) {
+       for (i = -1; i < nelems; i++) {
+           void *lower = (i == -1 ? lowbound : node->elems[i]);
+           void *higher =
+               (i + 1 == nelems ? highbound : node->elems[i + 1]);
+           if (lower && higher && cmp(lower, higher) >= 0) {
+               error("node %p: kid comparison [%d=%s,%d=%s] failed",
+                     node, i, lower, i + 1, higher);
+           }
+       }
+    }
+
+    /*
+     * Check parent pointers: all non-NULL kids should have a
+     * parent pointer coming back to this node.
+     */
+    for (i = 0; i < nkids; i++)
+       if (node->kids[i]->parent != node) {
+           error("node %p kid %d: parent ptr is %p not %p",
+                 node, i, node->kids[i]->parent, node);
+       }
+
+
+    /*
+     * Now (finally!) recurse into subtrees.
+     */
+    count = nelems;
+
+    for (i = 0; i < nkids; i++) {
+       void *lower = (i == 0 ? lowbound : node->elems[i - 1]);
+       void *higher = (i >= nelems ? highbound : node->elems[i]);
+       int subcount =
+           chknode(ctx, level + 1, node->kids[i], lower, higher);
+       if (node->counts[i] != subcount) {
+           error("node %p kid %d: count says %d, subtree really has %d",
+                 node, i, node->counts[i], subcount);
+       }
+       count += subcount;
+    }
+
+    return count;
+}
+
+void verify(void)
+{
+    chkctx ctx;
+    int i;
+    void *p;
+
+    ctx.treedepth = -1;                       /* depth unknown yet */
+    ctx.elemcount = 0;                /* no elements seen yet */
+    /*
+     * Verify validity of tree properties.
+     */
+    if (tree->root) {
+       if (tree->root->parent != NULL)
+           error("root->parent is %p should be null", tree->root->parent);
+       chknode(&ctx, 0, tree->root, NULL, NULL);
+    }
+    printf("tree depth: %d\n", ctx.treedepth);
+    /*
+     * Enumerate the tree and ensure it matches up to the array.
+     */
+    for (i = 0; NULL != (p = index234(tree, i)); i++) {
+       if (i >= arraylen)
+           error("tree contains more than %d elements", arraylen);
+       if (array[i] != p)
+           error("enum at position %d: array says %s, tree says %s",
+                 i, array[i], p);
+    }
+    if (ctx.elemcount != i) {
+       error("tree really contains %d elements, enum gave %d",
+             ctx.elemcount, i);
+    }
+    if (i < arraylen) {
+       error("enum gave only %d elements, array has %d", i, arraylen);
+    }
+    i = count234(tree);
+    if (ctx.elemcount != i) {
+       error("tree really contains %d elements, count234 gave %d",
+             ctx.elemcount, i);
+    }
+}
+
+void internal_addtest(void *elem, int index, void *realret)
+{
+    int i, j;
+    void *retval;
+
+    if (arraysize < arraylen + 1) {
+       arraysize = arraylen + 1 + 256;
+       array = sresize(array, arraysize, void *);
+    }
+
+    i = index;
+    /* now i points to the first element >= elem */
+    retval = elem;                    /* expect elem returned (success) */
+    for (j = arraylen; j > i; j--)
+       array[j] = array[j - 1];
+    array[i] = elem;                  /* add elem to array */
+    arraylen++;
+
+    if (realret != retval) {
+       error("add: retval was %p expected %p", realret, retval);
+    }
+
+    verify();
+}
+
+void addtest(void *elem)
+{
+    int i;
+    void *realret;
+
+    realret = add234(tree, elem);
+
+    i = 0;
+    while (i < arraylen && cmp(elem, array[i]) > 0)
+       i++;
+    if (i < arraylen && !cmp(elem, array[i])) {
+       void *retval = array[i];       /* expect that returned not elem */
+       if (realret != retval) {
+           error("add: retval was %p expected %p", realret, retval);
+       }
+    } else
+       internal_addtest(elem, i, realret);
+}
+
+void addpostest(void *elem, int i)
+{
+    void *realret;
+
+    realret = addpos234(tree, elem, i);
+
+    internal_addtest(elem, i, realret);
+}
+
+void delpostest(int i)
+{
+    int index = i;
+    void *elem = array[i], *ret;
+
+    /* i points to the right element */
+    while (i < arraylen - 1) {
+       array[i] = array[i + 1];
+       i++;
+    }
+    arraylen--;                               /* delete elem from array */
+
+    if (tree->cmp)
+       ret = del234(tree, elem);
+    else
+       ret = delpos234(tree, index);
+
+    if (ret != elem) {
+       error("del returned %p, expected %p", ret, elem);
+    }
+
+    verify();
+}
+
+void deltest(void *elem)
+{
+    int i;
+
+    i = 0;
+    while (i < arraylen && cmp(elem, array[i]) > 0)
+       i++;
+    if (i >= arraylen || cmp(elem, array[i]) != 0)
+       return;                        /* don't do it! */
+    delpostest(i);
+}
+
+/* A sample data set and test utility. Designed for pseudo-randomness,
+ * and yet repeatability. */
+
+/*
+ * This random number generator uses the `portable implementation'
+ * given in ANSI C99 draft N869. It assumes `unsigned' is 32 bits;
+ * change it if not.
+ */
+int randomnumber(unsigned *seed)
+{
+    *seed *= 1103515245;
+    *seed += 12345;
+    return ((*seed) / 65536) % 32768;
+}
+
+int mycmp(void *av, void *bv)
+{
+    char const *a = (char const *) av;
+    char const *b = (char const *) bv;
+    return strcmp(a, b);
+}
+
+#define lenof(x) ( sizeof((x)) / sizeof(*(x)) )
+
+char *strings[] = {
+    "a", "ab", "absque", "coram", "de",
+    "palam", "clam", "cum", "ex", "e",
+    "sine", "tenus", "pro", "prae",
+    "banana", "carrot", "cabbage", "broccoli", "onion", "zebra",
+    "penguin", "blancmange", "pangolin", "whale", "hedgehog",
+    "giraffe", "peanut", "bungee", "foo", "bar", "baz", "quux",
+    "murfl", "spoo", "breen", "flarn", "octothorpe",
+    "snail", "tiger", "elephant", "octopus", "warthog", "armadillo",
+    "aardvark", "wyvern", "dragon", "elf", "dwarf", "orc", "goblin",
+    "pixie", "basilisk", "warg", "ape", "lizard", "newt", "shopkeeper",
+    "wand", "ring", "amulet"
+};
+
+#define NSTR lenof(strings)
+
+int findtest(void)
+{
+    const static int rels[] = {
+       REL234_EQ, REL234_GE, REL234_LE, REL234_LT, REL234_GT
+    };
+    const static char *const relnames[] = {
+       "EQ", "GE", "LE", "LT", "GT"
+    };
+    int i, j, rel, index;
+    char *p, *ret, *realret, *realret2;
+    int lo, hi, mid, c;
+
+    for (i = 0; i < NSTR; i++) {
+       p = strings[i];
+       for (j = 0; j < sizeof(rels) / sizeof(*rels); j++) {
+           rel = rels[j];
+
+           lo = 0;
+           hi = arraylen - 1;
+           while (lo <= hi) {
+               mid = (lo + hi) / 2;
+               c = strcmp(p, array[mid]);
+               if (c < 0)
+                   hi = mid - 1;
+               else if (c > 0)
+                   lo = mid + 1;
+               else
+                   break;
+           }
+
+           if (c == 0) {
+               if (rel == REL234_LT)
+                   ret = (mid > 0 ? array[--mid] : NULL);
+               else if (rel == REL234_GT)
+                   ret = (mid < arraylen - 1 ? array[++mid] : NULL);
+               else
+                   ret = array[mid];
+           } else {
+               assert(lo == hi + 1);
+               if (rel == REL234_LT || rel == REL234_LE) {
+                   mid = hi;
+                   ret = (hi >= 0 ? array[hi] : NULL);
+               } else if (rel == REL234_GT || rel == REL234_GE) {
+                   mid = lo;
+                   ret = (lo < arraylen ? array[lo] : NULL);
+               } else
+                   ret = NULL;
+           }
+
+           realret = findrelpos234(tree, p, NULL, rel, &index);
+           if (realret != ret) {
+               error("find(\"%s\",%s) gave %s should be %s",
+                     p, relnames[j], realret, ret);
+           }
+           if (realret && index != mid) {
+               error("find(\"%s\",%s) gave %d should be %d",
+                     p, relnames[j], index, mid);
+           }
+           if (realret && rel == REL234_EQ) {
+               realret2 = index234(tree, index);
+               if (realret2 != realret) {
+                   error("find(\"%s\",%s) gave %s(%d) but %d -> %s",
+                         p, relnames[j], realret, index, index, realret2);
+               }
+           }
+#if 0
+           printf("find(\"%s\",%s) gave %s(%d)\n", p, relnames[j],
+                  realret, index);
+#endif
+       }
+    }
+
+    realret = findrelpos234(tree, NULL, NULL, REL234_GT, &index);
+    if (arraylen && (realret != array[0] || index != 0)) {
+       error("find(NULL,GT) gave %s(%d) should be %s(0)",
+             realret, index, array[0]);
+    } else if (!arraylen && (realret != NULL)) {
+       error("find(NULL,GT) gave %s(%d) should be NULL", realret, index);
+    }
+
+    realret = findrelpos234(tree, NULL, NULL, REL234_LT, &index);
+    if (arraylen
+       && (realret != array[arraylen - 1] || index != arraylen - 1)) {
+       error("find(NULL,LT) gave %s(%d) should be %s(0)", realret, index,
+             array[arraylen - 1]);
+    } else if (!arraylen && (realret != NULL)) {
+       error("find(NULL,LT) gave %s(%d) should be NULL", realret, index);
+    }
+}
+
+int main(void)
+{
+    int in[NSTR];
+    int i, j, k;
+    unsigned seed = 0;
+
+    for (i = 0; i < NSTR; i++)
+       in[i] = 0;
+    array = NULL;
+    arraylen = arraysize = 0;
+    tree = newtree234(mycmp);
+    cmp = mycmp;
+
+    verify();
+    for (i = 0; i < 10000; i++) {
+       j = randomnumber(&seed);
+       j %= NSTR;
+       printf("trial: %d\n", i);
+       if (in[j]) {
+           printf("deleting %s (%d)\n", strings[j], j);
+           deltest(strings[j]);
+           in[j] = 0;
+       } else {
+           printf("adding %s (%d)\n", strings[j], j);
+           addtest(strings[j]);
+           in[j] = 1;
+       }
+       findtest();
+    }
+
+    while (arraylen > 0) {
+       j = randomnumber(&seed);
+       j %= arraylen;
+       deltest(array[j]);
+    }
+
+    freetree234(tree);
+
+    /*
+     * Now try an unsorted tree. We don't really need to test
+     * delpos234 because we know del234 is based on it, so it's
+     * already been tested in the above sorted-tree code; but for
+     * completeness we'll use it to tear down our unsorted tree
+     * once we've built it.
+     */
+    tree = newtree234(NULL);
+    cmp = NULL;
+    verify();
+    for (i = 0; i < 1000; i++) {
+       printf("trial: %d\n", i);
+       j = randomnumber(&seed);
+       j %= NSTR;
+       k = randomnumber(&seed);
+       k %= count234(tree) + 1;
+       printf("adding string %s at index %d\n", strings[j], k);
+       addpostest(strings[j], k);
+    }
+    while (count234(tree) > 0) {
+       printf("cleanup: tree size %d\n", count234(tree));
+       j = randomnumber(&seed);
+       j %= count234(tree);
+       printf("deleting string %s from index %d\n", array[j], j);
+       delpostest(j);
+    }
+
+    return 0;
+}
+
+#endif
diff --git a/arm/vt100/tree234.h b/arm/vt100/tree234.h
new file mode 100644 (file)
index 0000000..ba74308
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * tree234.h: header defining functions in tree234.c.
+ * 
+ * This file is copyright 1999-2001 Simon Tatham.
+ * 
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL SIMON TATHAM BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef TREE234_H
+#define TREE234_H
+
+/*
+ * This typedef is opaque outside tree234.c itself.
+ */
+typedef struct tree234_Tag tree234;
+
+typedef int (*cmpfn234) (void *, void *);
+
+/*
+ * Create a 2-3-4 tree. If `cmp' is NULL, the tree is unsorted, and
+ * lookups by key will fail: you can only look things up by numeric
+ * index, and you have to use addpos234() and delpos234().
+ */
+tree234 *newtree234(cmpfn234 cmp);
+
+/*
+ * Free a 2-3-4 tree (not including freeing the elements).
+ */
+void freetree234(tree234 * t);
+
+/*
+ * Add an element e to a sorted 2-3-4 tree t. Returns e on success,
+ * or if an existing element compares equal, returns that.
+ */
+void *add234(tree234 * t, void *e);
+
+/*
+ * Add an element e to an unsorted 2-3-4 tree t. Returns e on
+ * success, NULL on failure. (Failure should only occur if the
+ * index is out of range or the tree is sorted.)
+ * 
+ * Index range can be from 0 to the tree's current element count,
+ * inclusive.
+ */
+void *addpos234(tree234 * t, void *e, int index);
+
+/*
+ * Look up the element at a given numeric index in a 2-3-4 tree.
+ * Returns NULL if the index is out of range.
+ * 
+ * One obvious use for this function is in iterating over the whole
+ * of a tree (sorted or unsorted):
+ * 
+ *   for (i = 0; (p = index234(tree, i)) != NULL; i++) consume(p);
+ * 
+ * or
+ * 
+ *   int maxcount = count234(tree);
+ *   for (i = 0; i < maxcount; i++) {
+ *       p = index234(tree, i);
+ *       assert(p != NULL);
+ *       consume(p);
+ *   }
+ */
+void *index234(tree234 * t, int index);
+
+/*
+ * Find an element e in a sorted 2-3-4 tree t. Returns NULL if not
+ * found. e is always passed as the first argument to cmp, so cmp
+ * can be an asymmetric function if desired. cmp can also be passed
+ * as NULL, in which case the compare function from the tree proper
+ * will be used.
+ * 
+ * Three of these functions are special cases of findrelpos234. The
+ * non-`pos' variants lack the `index' parameter: if the parameter
+ * is present and non-NULL, it must point to an integer variable
+ * which will be filled with the numeric index of the returned
+ * element.
+ * 
+ * The non-`rel' variants lack the `relation' parameter. This
+ * parameter allows you to specify what relation the element you
+ * provide has to the element you're looking for. This parameter
+ * can be:
+ * 
+ *   REL234_EQ     - find only an element that compares equal to e
+ *   REL234_LT     - find the greatest element that compares < e
+ *   REL234_LE     - find the greatest element that compares <= e
+ *   REL234_GT     - find the smallest element that compares > e
+ *   REL234_GE     - find the smallest element that compares >= e
+ * 
+ * Non-`rel' variants assume REL234_EQ.
+ * 
+ * If `rel' is REL234_GT or REL234_LT, the `e' parameter may be
+ * NULL. In this case, REL234_GT will return the smallest element
+ * in the tree, and REL234_LT will return the greatest. This gives
+ * an alternative means of iterating over a sorted tree, instead of
+ * using index234:
+ * 
+ *   // to loop forwards
+ *   for (p = NULL; (p = findrel234(tree, p, NULL, REL234_GT)) != NULL ;)
+ *       consume(p);
+ * 
+ *   // to loop backwards
+ *   for (p = NULL; (p = findrel234(tree, p, NULL, REL234_LT)) != NULL ;)
+ *       consume(p);
+ */
+enum {
+    REL234_EQ, REL234_LT, REL234_LE, REL234_GT, REL234_GE
+};
+void *find234(tree234 * t, void *e, cmpfn234 cmp);
+void *findrel234(tree234 * t, void *e, cmpfn234 cmp, int relation);
+void *findpos234(tree234 * t, void *e, cmpfn234 cmp, int *index);
+void *findrelpos234(tree234 * t, void *e, cmpfn234 cmp, int relation,
+                   int *index);
+
+/*
+ * Delete an element e in a 2-3-4 tree. Does not free the element,
+ * merely removes all links to it from the tree nodes.
+ * 
+ * delpos234 deletes the element at a particular tree index: it
+ * works on both sorted and unsorted trees.
+ * 
+ * del234 deletes the element passed to it, so it only works on
+ * sorted trees. (It's equivalent to using findpos234 to determine
+ * the index of an element, and then passing that index to
+ * delpos234.)
+ * 
+ * Both functions return a pointer to the element they delete, for
+ * the user to free or pass on elsewhere or whatever. If the index
+ * is out of range (delpos234) or the element is already not in the
+ * tree (del234) then they return NULL.
+ */
+void *del234(tree234 * t, void *e);
+void *delpos234(tree234 * t, int index);
+
+/*
+ * Return the total element count of a tree234.
+ */
+int count234(tree234 * t);
+
+#endif                         /* TREE234_H */
diff --git a/arm/vt100/vt100.c b/arm/vt100/vt100.c
new file mode 100644 (file)
index 0000000..5d7f0fd
--- /dev/null
@@ -0,0 +1,546 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "vt100.h"
+#include "data/prefs.h"
+#include "rsrc/rsrc.h"
+#include "ssh/ssh.h"
+
+#include "putty.h"
+#include "terminal.h"
+
+display *gdd = NULL;
+
+static struct unicode_data *ucsdata;
+
+static int inited = 0;
+static FontID NanoFontIDForScreen;
+static FontID MediumFontIDForScreen;
+
+static void vt100_set_native_bounds(display *disp, RectangleType bounds);
+static Boolean read_font_from_prefs(display *disp);
+static void vt100_read_prefs(display *disp);
+static void choose_fonts_for_screen(void);
+FontID font_for_screen(int fontPref);
+static void set_default_config(Config *cfg);
+
+FontID font_for_screen(int fontPref)
+{
+    UInt32 density;
+    Boolean lowres;
+
+    WinScreenGetAttribute(winScreenDensity, &density);
+
+    switch (density) {
+    case kDensityDouble:
+    case kDensityTriple:
+    case kDensityQuadruple:
+        lowres = false;
+        break;
+    case kDensityLow:
+    case kDensityOneAndAHalf:
+    default:
+        lowres = true;
+        break;
+    }
+
+    switch (fontPref) {
+    case font6x10: return lowres ? MediumFontSingleID : MediumFontDoubleID;
+    case font4x6: 
+    default: return lowres ? NanoFontSingleID : NanoFontDoubleID; 
+    }
+}
+
+static void choose_fonts_for_screen(void)
+{
+    vt100_log(__PRETTY_FUNCTION__);
+    NanoFontIDForScreen = font_for_screen(font4x6);
+    MediumFontIDForScreen = font_for_screen(font6x10);
+}
+
+static Boolean read_font_from_prefs(display *disp)
+{
+    uint32_t value = PrefsGetInt(prefTerminalFont, fontDefault);
+
+    if (value == font4x6  &&  value != disp->fontPref) {
+        disp->fontPref = value;
+        disp->fontID = NanoFontIDForScreen;
+        disp->font_width = 4;
+        disp->font_height = 6;
+        return true;
+    }
+    else if (value == font6x10  &&  value != disp->fontPref) {
+        disp->fontPref = value;
+        disp->fontID = MediumFontIDForScreen;
+        disp->font_width = 6; 
+        disp->font_height = 10;
+        return true;
+    }
+    else if (disp->fontID == 0) {
+        // no font set and pref's value isn't understood - force to default
+        disp->fontPref = font4x6;
+        disp->fontID = NanoFontIDForScreen;
+        disp->font_width = 4;
+        disp->font_height = 6;
+        return true;
+    }
+    else {
+        // no change
+        return false;
+    }
+}
+
+static short defaultWordness[] = {
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
+    0,1,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,
+    1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2,
+    1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,
+    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2
+};
+static void set_default_config(Config *cfg)
+{
+    strcpy(cfg->host, "");
+    cfg->port = 22;
+    cfg->protocol = PROT_SSH;
+    cfg->close_on_exit = 0;
+    cfg->warn_on_close = 0;
+    cfg->ping_interval = 0;
+    cfg->tcp_nodelay = 1;
+
+    strcpy(cfg->proxy_exclude_list, "");
+    cfg->proxy_dns = 1;
+    cfg->even_proxy_localhost = 0;
+    cfg->proxy_type = PROXY_NONE;
+    strcpy(cfg->proxy_host, "");
+    cfg->proxy_port = 80;
+    strcpy(cfg->proxy_username, "");
+    strcpy(cfg->proxy_password, "");
+    strcpy(cfg->proxy_telnet_command, "connect %host %port");
+
+    strcpy(cfg->remote_cmd, "");
+    strcpy(cfg->remote_cmd2, "");
+    cfg->remote_cmd_ptr = cfg->remote_cmd;
+    cfg->remote_cmd_ptr2 = cfg->remote_cmd2;
+    cfg->nopty = 0;
+    cfg->compression = 0;
+    cfg->agentfwd = 0;
+    cfg->change_username = 0;
+    // cfg->ssh_cipherlist
+    // cfg->filename
+    cfg->sshprot = 2;
+    cfg->ssh2_des_cbc = 0;
+    cfg->try_tis_auth = 0;
+    cfg->try_ki_auth = 0;
+    cfg->ssh_subsys = 0;
+    cfg->ssh_subsys2 = 0;
+
+    cfg->termtype = arena_strdup("xterm");
+    strcpy(cfg->termspeed, "38400,38400");
+    strcpy(cfg->environmt, "");
+    strcpy(cfg->username, "");
+    strcpy(cfg->localusername, "");
+    cfg->rfc_environ = 0;
+    cfg->passive_telnet = 0;
+
+    cfg->bksp_is_delete = 1;
+    cfg->rxvt_homeend = 0;
+    cfg->funky_type = 0;
+    cfg->no_applic_c = 0;
+    cfg->no_applic_k = 0;
+    cfg->no_mouse_rep = 0;
+    cfg->no_remote_resize = 1;
+    cfg->no_alt_screen = 0;
+    cfg->no_remote_wintitle = 0;
+    cfg->no_dbackspace = 0;
+    cfg->no_remote_charset = 0;
+    cfg->no_remote_qtitle = 1;
+    cfg->app_cursor = 0;
+    cfg->app_keypad = 0;
+    cfg->nethack_keypad = 0;
+    cfg->telnet_keyboard = 0;
+    cfg->telnet_newline = 1;
+    cfg->alt_f4 = 0;
+    cfg->alt_space = 0;
+    cfg->alt_only = 0;
+    cfg->localecho = 0;
+    cfg->localedit = 0;
+    cfg->alwaysontop = 1;
+    cfg->fullscreenonaltenter = 0;
+    cfg->scroll_on_key = defaultScrollDownOnTyping;
+    cfg->scroll_on_disp = defaultScrollDownOnActivity;
+    cfg->erase_to_scrollback = 1;
+    cfg->compose_key = 0;
+    cfg->ctrlaltkeys = 1;
+    strcpy(cfg->wintitle, "");
+    cfg->savelines = defaultScrollbackLines;
+    cfg->dec_om = 0;
+    cfg->wrap_mode = 1;
+    cfg->lfhascr = 0;
+    cfg->cursor_type = 0;
+    cfg->blink_cur = 0;
+    cfg->beep = BELL_AUDIBLE;
+    cfg->beep_ind = 0;
+    cfg->bellovl = 1;
+    cfg->bellovl_n = 5;
+    cfg->bellovl_t = 2*TICKSPERSEC;
+    cfg->bellovl_s = 5*TICKSPERSEC;
+    cfg->scrollbar = 1;
+    cfg->scrollbar_in_fullscreen = 0;
+    cfg->resize_action = 0;
+    cfg->bce = 1;
+    cfg->blinktext = 0;
+    cfg->win_name_always = 1;
+    cfg->width = 80;
+    cfg->height = 24;
+    // cfg->font fixme;
+    cfg->logtype = 0;
+    cfg->logxfovr = 0;
+    cfg->hide_mouseptr = 0;
+    cfg->sunken_edge = 0;
+    cfg->window_border = 1;
+    strcpy(cfg->answerback, "pssh");
+    strcpy(cfg->printer, "");
+
+    cfg->system_colour = 0;
+    cfg->try_palette = 0;
+    cfg->bold_colour = 1;
+    // cfg->colours fixme
+
+    cfg->mouse_is_xterm = 0;
+    cfg->rect_select = 0;
+    cfg->rawcnp = 0;
+    cfg->rtf_paste = 0;
+    cfg->mouse_override = 1;
+    cfg->wordness = defaultWordness;
+
+    cfg->vtmode = VT_UNICODE;
+    strcpy(cfg->line_codepage, "ISO-8859-1");
+    cfg->xlat_capslockcyr = 0;
+}
+
+
+// bounds is STANDARD-RESOLUTION
+display *vt100_new(struct ssh_session_t *ss, RectangleType bounds) 
+{
+    display *disp;
+
+    vt100_log(__PRETTY_FUNCTION__);
+    if (!inited) {
+        // first-time init
+        choose_fonts_for_screen();
+        inited = 1;
+    }
+
+    disp = arena_calloc(sizeof(display));
+    gdd = disp;
+    disp->ss = ss;
+    disp->cfg = arena_calloc(sizeof(struct config_tag));
+
+    palette_reset(disp);
+    set_default_config(disp->cfg);
+    vt100_read_prefs(disp);
+
+    ucsdata = arena_calloc(sizeof(struct unicode_data));
+    init_ucs(ucsdata, DEFAULT_CODEPAGE, disp->cfg->vtmode);
+
+    disp->term = term_init(disp->cfg, ucsdata, disp);
+    disp->term->ldisc = disp;
+    vt100_set_bounds(disp, bounds);
+
+    return disp;
+}
+
+void vt100_free(display *disp) 
+{
+    term_clrsb(disp->term);
+    arena_free(disp);
+    gdd = NULL;
+}
+
+void vt100_write(display *disp, const char *bytes, size_t len) 
+{
+    if (len > 0) {
+        term_data(disp->term, 0, bytes, len);
+        term_out(disp->term);
+    }
+}
+
+
+int from_backend(void *frontend, int is_stderr, const char *data, size_t len)
+{
+    display *disp = (display *)frontend;
+    vt100_write(disp, data, len);
+    return 0;
+}
+
+
+// trivial ldisc - fixme use putty's instead
+
+void ldisc_send(void *handle, char *buf, ssize_t len, int interactive)
+{
+    display *disp = (display *)handle;
+    if (len == 0) return;
+
+    // len < 0 isn't used in terminal.c
+
+    ssh_bytes(disp->ss, (uint8_t *)buf, len);
+}
+
+
+void lpage_send(void *handle,
+               int codepage, char *buf, size_t len, int interactive)
+{
+    // no codepage support other than ISO 8859-1
+    ldisc_send(handle, buf, len, interactive);
+}
+
+
+void luni_send(void *handle, wchar_t * widebuf, size_t len, int interactive)
+{
+    display *disp = (display *)handle;
+    unsigned int ratio = (in_utf(disp->term))?3:1;
+    char *linebuffer;
+    size_t linesize;
+    unsigned int i;
+    char *p;
+
+    linesize = len * ratio * 2;
+    linebuffer = snewn(linesize, char);
+
+    if (in_utf(disp->term)) {
+       /* UTF is a simple algorithm */
+       for (p = linebuffer, i = 0; i < len; i++) {
+           wchar_t ch = widebuf[i];
+           /* We only deal with 16-bit wide chars */
+           if ((ch&0xF800) == 0xD800) ch = '.';
+
+           if (ch < 0x80) {
+               *p++ = (char) (ch);
+           } else if (ch < 0x800) {
+               *p++ = (0xC0 | (ch >> 6));
+               *p++ = (0x80 | (ch & 0x3F));
+           } else {
+               *p++ = (0xE0 | (ch >> 12));
+               *p++ = (0x80 | ((ch >> 6) & 0x3F));
+               *p++ = (0x80 | (ch & 0x3F));
+           }
+       }
+    } else {
+       ssize_t rv;
+       rv = wc_to_mb(disp->term->ucsdata->line_codepage, 0, widebuf, len,
+                     linebuffer, linesize, NULL, NULL, disp->term->ucsdata);
+       if (rv >= 0)
+           p = linebuffer + rv;
+       else
+           p = linebuffer;
+    }
+    if (p > linebuffer)
+       ldisc_send(disp, linebuffer, p - linebuffer, interactive);
+
+    sfree(linebuffer);
+}
+
+
+
+void vt100_update(display *disp)
+{
+    term_task(disp->term);
+    term_update(disp->term);
+}
+
+void vt100_task(display *disp)
+{
+    term_task(disp->term);
+}
+
+void vt100_scroll(display *disp, int lines) 
+{
+    term_scroll(disp->term, 0, lines);
+}
+
+void vt100_activate(display *disp) 
+{
+    disp->inactive = false;
+    term_invalidate(disp->term);
+}
+
+void vt100_deactivate(display *disp) 
+{
+    disp->inactive = true;
+}
+
+// bounds is NATIVE-RESOLUTION
+static void vt100_set_native_bounds(display *disp, RectangleType bounds)
+{
+    int cw, ch;
+
+    disp->gadgetBounds = bounds;
+
+    cw = disp->gadgetBounds.extent.x / disp->font_width;
+    ch = disp->gadgetBounds.extent.y / disp->font_height;
+
+    disp->textBounds.topLeft = disp->gadgetBounds.topLeft;
+    disp->textBounds.extent.x = cw * disp->font_width;
+    disp->textBounds.extent.y = ch * disp->font_height;
+    // fixme center text area inside gadget
+
+    term_size(disp->term, ch, cw, PrefsGetInt(prefScrollbackLines,defaultScrollbackLines));
+    
+    term_invalidate(disp->term);
+}
+
+
+// bounds is STANDARD-RESOLUTION
+void vt100_set_bounds(display *disp, RectangleType bounds)
+{
+    // scale bounds to native-resolution
+    WinPushDrawState();
+    WinSetCoordinateSystem(kCoordinatesNative);
+    WinScaleRectangle(&bounds); // convert from standard to native
+    disp->closeBoxSize = WinScaleCoord(6, false);
+    WinPopDrawState();
+
+    vt100_set_native_bounds(disp, bounds);
+}
+
+
+// bounds returned is NATIVE-RESOLUTION
+void vt100_size(display *disp, int *charsWide, int *charsHigh, 
+                RectangleType *bounds)
+{
+    if (charsWide) *charsWide = disp->textBounds.extent.x / disp->font_width;
+    if (charsHigh) *charsHigh = disp->textBounds.extent.y / disp->font_height;
+    if (bounds) *bounds = disp->gadgetBounds;
+}
+
+
+// x and y are STANDARD-RESOLUTION
+// clickCount is 1 or more for mouse down, 0 for mouse up
+void vt100_click(display *disp, int x, int y, int clickCount)
+{
+    Coord hix, hiy;
+    int charx, chary;
+    Mouse_Action action;
+
+    // scale point to hi-res
+    WinPushDrawState();
+    WinSetCoordinateSystem(kCoordinatesNative);
+    hix = WinScaleCoord(x, false); // convert from standard to native
+    hiy = WinScaleCoord(y, false); // convert from standard to native
+    WinPopDrawState();
+
+    // calculate coordinate
+    charx = (hix - disp->textBounds.topLeft.x) / disp->font_width;
+    chary = (hiy - disp->textBounds.topLeft.y) / disp->font_height;
+
+    // choose mouse button and mouse action
+    switch (clickCount) {
+    case -1: action = MA_DRAG; break;
+    case 0:  action = MA_RELEASE; break; // mouse up
+    case 1:  action = MA_CLICK;   break; // mouse down
+    case 2:  action = MA_2CLK;    break; // double-click
+    case 3:  action = MA_3CLK;    break; // triple-click
+    default: return; // ignore 4+ clicks (fixme?)
+    }
+    
+    // fixme shift/ctrl/alt modifiers?
+    // send at least one drag before release
+    term_mouse(disp->term, MBT_LEFT, MBT_SELECT, action, charx, chary, 0, 0, 0);
+}
+
+
+void vt100_deselect(display *disp)
+{
+    term_deselect(disp->term);
+}
+
+
+void vt100_copy(display *disp)
+{
+    term_copy(disp->term);
+}
+
+void vt100_paste(display *disp) 
+{
+    term_do_paste(disp->term);
+}
+
+int vt100_selection_exists(display *disp) 
+{
+    return term_selection_exists(disp->term);
+}
+
+static void vt100_read_prefs(display *disp)
+{
+    Config *cfg = disp->cfg;
+
+    vt100_log(__PRETTY_FUNCTION__);
+
+    // values used outside cfg
+    read_font_from_prefs(disp);
+    read_default_colors();
+
+    // values used only in cfg
+
+    if (cfg->termtype) arena_free(cfg->termtype);
+    cfg->termtype = PrefsGetString(prefTerminalType, "xterm");
+
+    cfg->scroll_on_key = PrefsGetInt(prefScrollDownOnTyping, defaultScrollDownOnTyping);
+    cfg->scroll_on_disp = PrefsGetInt(prefScrollDownOnActivity, defaultScrollDownOnActivity);
+    cfg->savelines = PrefsGetInt(prefScrollbackLines, defaultScrollbackLines);
+
+    cfg->beep = 0;
+    if (PrefsGetInt(prefBellBeep, defaultBellBeep))  cfg->beep |= BELL_AUDIBLE;
+    if (PrefsGetInt(prefBellFlash,defaultBellFlash)) cfg->beep |= BELL_VISIBLE;
+
+    // cfg->width used only in calls to request_resize()
+    // cfg->height used only in calls to request_resize()
+
+    if (disp->term) term_reconfig(disp->term, disp->cfg);
+}
+
+void vt100_reread_prefs(display *disp) 
+{
+    vt100_read_prefs(disp);
+
+    // resize and set scrollback
+    vt100_set_native_bounds(disp, disp->gadgetBounds);
+
+    // force redraw
+    term_invalidate(disp->term);
+}
+
+void vt100_seen_key(display *disp)
+{
+    term_seen_key_event(disp->term);
+}
+
+int vt100_app_cursor_keys(display *disp) 
+{
+    return term_app_cursor_keys(disp->term);
+}
diff --git a/arm/vt100/vt100.h b/arm/vt100/vt100.h
new file mode 100644 (file)
index 0000000..8088404
--- /dev/null
@@ -0,0 +1,99 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef VT100_H
+#define VT100_H
+
+#include "includes.h"
+
+typedef struct display {
+    // ALL OF THE VALUES BELOW ARE NATIVE-RESOLUTION
+    // gadgetBounds is the bounds of the gadget
+    // textBounds is the area inside the gadget that can be occupied by 
+    //   terminal text of the corrent font. 
+    // gadgetBounds != textBounds if the current font size doesn't evenly 
+    //   divide the gadget size
+    RectangleType gadgetBounds;
+    RectangleType textBounds;
+    int font_width;
+    int font_height;
+    int closeBoxSize;
+
+    int fontPref;
+    FontID fontID;
+    int inactive; // TRUE if we shouldn't draw anything now
+
+    struct terminal_tag *term;
+    struct config_tag *cfg;
+    struct ssh_session_t *ss;
+} display;
+
+// bounds is STANDARD-RESOLUTION
+display *vt100_new(struct ssh_session_t *ss, 
+                   RectangleType bounds);
+
+void vt100_free(display *disp);
+
+void vt100_write(display *disp, const char *bytes, size_t len);
+
+void vt100_update(display *disp);
+
+void vt100_task(display *disp);
+
+void vt100_scroll(display *disp, int lines);
+
+void vt100_activate(display *disp);
+
+void vt100_deactivate(display *disp);
+
+// in: bounds (STANDARD-RESOLUTION)
+// out: charsWide and charsHigh
+void vt100_set_bounds(display *disp, RectangleType bounds);
+
+// x and y are STANDARD-RESOLUTION
+// clickCount is 1 or more for mouse down, 0 for mouse up
+void vt100_click(display *disp, int x, int y, int clickCount);
+
+void vt100_deselect(display *disp);
+
+void vt100_copy(display *disp);
+
+void vt100_paste(display *disp);
+
+int vt100_selection_exists(display *disp);
+
+// bounds returned is NATIVE-RESOLUTION
+void vt100_size(display *disp, int *charsWide, int *charsHigh, RectangleType *bounds);
+
+void vt100_reread_prefs(display *disp);
+
+void vt100_seen_key(display *disp);
+
+int vt100_app_cursor_keys(display *disp); // fixme suck
+
+FontID font_for_screen(int fontPref);
+
+void set_palm_color(int fg_color, int bg_color);
+
+#endif
diff --git a/arm/vt100/vt100_armcalls.c b/arm/vt100/vt100_armcalls.c
new file mode 100644 (file)
index 0000000..f8f7062
--- /dev/null
@@ -0,0 +1,210 @@
+#include "vt100.h"
+#include "pealstub.h"
+#include "swap.h"
+
+uint32_t vt100_new_stub(uint32_t *param);
+uint32_t vt100_free_stub(uint32_t *param);
+uint32_t vt100_write_stub(uint32_t *param);
+uint32_t vt100_update_stub(uint32_t *param);
+uint32_t vt100_task_stub(uint32_t *param);
+uint32_t vt100_scroll_stub(uint32_t *param);
+uint32_t vt100_activate_stub(uint32_t *param);
+uint32_t vt100_deactivate_stub(uint32_t *param);
+uint32_t vt100_set_bounds_stub(uint32_t *param);
+uint32_t vt100_click_stub(uint32_t *param);
+uint32_t vt100_deselect_stub(uint32_t *param);
+uint32_t vt100_copy_stub(uint32_t *param);
+uint32_t vt100_paste_stub(uint32_t *param);
+uint32_t vt100_selection_exists_stub(uint32_t *param);
+uint32_t vt100_size_stub(uint32_t *param);
+uint32_t vt100_reread_prefs_stub(uint32_t *param);
+uint32_t vt100_seen_key_stub(uint32_t *param);
+uint32_t vt100_app_cursor_keys_stub(uint32_t *param);
+uint32_t font_for_screen_stub(uint32_t *param);
+uint32_t set_palm_color_stub(uint32_t *param);
+
+
+uint32_t vt100_new_stub(uint32_t *param) 
+{
+    struct ssh_session_t *ss = (struct ssh_session_t *)read32(&param[0]);
+    RectangleType bounds = readRect(read32(&param[1]));
+    return (uint32_t) vt100_new(ss, bounds);
+}
+
+
+uint32_t vt100_free_stub(uint32_t *param) 
+{
+    struct display *disp = (struct display *)read32(&param[0]);
+    vt100_free(disp);
+    return 0;
+}
+
+
+uint32_t vt100_write_stub(uint32_t *param) 
+{
+    struct display *disp = (struct display *)read32(&param[0]);
+    const char *bytes = (const char *)read32(&param[1]);
+    size_t len = (size_t)read32(&param[2]);
+    vt100_write(disp, bytes, len);
+    return 0;
+}
+
+
+uint32_t vt100_update_stub(uint32_t *param) 
+{
+    struct display *disp = (struct display *)read32(&param[0]);
+    vt100_update(disp);
+    return 0;
+}
+
+
+uint32_t vt100_task_stub(uint32_t *param) 
+{
+    struct display *disp = (struct display *)read32(&param[0]);
+    vt100_task(disp);
+    return 0;
+}
+
+
+uint32_t vt100_scroll_stub(uint32_t *param) 
+{
+    struct display *disp = (struct display *)read32(&param[0]);
+    int lines = (int)read32(&param[1]);
+    vt100_scroll(disp, lines);
+    return 0;
+}
+
+
+uint32_t vt100_activate_stub(uint32_t *param) 
+{
+    struct display *disp = (struct display *)read32(&param[0]);
+    vt100_activate(disp);
+    return 0;
+}
+
+
+uint32_t vt100_deactivate_stub(uint32_t *param) 
+{
+    struct display *disp = (struct display *)read32(&param[0]);
+    vt100_deactivate(disp);
+    return 0;
+}
+
+
+uint32_t vt100_set_bounds_stub(uint32_t *param) 
+{
+    struct display *disp = (struct display *)read32(&param[0]);
+    RectangleType bounds = readRect(read32(&param[1]));
+    vt100_set_bounds(disp, bounds);
+    return 0;
+}
+
+
+uint32_t vt100_click_stub(uint32_t *param) 
+{
+    struct display *disp = (struct display *)read32(&param[0]);
+    int x = (int)read32(&param[1]);
+    int y = (int)read32(&param[2]);
+    int clickCount = (int)read32(&param[3]);
+    vt100_click(disp, x, y, clickCount);
+    return 0;
+}
+
+
+uint32_t vt100_deselect_stub(uint32_t *param) 
+{
+    struct display *disp = (struct display *)read32(&param[0]);
+    vt100_deselect(disp);
+    return 0;
+}
+
+
+uint32_t vt100_copy_stub(uint32_t *param) 
+{
+    struct display *disp = (struct display *)read32(&param[0]);
+    vt100_copy(disp);
+    return 0;
+}
+
+
+uint32_t vt100_paste_stub(uint32_t *param) 
+{
+    struct display *disp = (struct display *)read32(&param[0]);
+    vt100_paste(disp);
+    return 0;
+}
+
+
+uint32_t vt100_selection_exists_stub(uint32_t *param) 
+{
+    struct display *disp = (struct display *)read32(&param[0]);
+    return (uint32_t) vt100_selection_exists(disp);
+}
+
+
+uint32_t vt100_size_stub(uint32_t *param) 
+{
+    struct display *disp = (struct display *)read32(&param[0]);
+    int16_t *charsWideP = (int16_t *)read32(&param[1]);
+    int16_t *charsHighP = (int16_t *)read32(&param[2]);
+    RectangleType *boundsP = (RectangleType *)read32(&param[3]);
+
+    RectangleType bounds;
+    int charsWide;
+    int charsHigh;
+
+    if (charsWideP) charsWide = read16(charsWideP);
+    if (charsHighP) charsHigh = read16(charsHighP);
+    if (boundsP) bounds = readRect(boundsP);
+
+    vt100_size(disp, 
+               charsWideP ? &charsWide : NULL, 
+               charsHighP ? &charsHigh : NULL, 
+               boundsP ? &bounds : NULL);
+
+    if (charsWideP) write16(charsWideP, charsWide);
+    if (charsHighP) write16(charsHighP, charsHigh);
+    if (boundsP) writeRect(boundsP, bounds);
+
+    return 0;
+}
+
+
+uint32_t vt100_reread_prefs_stub(uint32_t *param) 
+{
+    struct display *disp = (struct display *)read32(&param[0]);
+    vt100_reread_prefs(disp);
+    return 0;
+}
+
+
+uint32_t vt100_seen_key_stub(uint32_t *param) 
+{
+    struct display *disp = (struct display *)read32(&param[0]);
+    vt100_seen_key(disp);
+    return 0;
+}
+
+
+uint32_t vt100_app_cursor_keys_stub(uint32_t *param) 
+{
+    struct display *disp = (struct display *)read32(&param[0]);
+    return (uint32_t) vt100_app_cursor_keys(disp);
+}
+
+
+uint32_t font_for_screen_stub(uint32_t *param) 
+{
+    int fontPref = (int)read32(&param[0]);
+    return (uint32_t) font_for_screen(fontPref);
+}
+
+
+uint32_t set_palm_color_stub(uint32_t *param) 
+{
+    int fg_color = (int)read32(&param[0]);
+    int bg_color = (int)read32(&param[1]);
+    set_palm_color(fg_color, bg_color);
+    return 0;
+}
+
diff --git a/arm/vt100/wcwidth.c b/arm/vt100/wcwidth.c
new file mode 100644 (file)
index 0000000..2a38b83
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * This is an implementation of wcwidth() and wcswidth() as defined in
+ * "The Single UNIX Specification, Version 2, The Open Group, 1997"
+ * <http://www.UNIX-systems.org/online.html>
+ *
+ * Markus Kuhn -- 2001-01-12 -- public domain
+ */
+
+#include "putty.h"
+
+struct interval {
+  unsigned short first;
+  unsigned short last;
+};
+
+static int bisearch(wchar_t ucs, const struct interval *table, int max);
+
+/* auxiliary function for binary search in interval table */
+static int bisearch(wchar_t ucs, const struct interval *table, int max) {
+  int min = 0;
+  int mid;
+
+  if (ucs < table[0].first || ucs > table[max].last)
+    return 0;
+  while (max >= min) {
+    mid = (min + max) / 2;
+    if (ucs > table[mid].last)
+      min = mid + 1;
+    else if (ucs < table[mid].first)
+      max = mid - 1;
+    else
+      return 1;
+  }
+
+  return 0;
+}
+
+
+/* The following functions define the column width of an ISO 10646
+ * character as follows:
+ *
+ *    - The null character (U+0000) has a column width of 0.
+ *
+ *    - Other C0/C1 control characters and DEL will lead to a return
+ *      value of -1.
+ *
+ *    - Non-spacing and enclosing combining characters (general
+ *      category code Mn or Me in the Unicode database) have a
+ *      column width of 0.
+ *
+ *    - Other format characters (general category code Cf in the Unicode
+ *      database) and ZERO WIDTH SPACE (U+200B) have a column width of 0.
+ *
+ *    - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF)
+ *      have a column width of 0.
+ *
+ *    - Spacing characters in the East Asian Wide (W) or East Asian
+ *      FullWidth (F) category as defined in Unicode Technical
+ *      Report #11 have a column width of 2.
+ *
+ *    - All remaining characters (including all printable
+ *      ISO 8859-1 and WGL4 characters, Unicode control characters,
+ *      etc.) have a column width of 1.
+ *
+ * This implementation assumes that wchar_t characters are encoded
+ * in ISO 10646.
+ */
+
+  /* sorted list of non-overlapping intervals of non-spacing characters */
+  static const struct interval combining[] = {
+    { 0x0300, 0x034E }, { 0x0360, 0x0362 }, { 0x0483, 0x0486 },
+    { 0x0488, 0x0489 }, { 0x0591, 0x05A1 }, { 0x05A3, 0x05B9 },
+    { 0x05BB, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 },
+    { 0x05C4, 0x05C4 }, { 0x064B, 0x0655 }, { 0x0670, 0x0670 },
+    { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED },
+    { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A },
+    { 0x07A6, 0x07B0 }, { 0x0901, 0x0902 }, { 0x093C, 0x093C },
+    { 0x0941, 0x0948 }, { 0x094D, 0x094D }, { 0x0951, 0x0954 },
+    { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, { 0x09BC, 0x09BC },
+    { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, { 0x09E2, 0x09E3 },
+    { 0x0A02, 0x0A02 }, { 0x0A3C, 0x0A3C }, { 0x0A41, 0x0A42 },
+    { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, { 0x0A70, 0x0A71 },
+    { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, { 0x0AC1, 0x0AC5 },
+    { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, { 0x0B01, 0x0B01 },
+    { 0x0B3C, 0x0B3C }, { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 },
+    { 0x0B4D, 0x0B4D }, { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 },
+    { 0x0BC0, 0x0BC0 }, { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 },
+    { 0x0C46, 0x0C48 }, { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 },
+    { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD },
+    { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D }, { 0x0DCA, 0x0DCA },
+    { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 }, { 0x0E31, 0x0E31 },
+    { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E }, { 0x0EB1, 0x0EB1 },
+    { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC }, { 0x0EC8, 0x0ECD },
+    { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, { 0x0F37, 0x0F37 },
+    { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, { 0x0F80, 0x0F84 },
+    { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 }, { 0x0F99, 0x0FBC },
+    { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, { 0x1032, 0x1032 },
+    { 0x1036, 0x1037 }, { 0x1039, 0x1039 }, { 0x1058, 0x1059 },
+    { 0x1160, 0x11FF }, { 0x17B7, 0x17BD }, { 0x17C6, 0x17C6 },
+    { 0x17C9, 0x17D3 }, { 0x180B, 0x180E }, { 0x18A9, 0x18A9 },
+    { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x206A, 0x206F },
+    { 0x20D0, 0x20E3 }, { 0x302A, 0x302F }, { 0x3099, 0x309A },
+    { 0xFB1E, 0xFB1E }, { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF },
+    { 0xFFF9, 0xFFFB }
+  };
+
+int wcwidth(wchar_t ucs)
+{
+  /* test for 8-bit control characters */
+  if (ucs == 0)
+    return 0;
+  if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))
+    return -1;
+
+  /* binary search in table of non-spacing characters */
+  if (bisearch(ucs, combining,
+              sizeof(combining) / sizeof(struct interval) - 1))
+    return 0;
+
+  /* if we arrive here, ucs is not a combining or C0/C1 control character */
+
+  return 1 + 
+    (ucs >= 0x1100 &&
+     (ucs <= 0x115f ||                    /* Hangul Jamo init. consonants */
+      (ucs >= 0x2e80 && ucs <= 0xa4cf && (ucs & ~0x0011) != 0x300a &&
+       ucs != 0x303f) ||                  /* CJK ... Yi */
+      (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */
+      (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */
+      (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */
+      (ucs >= 0xff00 && ucs <= 0xff5f) || /* Fullwidth Forms */
+      (ucs >= 0xffe0 && ucs <= 0xffe6) ||
+      (ucs >= 0x20000 && ucs <= 0x2ffff)));
+}
+
+
+int wcswidth(const wchar_t *pwcs, size_t n)
+{
+  int w, width = 0;
+
+  for (;*pwcs && n-- > 0; pwcs++)
+    if ((w = wcwidth(*pwcs)) < 0)
+      return -1;
+    else
+      width += w;
+
+  return width;
+}
+
+#if 0 /* RDB: we don't need the cjk version */
+/*
+ * The following function is the same as wcwidth(), except that
+ * spacing characters in the East Asian Ambiguous (A) category as
+ * defined in Unicode Technical Report #11 have a column width of 2.
+ * This experimental variant might be useful for users of CJK legacy
+ * encodings who want to migrate to UCS. It is not otherwise
+ * recommended for general use.
+ */
+static int wcwidth_cjk(wchar_t ucs)
+{
+  /* sorted list of non-overlapping intervals of East Asian Ambiguous
+   * characters */
+  static const struct interval ambiguous[] = {
+    { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 },
+    { 0x00AA, 0x00AA }, { 0x00AD, 0x00AD }, { 0x00B0, 0x00B4 },
+    { 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 },
+    { 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 },
+    { 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED },
+    { 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA },
+    { 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 },
+    { 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B },
+    { 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 },
+    { 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 },
+    { 0x0148, 0x014A }, { 0x014D, 0x014D }, { 0x0152, 0x0153 },
+    { 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE },
+    { 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 },
+    { 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA },
+    { 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 },
+    { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB }, { 0x02CD, 0x02CD },
+    { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB }, { 0x02DD, 0x02DD },
+    { 0x0391, 0x03A1 }, { 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 },
+    { 0x03C3, 0x03C9 }, { 0x0401, 0x0401 }, { 0x0410, 0x044F },
+    { 0x0451, 0x0451 }, { 0x2010, 0x2010 }, { 0x2013, 0x2016 },
+    { 0x2018, 0x2019 }, { 0x201C, 0x201D }, { 0x2020, 0x2021 },
+    { 0x2025, 0x2027 }, { 0x2030, 0x2030 }, { 0x2032, 0x2033 },
+    { 0x2035, 0x2035 }, { 0x203B, 0x203B }, { 0x2074, 0x2074 },
+    { 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC },
+    { 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 },
+    { 0x2113, 0x2113 }, { 0x2121, 0x2122 }, { 0x2126, 0x2126 },
+    { 0x212B, 0x212B }, { 0x2154, 0x2155 }, { 0x215B, 0x215B },
+    { 0x215E, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 },
+    { 0x2190, 0x2199 }, { 0x21D2, 0x21D2 }, { 0x21D4, 0x21D4 },
+    { 0x2200, 0x2200 }, { 0x2202, 0x2203 }, { 0x2207, 0x2208 },
+    { 0x220B, 0x220B }, { 0x220F, 0x220F }, { 0x2211, 0x2211 },
+    { 0x2215, 0x2215 }, { 0x221A, 0x221A }, { 0x221D, 0x2220 },
+    { 0x2223, 0x2223 }, { 0x2225, 0x2225 }, { 0x2227, 0x222C },
+    { 0x222E, 0x222E }, { 0x2234, 0x2237 }, { 0x223C, 0x223D },
+    { 0x2248, 0x2248 }, { 0x224C, 0x224C }, { 0x2252, 0x2252 },
+    { 0x2260, 0x2261 }, { 0x2264, 0x2267 }, { 0x226A, 0x226B },
+    { 0x226E, 0x226F }, { 0x2282, 0x2283 }, { 0x2286, 0x2287 },
+    { 0x2295, 0x2295 }, { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 },
+    { 0x22BF, 0x22BF }, { 0x2312, 0x2312 }, { 0x2460, 0x24BF },
+    { 0x24D0, 0x24E9 }, { 0x2500, 0x254B }, { 0x2550, 0x2574 },
+    { 0x2580, 0x258F }, { 0x2592, 0x2595 }, { 0x25A0, 0x25A1 },
+    { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 }, { 0x25B6, 0x25B7 },
+    { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 }, { 0x25C6, 0x25C8 },
+    { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 }, { 0x25E2, 0x25E5 },
+    { 0x25EF, 0x25EF }, { 0x2605, 0x2606 }, { 0x2609, 0x2609 },
+    { 0x260E, 0x260F }, { 0x261C, 0x261C }, { 0x261E, 0x261E },
+    { 0x2640, 0x2640 }, { 0x2642, 0x2642 }, { 0x2660, 0x2661 },
+    { 0x2663, 0x2665 }, { 0x2667, 0x266A }, { 0x266C, 0x266D },
+    { 0x266F, 0x266F }, { 0x300A, 0x300B }, { 0x301A, 0x301B },
+    { 0xE000, 0xF8FF }, { 0xFFFD, 0xFFFD }
+  };
+
+  /* binary search in table of non-spacing characters */
+  if (bisearch(ucs, ambiguous,
+              sizeof(ambiguous) / sizeof(struct interval) - 1))
+    return 2;
+
+  return wcwidth(ucs);
+}
+
+
+int wcswidth_cjk(const wchar_t *pwcs, size_t n)
+{
+  int w, width = 0;
+
+  for (;*pwcs && n-- > 0; pwcs++)
+    if ((w = wcwidth_cjk(*pwcs)) < 0)
+      return -1;
+    else
+      width += w;
+
+  return width;
+}
+#endif
diff --git a/arm/vt100/wcwidth.h b/arm/vt100/wcwidth.h
new file mode 100644 (file)
index 0000000..cdd022f
--- /dev/null
@@ -0,0 +1,31 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef WCWIDTH_H
+#define WCWIDTH_H
+
+int wcswidth(const wchar_t *pwcs, size_t n);
+int wcwidth(wchar_t ucs);
+
+#endif
diff --git a/crypto/cryptorsrc.h b/crypto/cryptorsrc.h
new file mode 100644 (file)
index 0000000..11dfe33
--- /dev/null
@@ -0,0 +1,50 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef CRYPTORSRC_H
+#define CRYPTORSRC_H 1
+
+// DES
+#define DES_SPtrans0_id 9000
+#define DES_SPtrans1_id 9001
+#define DES_SPtrans2_id 9002
+#define DES_SPtrans3_id 9003
+#define DES_SPtrans4_id 9004
+#define DES_SPtrans5_id 9005
+#define DES_SPtrans6_id 9006
+#define DES_SPtrans7_id 9007
+
+// AES
+#define AES_Te0_id 9010
+#define AES_Te1_id 9011
+#define AES_Te2_id 9012
+#define AES_Te3_id 9013
+#define AES_Te4_id 9014
+#define AES_Td0_id 9015
+#define AES_Td1_id 9016
+#define AES_Td2_id 9017
+#define AES_Td3_id 9018
+#define AES_Td4_id 9019
+
+#endif
diff --git a/crypto/openssl/aes/aes.h b/crypto/openssl/aes/aes.h
new file mode 100644 (file)
index 0000000..4656fde
--- /dev/null
@@ -0,0 +1,144 @@
+/* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 1998-2002 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.
+ * ====================================================================
+ *
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// added AES_SEGMENT everywhere
+// changed some variables to use stdint types
+
+#ifndef HEADER_AES_H
+#define HEADER_AES_H
+
+#include "openssl/cryptlib.h"
+
+#ifdef OPENSSL_NO_AES
+#error AES is disabled.
+#endif
+
+#define AES_ENCRYPT    1
+#define AES_DECRYPT    0
+
+/* Because array size can't be a const in C, the following two are macros.
+   Both sizes are in bytes. */
+#define AES_MAXNR 14
+#define AES_BLOCK_SIZE 16
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* This should be a hidden type, but EVP requires that the size be known */
+// pssh: contents of AES_KEY are left in ARM-endian order. Do not use.
+struct aes_key_st {
+    uint32_t rd_key[4 *(AES_MAXNR + 1)];
+    uint32_t rounds;
+};
+typedef struct aes_key_st AES_KEY;
+
+const char *AES_options(void) AES_SEGMENT;
+
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+       AES_KEY *key) AES_SEGMENT;
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+       AES_KEY *key) AES_SEGMENT;
+
+void AES_encrypt(const unsigned char *in, unsigned char *out,
+       const AES_KEY *key) AES_SEGMENT;
+void AES_decrypt(const unsigned char *in, unsigned char *out,
+       const AES_KEY *key) AES_SEGMENT;
+
+void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
+       const AES_KEY *key, const int enc) AES_SEGMENT;
+void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+       const uint32_t length, const AES_KEY *key,
+       unsigned char *ivec, const int enc) AES_SEGMENT;
+void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+       const uint32_t length, const AES_KEY *key,
+       unsigned char *ivec, int *num, const int enc) AES_SEGMENT;
+void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+       const uint32_t length, const AES_KEY *key,
+       unsigned char *ivec, int *num) AES_SEGMENT;
+void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+       const uint32_t length, const AES_KEY *key,
+       unsigned char ivec[AES_BLOCK_SIZE],
+       unsigned char ecount_buf[AES_BLOCK_SIZE],
+       uint32_t *num) AES_SEGMENT;
+
+void AES_ctr128_inc(unsigned char *counter) AES_SEGMENT;
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* !HEADER_AES_H */
diff --git a/crypto/openssl/aes/aes_armstubs.c b/crypto/openssl/aes/aes_armstubs.c
new file mode 100644 (file)
index 0000000..85b60e7
--- /dev/null
@@ -0,0 +1,101 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "aes.h"
+#include "aes_armstubs.h"
+#include "armstubs.h"
+
+
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+                        AES_KEY *key) 
+{
+    static void *addr = NULL;
+    uint32_t result;
+    uint32_t param[3];
+    param[0] = (uint32_t)userKey;
+    param[1] = (uint32_t)bits;
+    param[2] = (uint32_t)key;
+
+    if (!addr) addr = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!addr) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    result = PealCall(arm_module, addr, param);
+
+    return (int)result;
+}
+
+
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+                        AES_KEY *key) 
+{
+    static void *addr = NULL;
+    uint32_t result;
+    uint32_t param[3];
+    param[0] = (uint32_t)userKey;
+    param[1] = (uint32_t)bits;
+    param[2] = (uint32_t)key;
+
+    if (!addr) addr = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!addr) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    
+    result = PealCall(arm_module, addr, param);
+
+    return (int)result;
+}
+
+
+void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                     const uint32_t length, const AES_KEY *key,
+                     unsigned char *ivec, const int enc) 
+{
+    static void *addr = NULL;
+    uint32_t param[6];
+    param[0] = (uint32_t)in;
+    param[1] = (uint32_t)out;
+    param[2] = (uint32_t)length;
+    param[3] = (uint32_t)key;
+    param[4] = (uint32_t)ivec;
+    param[5] = (uint32_t)enc;
+
+    if (!addr) addr = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!addr) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    
+    PealCall(arm_module, addr, param);
+}
+
+void AES_encrypt(const unsigned char *in, unsigned char *out,
+                 const AES_KEY *key) 
+{
+    static void *addr = NULL;
+    uint32_t param[3];
+    param[0] = (uint32_t)in;
+    param[1] = (uint32_t)out;
+    param[2] = (uint32_t)key;
+
+    if (!addr) addr = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!addr) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    
+    PealCall(arm_module, addr, param);
+}
diff --git a/crypto/openssl/aes/aes_armstubs.h b/crypto/openssl/aes/aes_armstubs.h
new file mode 100644 (file)
index 0000000..f6c40a4
--- /dev/null
@@ -0,0 +1,31 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef AES_ARMSTUBS_H
+#define AES_ARMSTUBS_H
+
+#include <stdint.h>
+#include <PceNativeCall.h>
+
+#endif
diff --git a/crypto/openssl/aes/aes_tables.rcp b/crypto/openssl/aes/aes_tables.rcp
new file mode 100644 (file)
index 0000000..0acbab4
--- /dev/null
@@ -0,0 +1,723 @@
+/* crypto/aes/aes_core.c -*- mode:C; c-file-style: "eay" -*- */
+/**
+ * rijndael-alg-fst.c
+ *
+ * @version 3.0 (December 2000)
+ *
+ * Optimised ANSI C code for the Rijndael cipher (now AES)
+ *
+ * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ * @author Paulo Barreto <paulo.barreto@terra.com.br>
+ *
+ * This code is hereby placed in the public domain.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS 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.
+ */
+
+#include "cryptorsrc.h"
+
+/*
+Te0[x] = S [x].[02, 01, 01, 03];
+Te1[x] = S [x].[03, 02, 01, 01];
+Te2[x] = S [x].[01, 03, 02, 01];
+Te3[x] = S [x].[01, 01, 03, 02];
+Te4[x] = S [x].[01, 01, 01, 01];
+
+Td0[x] = Si[x].[0e, 09, 0d, 0b];
+Td1[x] = Si[x].[0b, 0e, 09, 0d];
+Td2[x] = Si[x].[0d, 0b, 0e, 09];
+Td3[x] = Si[x].[09, 0d, 0b, 0e];
+Td4[x] = Si[x].[01, 01, 01, 01];
+*/
+
+LONGWORDLIST ID AES_Te0_id
+BEGIN
+    0xc66363a5LU 0xf87c7c84LU 0xee777799LU 0xf67b7b8dLU
+    0xfff2f20dLU 0xd66b6bbdLU 0xde6f6fb1LU 0x91c5c554LU
+    0x60303050LU 0x02010103LU 0xce6767a9LU 0x562b2b7dLU
+    0xe7fefe19LU 0xb5d7d762LU 0x4dababe6LU 0xec76769aLU
+    0x8fcaca45LU 0x1f82829dLU 0x89c9c940LU 0xfa7d7d87LU
+    0xeffafa15LU 0xb25959ebLU 0x8e4747c9LU 0xfbf0f00bLU
+    0x41adadecLU 0xb3d4d467LU 0x5fa2a2fdLU 0x45afafeaLU
+    0x239c9cbfLU 0x53a4a4f7LU 0xe4727296LU 0x9bc0c05bLU
+    0x75b7b7c2LU 0xe1fdfd1cLU 0x3d9393aeLU 0x4c26266aLU
+    0x6c36365aLU 0x7e3f3f41LU 0xf5f7f702LU 0x83cccc4fLU
+    0x6834345cLU 0x51a5a5f4LU 0xd1e5e534LU 0xf9f1f108LU
+    0xe2717193LU 0xabd8d873LU 0x62313153LU 0x2a15153fLU
+    0x0804040cLU 0x95c7c752LU 0x46232365LU 0x9dc3c35eLU
+    0x30181828LU 0x379696a1LU 0x0a05050fLU 0x2f9a9ab5LU
+    0x0e070709LU 0x24121236LU 0x1b80809bLU 0xdfe2e23dLU
+    0xcdebeb26LU 0x4e272769LU 0x7fb2b2cdLU 0xea75759fLU
+    0x1209091bLU 0x1d83839eLU 0x582c2c74LU 0x341a1a2eLU
+    0x361b1b2dLU 0xdc6e6eb2LU 0xb45a5aeeLU 0x5ba0a0fbLU
+    0xa45252f6LU 0x763b3b4dLU 0xb7d6d661LU 0x7db3b3ceLU
+    0x5229297bLU 0xdde3e33eLU 0x5e2f2f71LU 0x13848497LU
+    0xa65353f5LU 0xb9d1d168LU 0x00000000LU 0xc1eded2cLU
+    0x40202060LU 0xe3fcfc1fLU 0x79b1b1c8LU 0xb65b5bedLU
+    0xd46a6abeLU 0x8dcbcb46LU 0x67bebed9LU 0x7239394bLU
+    0x944a4adeLU 0x984c4cd4LU 0xb05858e8LU 0x85cfcf4aLU
+    0xbbd0d06bLU 0xc5efef2aLU 0x4faaaae5LU 0xedfbfb16LU
+    0x864343c5LU 0x9a4d4dd7LU 0x66333355LU 0x11858594LU
+    0x8a4545cfLU 0xe9f9f910LU 0x04020206LU 0xfe7f7f81LU
+    0xa05050f0LU 0x783c3c44LU 0x259f9fbaLU 0x4ba8a8e3LU
+    0xa25151f3LU 0x5da3a3feLU 0x804040c0LU 0x058f8f8aLU
+    0x3f9292adLU 0x219d9dbcLU 0x70383848LU 0xf1f5f504LU
+    0x63bcbcdfLU 0x77b6b6c1LU 0xafdada75LU 0x42212163LU
+    0x20101030LU 0xe5ffff1aLU 0xfdf3f30eLU 0xbfd2d26dLU
+    0x81cdcd4cLU 0x180c0c14LU 0x26131335LU 0xc3ecec2fLU
+    0xbe5f5fe1LU 0x359797a2LU 0x884444ccLU 0x2e171739LU
+    0x93c4c457LU 0x55a7a7f2LU 0xfc7e7e82LU 0x7a3d3d47LU
+    0xc86464acLU 0xba5d5de7LU 0x3219192bLU 0xe6737395LU
+    0xc06060a0LU 0x19818198LU 0x9e4f4fd1LU 0xa3dcdc7fLU
+    0x44222266LU 0x542a2a7eLU 0x3b9090abLU 0x0b888883LU
+    0x8c4646caLU 0xc7eeee29LU 0x6bb8b8d3LU 0x2814143cLU
+    0xa7dede79LU 0xbc5e5ee2LU 0x160b0b1dLU 0xaddbdb76LU
+    0xdbe0e03bLU 0x64323256LU 0x743a3a4eLU 0x140a0a1eLU
+    0x924949dbLU 0x0c06060aLU 0x4824246cLU 0xb85c5ce4LU
+    0x9fc2c25dLU 0xbdd3d36eLU 0x43acacefLU 0xc46262a6LU
+    0x399191a8LU 0x319595a4LU 0xd3e4e437LU 0xf279798bLU
+    0xd5e7e732LU 0x8bc8c843LU 0x6e373759LU 0xda6d6db7LU
+    0x018d8d8cLU 0xb1d5d564LU 0x9c4e4ed2LU 0x49a9a9e0LU
+    0xd86c6cb4LU 0xac5656faLU 0xf3f4f407LU 0xcfeaea25LU
+    0xca6565afLU 0xf47a7a8eLU 0x47aeaee9LU 0x10080818LU
+    0x6fbabad5LU 0xf0787888LU 0x4a25256fLU 0x5c2e2e72LU
+    0x381c1c24LU 0x57a6a6f1LU 0x73b4b4c7LU 0x97c6c651LU
+    0xcbe8e823LU 0xa1dddd7cLU 0xe874749cLU 0x3e1f1f21LU
+    0x964b4bddLU 0x61bdbddcLU 0x0d8b8b86LU 0x0f8a8a85LU
+    0xe0707090LU 0x7c3e3e42LU 0x71b5b5c4LU 0xcc6666aaLU
+    0x904848d8LU 0x06030305LU 0xf7f6f601LU 0x1c0e0e12LU
+    0xc26161a3LU 0x6a35355fLU 0xae5757f9LU 0x69b9b9d0LU
+    0x17868691LU 0x99c1c158LU 0x3a1d1d27LU 0x279e9eb9LU
+    0xd9e1e138LU 0xebf8f813LU 0x2b9898b3LU 0x22111133LU
+    0xd26969bbLU 0xa9d9d970LU 0x078e8e89LU 0x339494a7LU
+    0x2d9b9bb6LU 0x3c1e1e22LU 0x15878792LU 0xc9e9e920LU
+    0x87cece49LU 0xaa5555ffLU 0x50282878LU 0xa5dfdf7aLU
+    0x038c8c8fLU 0x59a1a1f8LU 0x09898980LU 0x1a0d0d17LU
+    0x65bfbfdaLU 0xd7e6e631LU 0x844242c6LU 0xd06868b8LU
+    0x824141c3LU 0x299999b0LU 0x5a2d2d77LU 0x1e0f0f11LU
+    0x7bb0b0cbLU 0xa85454fcLU 0x6dbbbbd6LU 0x2c16163aLU
+END
+
+LONGWORDLIST ID AES_Te1_id
+BEGIN
+    0xa5c66363LU 0x84f87c7cLU 0x99ee7777LU 0x8df67b7bLU
+    0x0dfff2f2LU 0xbdd66b6bLU 0xb1de6f6fLU 0x5491c5c5LU
+    0x50603030LU 0x03020101LU 0xa9ce6767LU 0x7d562b2bLU
+    0x19e7fefeLU 0x62b5d7d7LU 0xe64dababLU 0x9aec7676LU
+    0x458fcacaLU 0x9d1f8282LU 0x4089c9c9LU 0x87fa7d7dLU
+    0x15effafaLU 0xebb25959LU 0xc98e4747LU 0x0bfbf0f0LU
+    0xec41adadLU 0x67b3d4d4LU 0xfd5fa2a2LU 0xea45afafLU
+    0xbf239c9cLU 0xf753a4a4LU 0x96e47272LU 0x5b9bc0c0LU
+    0xc275b7b7LU 0x1ce1fdfdLU 0xae3d9393LU 0x6a4c2626LU
+    0x5a6c3636LU 0x417e3f3fLU 0x02f5f7f7LU 0x4f83ccccLU
+    0x5c683434LU 0xf451a5a5LU 0x34d1e5e5LU 0x08f9f1f1LU
+    0x93e27171LU 0x73abd8d8LU 0x53623131LU 0x3f2a1515LU
+    0x0c080404LU 0x5295c7c7LU 0x65462323LU 0x5e9dc3c3LU
+    0x28301818LU 0xa1379696LU 0x0f0a0505LU 0xb52f9a9aLU
+    0x090e0707LU 0x36241212LU 0x9b1b8080LU 0x3ddfe2e2LU
+    0x26cdebebLU 0x694e2727LU 0xcd7fb2b2LU 0x9fea7575LU
+    0x1b120909LU 0x9e1d8383LU 0x74582c2cLU 0x2e341a1aLU
+    0x2d361b1bLU 0xb2dc6e6eLU 0xeeb45a5aLU 0xfb5ba0a0LU
+    0xf6a45252LU 0x4d763b3bLU 0x61b7d6d6LU 0xce7db3b3LU
+    0x7b522929LU 0x3edde3e3LU 0x715e2f2fLU 0x97138484LU
+    0xf5a65353LU 0x68b9d1d1LU 0x00000000LU 0x2cc1ededLU
+    0x60402020LU 0x1fe3fcfcLU 0xc879b1b1LU 0xedb65b5bLU
+    0xbed46a6aLU 0x468dcbcbLU 0xd967bebeLU 0x4b723939LU
+    0xde944a4aLU 0xd4984c4cLU 0xe8b05858LU 0x4a85cfcfLU
+    0x6bbbd0d0LU 0x2ac5efefLU 0xe54faaaaLU 0x16edfbfbLU
+    0xc5864343LU 0xd79a4d4dLU 0x55663333LU 0x94118585LU
+    0xcf8a4545LU 0x10e9f9f9LU 0x06040202LU 0x81fe7f7fLU
+    0xf0a05050LU 0x44783c3cLU 0xba259f9fLU 0xe34ba8a8LU
+    0xf3a25151LU 0xfe5da3a3LU 0xc0804040LU 0x8a058f8fLU
+    0xad3f9292LU 0xbc219d9dLU 0x48703838LU 0x04f1f5f5LU
+    0xdf63bcbcLU 0xc177b6b6LU 0x75afdadaLU 0x63422121LU
+    0x30201010LU 0x1ae5ffffLU 0x0efdf3f3LU 0x6dbfd2d2LU
+    0x4c81cdcdLU 0x14180c0cLU 0x35261313LU 0x2fc3ececLU
+    0xe1be5f5fLU 0xa2359797LU 0xcc884444LU 0x392e1717LU
+    0x5793c4c4LU 0xf255a7a7LU 0x82fc7e7eLU 0x477a3d3dLU
+    0xacc86464LU 0xe7ba5d5dLU 0x2b321919LU 0x95e67373LU
+    0xa0c06060LU 0x98198181LU 0xd19e4f4fLU 0x7fa3dcdcLU
+    0x66442222LU 0x7e542a2aLU 0xab3b9090LU 0x830b8888LU
+    0xca8c4646LU 0x29c7eeeeLU 0xd36bb8b8LU 0x3c281414LU
+    0x79a7dedeLU 0xe2bc5e5eLU 0x1d160b0bLU 0x76addbdbLU
+    0x3bdbe0e0LU 0x56643232LU 0x4e743a3aLU 0x1e140a0aLU
+    0xdb924949LU 0x0a0c0606LU 0x6c482424LU 0xe4b85c5cLU
+    0x5d9fc2c2LU 0x6ebdd3d3LU 0xef43acacLU 0xa6c46262LU
+    0xa8399191LU 0xa4319595LU 0x37d3e4e4LU 0x8bf27979LU
+    0x32d5e7e7LU 0x438bc8c8LU 0x596e3737LU 0xb7da6d6dLU
+    0x8c018d8dLU 0x64b1d5d5LU 0xd29c4e4eLU 0xe049a9a9LU
+    0xb4d86c6cLU 0xfaac5656LU 0x07f3f4f4LU 0x25cfeaeaLU
+    0xafca6565LU 0x8ef47a7aLU 0xe947aeaeLU 0x18100808LU
+    0xd56fbabaLU 0x88f07878LU 0x6f4a2525LU 0x725c2e2eLU
+    0x24381c1cLU 0xf157a6a6LU 0xc773b4b4LU 0x5197c6c6LU
+    0x23cbe8e8LU 0x7ca1ddddLU 0x9ce87474LU 0x213e1f1fLU
+    0xdd964b4bLU 0xdc61bdbdLU 0x860d8b8bLU 0x850f8a8aLU
+    0x90e07070LU 0x427c3e3eLU 0xc471b5b5LU 0xaacc6666LU
+    0xd8904848LU 0x05060303LU 0x01f7f6f6LU 0x121c0e0eLU
+    0xa3c26161LU 0x5f6a3535LU 0xf9ae5757LU 0xd069b9b9LU
+    0x91178686LU 0x5899c1c1LU 0x273a1d1dLU 0xb9279e9eLU
+    0x38d9e1e1LU 0x13ebf8f8LU 0xb32b9898LU 0x33221111LU
+    0xbbd26969LU 0x70a9d9d9LU 0x89078e8eLU 0xa7339494LU
+    0xb62d9b9bLU 0x223c1e1eLU 0x92158787LU 0x20c9e9e9LU
+    0x4987ceceLU 0xffaa5555LU 0x78502828LU 0x7aa5dfdfLU
+    0x8f038c8cLU 0xf859a1a1LU 0x80098989LU 0x171a0d0dLU
+    0xda65bfbfLU 0x31d7e6e6LU 0xc6844242LU 0xb8d06868LU
+    0xc3824141LU 0xb0299999LU 0x775a2d2dLU 0x111e0f0fLU
+    0xcb7bb0b0LU 0xfca85454LU 0xd66dbbbbLU 0x3a2c1616LU
+END
+
+LONGWORDLIST ID AES_Te2_id
+BEGIN
+    0x63a5c663LU 0x7c84f87cLU 0x7799ee77LU 0x7b8df67bLU
+    0xf20dfff2LU 0x6bbdd66bLU 0x6fb1de6fLU 0xc55491c5LU
+    0x30506030LU 0x01030201LU 0x67a9ce67LU 0x2b7d562bLU
+    0xfe19e7feLU 0xd762b5d7LU 0xabe64dabLU 0x769aec76LU
+    0xca458fcaLU 0x829d1f82LU 0xc94089c9LU 0x7d87fa7dLU
+    0xfa15effaLU 0x59ebb259LU 0x47c98e47LU 0xf00bfbf0LU
+    0xadec41adLU 0xd467b3d4LU 0xa2fd5fa2LU 0xafea45afLU
+    0x9cbf239cLU 0xa4f753a4LU 0x7296e472LU 0xc05b9bc0LU
+    0xb7c275b7LU 0xfd1ce1fdLU 0x93ae3d93LU 0x266a4c26LU
+    0x365a6c36LU 0x3f417e3fLU 0xf702f5f7LU 0xcc4f83ccLU
+    0x345c6834LU 0xa5f451a5LU 0xe534d1e5LU 0xf108f9f1LU
+    0x7193e271LU 0xd873abd8LU 0x31536231LU 0x153f2a15LU
+    0x040c0804LU 0xc75295c7LU 0x23654623LU 0xc35e9dc3LU
+    0x18283018LU 0x96a13796LU 0x050f0a05LU 0x9ab52f9aLU
+    0x07090e07LU 0x12362412LU 0x809b1b80LU 0xe23ddfe2LU
+    0xeb26cdebLU 0x27694e27LU 0xb2cd7fb2LU 0x759fea75LU
+    0x091b1209LU 0x839e1d83LU 0x2c74582cLU 0x1a2e341aLU
+    0x1b2d361bLU 0x6eb2dc6eLU 0x5aeeb45aLU 0xa0fb5ba0LU
+    0x52f6a452LU 0x3b4d763bLU 0xd661b7d6LU 0xb3ce7db3LU
+    0x297b5229LU 0xe33edde3LU 0x2f715e2fLU 0x84971384LU
+    0x53f5a653LU 0xd168b9d1LU 0x00000000LU 0xed2cc1edLU
+    0x20604020LU 0xfc1fe3fcLU 0xb1c879b1LU 0x5bedb65bLU
+    0x6abed46aLU 0xcb468dcbLU 0xbed967beLU 0x394b7239LU
+    0x4ade944aLU 0x4cd4984cLU 0x58e8b058LU 0xcf4a85cfLU
+    0xd06bbbd0LU 0xef2ac5efLU 0xaae54faaLU 0xfb16edfbLU
+    0x43c58643LU 0x4dd79a4dLU 0x33556633LU 0x85941185LU
+    0x45cf8a45LU 0xf910e9f9LU 0x02060402LU 0x7f81fe7fLU
+    0x50f0a050LU 0x3c44783cLU 0x9fba259fLU 0xa8e34ba8LU
+    0x51f3a251LU 0xa3fe5da3LU 0x40c08040LU 0x8f8a058fLU
+    0x92ad3f92LU 0x9dbc219dLU 0x38487038LU 0xf504f1f5LU
+    0xbcdf63bcLU 0xb6c177b6LU 0xda75afdaLU 0x21634221LU
+    0x10302010LU 0xff1ae5ffLU 0xf30efdf3LU 0xd26dbfd2LU
+    0xcd4c81cdLU 0x0c14180cLU 0x13352613LU 0xec2fc3ecLU
+    0x5fe1be5fLU 0x97a23597LU 0x44cc8844LU 0x17392e17LU
+    0xc45793c4LU 0xa7f255a7LU 0x7e82fc7eLU 0x3d477a3dLU
+    0x64acc864LU 0x5de7ba5dLU 0x192b3219LU 0x7395e673LU
+    0x60a0c060LU 0x81981981LU 0x4fd19e4fLU 0xdc7fa3dcLU
+    0x22664422LU 0x2a7e542aLU 0x90ab3b90LU 0x88830b88LU
+    0x46ca8c46LU 0xee29c7eeLU 0xb8d36bb8LU 0x143c2814LU
+    0xde79a7deLU 0x5ee2bc5eLU 0x0b1d160bLU 0xdb76addbLU
+    0xe03bdbe0LU 0x32566432LU 0x3a4e743aLU 0x0a1e140aLU
+    0x49db9249LU 0x060a0c06LU 0x246c4824LU 0x5ce4b85cLU
+    0xc25d9fc2LU 0xd36ebdd3LU 0xacef43acLU 0x62a6c462LU
+    0x91a83991LU 0x95a43195LU 0xe437d3e4LU 0x798bf279LU
+    0xe732d5e7LU 0xc8438bc8LU 0x37596e37LU 0x6db7da6dLU
+    0x8d8c018dLU 0xd564b1d5LU 0x4ed29c4eLU 0xa9e049a9LU
+    0x6cb4d86cLU 0x56faac56LU 0xf407f3f4LU 0xea25cfeaLU
+    0x65afca65LU 0x7a8ef47aLU 0xaee947aeLU 0x08181008LU
+    0xbad56fbaLU 0x7888f078LU 0x256f4a25LU 0x2e725c2eLU
+    0x1c24381cLU 0xa6f157a6LU 0xb4c773b4LU 0xc65197c6LU
+    0xe823cbe8LU 0xdd7ca1ddLU 0x749ce874LU 0x1f213e1fLU
+    0x4bdd964bLU 0xbddc61bdLU 0x8b860d8bLU 0x8a850f8aLU
+    0x7090e070LU 0x3e427c3eLU 0xb5c471b5LU 0x66aacc66LU
+    0x48d89048LU 0x03050603LU 0xf601f7f6LU 0x0e121c0eLU
+    0x61a3c261LU 0x355f6a35LU 0x57f9ae57LU 0xb9d069b9LU
+    0x86911786LU 0xc15899c1LU 0x1d273a1dLU 0x9eb9279eLU
+    0xe138d9e1LU 0xf813ebf8LU 0x98b32b98LU 0x11332211LU
+    0x69bbd269LU 0xd970a9d9LU 0x8e89078eLU 0x94a73394LU
+    0x9bb62d9bLU 0x1e223c1eLU 0x87921587LU 0xe920c9e9LU
+    0xce4987ceLU 0x55ffaa55LU 0x28785028LU 0xdf7aa5dfLU
+    0x8c8f038cLU 0xa1f859a1LU 0x89800989LU 0x0d171a0dLU
+    0xbfda65bfLU 0xe631d7e6LU 0x42c68442LU 0x68b8d068LU
+    0x41c38241LU 0x99b02999LU 0x2d775a2dLU 0x0f111e0fLU
+    0xb0cb7bb0LU 0x54fca854LU 0xbbd66dbbLU 0x163a2c16LU
+END
+
+LONGWORDLIST ID AES_Te3_id
+BEGIN
+    0x6363a5c6LU 0x7c7c84f8LU 0x777799eeLU 0x7b7b8df6LU
+    0xf2f20dffLU 0x6b6bbdd6LU 0x6f6fb1deLU 0xc5c55491LU
+    0x30305060LU 0x01010302LU 0x6767a9ceLU 0x2b2b7d56LU
+    0xfefe19e7LU 0xd7d762b5LU 0xababe64dLU 0x76769aecLU
+    0xcaca458fLU 0x82829d1fLU 0xc9c94089LU 0x7d7d87faLU
+    0xfafa15efLU 0x5959ebb2LU 0x4747c98eLU 0xf0f00bfbLU
+    0xadadec41LU 0xd4d467b3LU 0xa2a2fd5fLU 0xafafea45LU
+    0x9c9cbf23LU 0xa4a4f753LU 0x727296e4LU 0xc0c05b9bLU
+    0xb7b7c275LU 0xfdfd1ce1LU 0x9393ae3dLU 0x26266a4cLU
+    0x36365a6cLU 0x3f3f417eLU 0xf7f702f5LU 0xcccc4f83LU
+    0x34345c68LU 0xa5a5f451LU 0xe5e534d1LU 0xf1f108f9LU
+    0x717193e2LU 0xd8d873abLU 0x31315362LU 0x15153f2aLU
+    0x04040c08LU 0xc7c75295LU 0x23236546LU 0xc3c35e9dLU
+    0x18182830LU 0x9696a137LU 0x05050f0aLU 0x9a9ab52fLU
+    0x0707090eLU 0x12123624LU 0x80809b1bLU 0xe2e23ddfLU
+    0xebeb26cdLU 0x2727694eLU 0xb2b2cd7fLU 0x75759feaLU
+    0x09091b12LU 0x83839e1dLU 0x2c2c7458LU 0x1a1a2e34LU
+    0x1b1b2d36LU 0x6e6eb2dcLU 0x5a5aeeb4LU 0xa0a0fb5bLU
+    0x5252f6a4LU 0x3b3b4d76LU 0xd6d661b7LU 0xb3b3ce7dLU
+    0x29297b52LU 0xe3e33eddLU 0x2f2f715eLU 0x84849713LU
+    0x5353f5a6LU 0xd1d168b9LU 0x00000000LU 0xeded2cc1LU
+    0x20206040LU 0xfcfc1fe3LU 0xb1b1c879LU 0x5b5bedb6LU
+    0x6a6abed4LU 0xcbcb468dLU 0xbebed967LU 0x39394b72LU
+    0x4a4ade94LU 0x4c4cd498LU 0x5858e8b0LU 0xcfcf4a85LU
+    0xd0d06bbbLU 0xefef2ac5LU 0xaaaae54fLU 0xfbfb16edLU
+    0x4343c586LU 0x4d4dd79aLU 0x33335566LU 0x85859411LU
+    0x4545cf8aLU 0xf9f910e9LU 0x02020604LU 0x7f7f81feLU
+    0x5050f0a0LU 0x3c3c4478LU 0x9f9fba25LU 0xa8a8e34bLU
+    0x5151f3a2LU 0xa3a3fe5dLU 0x4040c080LU 0x8f8f8a05LU
+    0x9292ad3fLU 0x9d9dbc21LU 0x38384870LU 0xf5f504f1LU
+    0xbcbcdf63LU 0xb6b6c177LU 0xdada75afLU 0x21216342LU
+    0x10103020LU 0xffff1ae5LU 0xf3f30efdLU 0xd2d26dbfLU
+    0xcdcd4c81LU 0x0c0c1418LU 0x13133526LU 0xecec2fc3LU
+    0x5f5fe1beLU 0x9797a235LU 0x4444cc88LU 0x1717392eLU
+    0xc4c45793LU 0xa7a7f255LU 0x7e7e82fcLU 0x3d3d477aLU
+    0x6464acc8LU 0x5d5de7baLU 0x19192b32LU 0x737395e6LU
+    0x6060a0c0LU 0x81819819LU 0x4f4fd19eLU 0xdcdc7fa3LU
+    0x22226644LU 0x2a2a7e54LU 0x9090ab3bLU 0x8888830bLU
+    0x4646ca8cLU 0xeeee29c7LU 0xb8b8d36bLU 0x14143c28LU
+    0xdede79a7LU 0x5e5ee2bcLU 0x0b0b1d16LU 0xdbdb76adLU
+    0xe0e03bdbLU 0x32325664LU 0x3a3a4e74LU 0x0a0a1e14LU
+    0x4949db92LU 0x06060a0cLU 0x24246c48LU 0x5c5ce4b8LU
+    0xc2c25d9fLU 0xd3d36ebdLU 0xacacef43LU 0x6262a6c4LU
+    0x9191a839LU 0x9595a431LU 0xe4e437d3LU 0x79798bf2LU
+    0xe7e732d5LU 0xc8c8438bLU 0x3737596eLU 0x6d6db7daLU
+    0x8d8d8c01LU 0xd5d564b1LU 0x4e4ed29cLU 0xa9a9e049LU
+    0x6c6cb4d8LU 0x5656faacLU 0xf4f407f3LU 0xeaea25cfLU
+    0x6565afcaLU 0x7a7a8ef4LU 0xaeaee947LU 0x08081810LU
+    0xbabad56fLU 0x787888f0LU 0x25256f4aLU 0x2e2e725cLU
+    0x1c1c2438LU 0xa6a6f157LU 0xb4b4c773LU 0xc6c65197LU
+    0xe8e823cbLU 0xdddd7ca1LU 0x74749ce8LU 0x1f1f213eLU
+    0x4b4bdd96LU 0xbdbddc61LU 0x8b8b860dLU 0x8a8a850fLU
+    0x707090e0LU 0x3e3e427cLU 0xb5b5c471LU 0x6666aaccLU
+    0x4848d890LU 0x03030506LU 0xf6f601f7LU 0x0e0e121cLU
+    0x6161a3c2LU 0x35355f6aLU 0x5757f9aeLU 0xb9b9d069LU
+    0x86869117LU 0xc1c15899LU 0x1d1d273aLU 0x9e9eb927LU
+    0xe1e138d9LU 0xf8f813ebLU 0x9898b32bLU 0x11113322LU
+    0x6969bbd2LU 0xd9d970a9LU 0x8e8e8907LU 0x9494a733LU
+    0x9b9bb62dLU 0x1e1e223cLU 0x87879215LU 0xe9e920c9LU
+    0xcece4987LU 0x5555ffaaLU 0x28287850LU 0xdfdf7aa5LU
+    0x8c8c8f03LU 0xa1a1f859LU 0x89898009LU 0x0d0d171aLU
+    0xbfbfda65LU 0xe6e631d7LU 0x4242c684LU 0x6868b8d0LU
+    0x4141c382LU 0x9999b029LU 0x2d2d775aLU 0x0f0f111eLU
+    0xb0b0cb7bLU 0x5454fca8LU 0xbbbbd66dLU 0x16163a2cLU
+END
+
+LONGWORDLIST ID AES_Te4_id
+BEGIN
+    0x63636363LU 0x7c7c7c7cLU 0x77777777LU 0x7b7b7b7bLU
+    0xf2f2f2f2LU 0x6b6b6b6bLU 0x6f6f6f6fLU 0xc5c5c5c5LU
+    0x30303030LU 0x01010101LU 0x67676767LU 0x2b2b2b2bLU
+    0xfefefefeLU 0xd7d7d7d7LU 0xababababLU 0x76767676LU
+    0xcacacacaLU 0x82828282LU 0xc9c9c9c9LU 0x7d7d7d7dLU
+    0xfafafafaLU 0x59595959LU 0x47474747LU 0xf0f0f0f0LU
+    0xadadadadLU 0xd4d4d4d4LU 0xa2a2a2a2LU 0xafafafafLU
+    0x9c9c9c9cLU 0xa4a4a4a4LU 0x72727272LU 0xc0c0c0c0LU
+    0xb7b7b7b7LU 0xfdfdfdfdLU 0x93939393LU 0x26262626LU
+    0x36363636LU 0x3f3f3f3fLU 0xf7f7f7f7LU 0xccccccccLU
+    0x34343434LU 0xa5a5a5a5LU 0xe5e5e5e5LU 0xf1f1f1f1LU
+    0x71717171LU 0xd8d8d8d8LU 0x31313131LU 0x15151515LU
+    0x04040404LU 0xc7c7c7c7LU 0x23232323LU 0xc3c3c3c3LU
+    0x18181818LU 0x96969696LU 0x05050505LU 0x9a9a9a9aLU
+    0x07070707LU 0x12121212LU 0x80808080LU 0xe2e2e2e2LU
+    0xebebebebLU 0x27272727LU 0xb2b2b2b2LU 0x75757575LU
+    0x09090909LU 0x83838383LU 0x2c2c2c2cLU 0x1a1a1a1aLU
+    0x1b1b1b1bLU 0x6e6e6e6eLU 0x5a5a5a5aLU 0xa0a0a0a0LU
+    0x52525252LU 0x3b3b3b3bLU 0xd6d6d6d6LU 0xb3b3b3b3LU
+    0x29292929LU 0xe3e3e3e3LU 0x2f2f2f2fLU 0x84848484LU
+    0x53535353LU 0xd1d1d1d1LU 0x00000000LU 0xededededLU
+    0x20202020LU 0xfcfcfcfcLU 0xb1b1b1b1LU 0x5b5b5b5bLU
+    0x6a6a6a6aLU 0xcbcbcbcbLU 0xbebebebeLU 0x39393939LU
+    0x4a4a4a4aLU 0x4c4c4c4cLU 0x58585858LU 0xcfcfcfcfLU
+    0xd0d0d0d0LU 0xefefefefLU 0xaaaaaaaaLU 0xfbfbfbfbLU
+    0x43434343LU 0x4d4d4d4dLU 0x33333333LU 0x85858585LU
+    0x45454545LU 0xf9f9f9f9LU 0x02020202LU 0x7f7f7f7fLU
+    0x50505050LU 0x3c3c3c3cLU 0x9f9f9f9fLU 0xa8a8a8a8LU
+    0x51515151LU 0xa3a3a3a3LU 0x40404040LU 0x8f8f8f8fLU
+    0x92929292LU 0x9d9d9d9dLU 0x38383838LU 0xf5f5f5f5LU
+    0xbcbcbcbcLU 0xb6b6b6b6LU 0xdadadadaLU 0x21212121LU
+    0x10101010LU 0xffffffffLU 0xf3f3f3f3LU 0xd2d2d2d2LU
+    0xcdcdcdcdLU 0x0c0c0c0cLU 0x13131313LU 0xececececLU
+    0x5f5f5f5fLU 0x97979797LU 0x44444444LU 0x17171717LU
+    0xc4c4c4c4LU 0xa7a7a7a7LU 0x7e7e7e7eLU 0x3d3d3d3dLU
+    0x64646464LU 0x5d5d5d5dLU 0x19191919LU 0x73737373LU
+    0x60606060LU 0x81818181LU 0x4f4f4f4fLU 0xdcdcdcdcLU
+    0x22222222LU 0x2a2a2a2aLU 0x90909090LU 0x88888888LU
+    0x46464646LU 0xeeeeeeeeLU 0xb8b8b8b8LU 0x14141414LU
+    0xdedededeLU 0x5e5e5e5eLU 0x0b0b0b0bLU 0xdbdbdbdbLU
+    0xe0e0e0e0LU 0x32323232LU 0x3a3a3a3aLU 0x0a0a0a0aLU
+    0x49494949LU 0x06060606LU 0x24242424LU 0x5c5c5c5cLU
+    0xc2c2c2c2LU 0xd3d3d3d3LU 0xacacacacLU 0x62626262LU
+    0x91919191LU 0x95959595LU 0xe4e4e4e4LU 0x79797979LU
+    0xe7e7e7e7LU 0xc8c8c8c8LU 0x37373737LU 0x6d6d6d6dLU
+    0x8d8d8d8dLU 0xd5d5d5d5LU 0x4e4e4e4eLU 0xa9a9a9a9LU
+    0x6c6c6c6cLU 0x56565656LU 0xf4f4f4f4LU 0xeaeaeaeaLU
+    0x65656565LU 0x7a7a7a7aLU 0xaeaeaeaeLU 0x08080808LU
+    0xbabababaLU 0x78787878LU 0x25252525LU 0x2e2e2e2eLU
+    0x1c1c1c1cLU 0xa6a6a6a6LU 0xb4b4b4b4LU 0xc6c6c6c6LU
+    0xe8e8e8e8LU 0xddddddddLU 0x74747474LU 0x1f1f1f1fLU
+    0x4b4b4b4bLU 0xbdbdbdbdLU 0x8b8b8b8bLU 0x8a8a8a8aLU
+    0x70707070LU 0x3e3e3e3eLU 0xb5b5b5b5LU 0x66666666LU
+    0x48484848LU 0x03030303LU 0xf6f6f6f6LU 0x0e0e0e0eLU
+    0x61616161LU 0x35353535LU 0x57575757LU 0xb9b9b9b9LU
+    0x86868686LU 0xc1c1c1c1LU 0x1d1d1d1dLU 0x9e9e9e9eLU
+    0xe1e1e1e1LU 0xf8f8f8f8LU 0x98989898LU 0x11111111LU
+    0x69696969LU 0xd9d9d9d9LU 0x8e8e8e8eLU 0x94949494LU
+    0x9b9b9b9bLU 0x1e1e1e1eLU 0x87878787LU 0xe9e9e9e9LU
+    0xcecececeLU 0x55555555LU 0x28282828LU 0xdfdfdfdfLU
+    0x8c8c8c8cLU 0xa1a1a1a1LU 0x89898989LU 0x0d0d0d0dLU
+    0xbfbfbfbfLU 0xe6e6e6e6LU 0x42424242LU 0x68686868LU
+    0x41414141LU 0x99999999LU 0x2d2d2d2dLU 0x0f0f0f0fLU
+    0xb0b0b0b0LU 0x54545454LU 0xbbbbbbbbLU 0x16161616LU
+END
+
+LONGWORDLIST ID AES_Td0_id
+BEGIN
+    0x51f4a750LU 0x7e416553LU 0x1a17a4c3LU 0x3a275e96LU
+    0x3bab6bcbLU 0x1f9d45f1LU 0xacfa58abLU 0x4be30393LU
+    0x2030fa55LU 0xad766df6LU 0x88cc7691LU 0xf5024c25LU
+    0x4fe5d7fcLU 0xc52acbd7LU 0x26354480LU 0xb562a38fLU
+    0xdeb15a49LU 0x25ba1b67LU 0x45ea0e98LU 0x5dfec0e1LU
+    0xc32f7502LU 0x814cf012LU 0x8d4697a3LU 0x6bd3f9c6LU
+    0x038f5fe7LU 0x15929c95LU 0xbf6d7aebLU 0x955259daLU
+    0xd4be832dLU 0x587421d3LU 0x49e06929LU 0x8ec9c844LU
+    0x75c2896aLU 0xf48e7978LU 0x99583e6bLU 0x27b971ddLU
+    0xbee14fb6LU 0xf088ad17LU 0xc920ac66LU 0x7dce3ab4LU
+    0x63df4a18LU 0xe51a3182LU 0x97513360LU 0x62537f45LU
+    0xb16477e0LU 0xbb6bae84LU 0xfe81a01cLU 0xf9082b94LU
+    0x70486858LU 0x8f45fd19LU 0x94de6c87LU 0x527bf8b7LU
+    0xab73d323LU 0x724b02e2LU 0xe31f8f57LU 0x6655ab2aLU
+    0xb2eb2807LU 0x2fb5c203LU 0x86c57b9aLU 0xd33708a5LU
+    0x302887f2LU 0x23bfa5b2LU 0x02036abaLU 0xed16825cLU
+    0x8acf1c2bLU 0xa779b492LU 0xf307f2f0LU 0x4e69e2a1LU
+    0x65daf4cdLU 0x0605bed5LU 0xd134621fLU 0xc4a6fe8aLU
+    0x342e539dLU 0xa2f355a0LU 0x058ae132LU 0xa4f6eb75LU
+    0x0b83ec39LU 0x4060efaaLU 0x5e719f06LU 0xbd6e1051LU
+    0x3e218af9LU 0x96dd063dLU 0xdd3e05aeLU 0x4de6bd46LU
+    0x91548db5LU 0x71c45d05LU 0x0406d46fLU 0x605015ffLU
+    0x1998fb24LU 0xd6bde997LU 0x894043ccLU 0x67d99e77LU
+    0xb0e842bdLU 0x07898b88LU 0xe7195b38LU 0x79c8eedbLU
+    0xa17c0a47LU 0x7c420fe9LU 0xf8841ec9LU 0x00000000LU
+    0x09808683LU 0x322bed48LU 0x1e1170acLU 0x6c5a724eLU
+    0xfd0efffbLU 0x0f853856LU 0x3daed51eLU 0x362d3927LU
+    0x0a0fd964LU 0x685ca621LU 0x9b5b54d1LU 0x24362e3aLU
+    0x0c0a67b1LU 0x9357e70fLU 0xb4ee96d2LU 0x1b9b919eLU
+    0x80c0c54fLU 0x61dc20a2LU 0x5a774b69LU 0x1c121a16LU
+    0xe293ba0aLU 0xc0a02ae5LU 0x3c22e043LU 0x121b171dLU
+    0x0e090d0bLU 0xf28bc7adLU 0x2db6a8b9LU 0x141ea9c8LU
+    0x57f11985LU 0xaf75074cLU 0xee99ddbbLU 0xa37f60fdLU
+    0xf701269fLU 0x5c72f5bcLU 0x44663bc5LU 0x5bfb7e34LU
+    0x8b432976LU 0xcb23c6dcLU 0xb6edfc68LU 0xb8e4f163LU
+    0xd731dccaLU 0x42638510LU 0x13972240LU 0x84c61120LU
+    0x854a247dLU 0xd2bb3df8LU 0xaef93211LU 0xc729a16dLU
+    0x1d9e2f4bLU 0xdcb230f3LU 0x0d8652ecLU 0x77c1e3d0LU
+    0x2bb3166cLU 0xa970b999LU 0x119448faLU 0x47e96422LU
+    0xa8fc8cc4LU 0xa0f03f1aLU 0x567d2cd8LU 0x223390efLU
+    0x87494ec7LU 0xd938d1c1LU 0x8ccaa2feLU 0x98d40b36LU
+    0xa6f581cfLU 0xa57ade28LU 0xdab78e26LU 0x3fadbfa4LU
+    0x2c3a9de4LU 0x5078920dLU 0x6a5fcc9bLU 0x547e4662LU
+    0xf68d13c2LU 0x90d8b8e8LU 0x2e39f75eLU 0x82c3aff5LU
+    0x9f5d80beLU 0x69d0937cLU 0x6fd52da9LU 0xcf2512b3LU
+    0xc8ac993bLU 0x10187da7LU 0xe89c636eLU 0xdb3bbb7bLU
+    0xcd267809LU 0x6e5918f4LU 0xec9ab701LU 0x834f9aa8LU
+    0xe6956e65LU 0xaaffe67eLU 0x21bccf08LU 0xef15e8e6LU
+    0xbae79bd9LU 0x4a6f36ceLU 0xea9f09d4LU 0x29b07cd6LU
+    0x31a4b2afLU 0x2a3f2331LU 0xc6a59430LU 0x35a266c0LU
+    0x744ebc37LU 0xfc82caa6LU 0xe090d0b0LU 0x33a7d815LU
+    0xf104984aLU 0x41ecdaf7LU 0x7fcd500eLU 0x1791f62fLU
+    0x764dd68dLU 0x43efb04dLU 0xccaa4d54LU 0xe49604dfLU
+    0x9ed1b5e3LU 0x4c6a881bLU 0xc12c1fb8LU 0x4665517fLU
+    0x9d5eea04LU 0x018c355dLU 0xfa877473LU 0xfb0b412eLU
+    0xb3671d5aLU 0x92dbd252LU 0xe9105633LU 0x6dd64713LU
+    0x9ad7618cLU 0x37a10c7aLU 0x59f8148eLU 0xeb133c89LU
+    0xcea927eeLU 0xb761c935LU 0xe11ce5edLU 0x7a47b13cLU
+    0x9cd2df59LU 0x55f2733fLU 0x1814ce79LU 0x73c737bfLU
+    0x53f7cdeaLU 0x5ffdaa5bLU 0xdf3d6f14LU 0x7844db86LU
+    0xcaaff381LU 0xb968c43eLU 0x3824342cLU 0xc2a3405fLU
+    0x161dc372LU 0xbce2250cLU 0x283c498bLU 0xff0d9541LU
+    0x39a80171LU 0x080cb3deLU 0xd8b4e49cLU 0x6456c190LU
+    0x7bcb8461LU 0xd532b670LU 0x486c5c74LU 0xd0b85742LU
+END
+
+LONGWORDLIST ID AES_Td1_id
+BEGIN
+    0x5051f4a7LU 0x537e4165LU 0xc31a17a4LU 0x963a275eLU
+    0xcb3bab6bLU 0xf11f9d45LU 0xabacfa58LU 0x934be303LU
+    0x552030faLU 0xf6ad766dLU 0x9188cc76LU 0x25f5024cLU
+    0xfc4fe5d7LU 0xd7c52acbLU 0x80263544LU 0x8fb562a3LU
+    0x49deb15aLU 0x6725ba1bLU 0x9845ea0eLU 0xe15dfec0LU
+    0x02c32f75LU 0x12814cf0LU 0xa38d4697LU 0xc66bd3f9LU
+    0xe7038f5fLU 0x9515929cLU 0xebbf6d7aLU 0xda955259LU
+    0x2dd4be83LU 0xd3587421LU 0x2949e069LU 0x448ec9c8LU
+    0x6a75c289LU 0x78f48e79LU 0x6b99583eLU 0xdd27b971LU
+    0xb6bee14fLU 0x17f088adLU 0x66c920acLU 0xb47dce3aLU
+    0x1863df4aLU 0x82e51a31LU 0x60975133LU 0x4562537fLU
+    0xe0b16477LU 0x84bb6baeLU 0x1cfe81a0LU 0x94f9082bLU
+    0x58704868LU 0x198f45fdLU 0x8794de6cLU 0xb7527bf8LU
+    0x23ab73d3LU 0xe2724b02LU 0x57e31f8fLU 0x2a6655abLU
+    0x07b2eb28LU 0x032fb5c2LU 0x9a86c57bLU 0xa5d33708LU
+    0xf2302887LU 0xb223bfa5LU 0xba02036aLU 0x5ced1682LU
+    0x2b8acf1cLU 0x92a779b4LU 0xf0f307f2LU 0xa14e69e2LU
+    0xcd65daf4LU 0xd50605beLU 0x1fd13462LU 0x8ac4a6feLU
+    0x9d342e53LU 0xa0a2f355LU 0x32058ae1LU 0x75a4f6ebLU
+    0x390b83ecLU 0xaa4060efLU 0x065e719fLU 0x51bd6e10LU
+    0xf93e218aLU 0x3d96dd06LU 0xaedd3e05LU 0x464de6bdLU
+    0xb591548dLU 0x0571c45dLU 0x6f0406d4LU 0xff605015LU
+    0x241998fbLU 0x97d6bde9LU 0xcc894043LU 0x7767d99eLU
+    0xbdb0e842LU 0x8807898bLU 0x38e7195bLU 0xdb79c8eeLU
+    0x47a17c0aLU 0xe97c420fLU 0xc9f8841eLU 0x00000000LU
+    0x83098086LU 0x48322bedLU 0xac1e1170LU 0x4e6c5a72LU
+    0xfbfd0effLU 0x560f8538LU 0x1e3daed5LU 0x27362d39LU
+    0x640a0fd9LU 0x21685ca6LU 0xd19b5b54LU 0x3a24362eLU
+    0xb10c0a67LU 0x0f9357e7LU 0xd2b4ee96LU 0x9e1b9b91LU
+    0x4f80c0c5LU 0xa261dc20LU 0x695a774bLU 0x161c121aLU
+    0x0ae293baLU 0xe5c0a02aLU 0x433c22e0LU 0x1d121b17LU
+    0x0b0e090dLU 0xadf28bc7LU 0xb92db6a8LU 0xc8141ea9LU
+    0x8557f119LU 0x4caf7507LU 0xbbee99ddLU 0xfda37f60LU
+    0x9ff70126LU 0xbc5c72f5LU 0xc544663bLU 0x345bfb7eLU
+    0x768b4329LU 0xdccb23c6LU 0x68b6edfcLU 0x63b8e4f1LU
+    0xcad731dcLU 0x10426385LU 0x40139722LU 0x2084c611LU
+    0x7d854a24LU 0xf8d2bb3dLU 0x11aef932LU 0x6dc729a1LU
+    0x4b1d9e2fLU 0xf3dcb230LU 0xec0d8652LU 0xd077c1e3LU
+    0x6c2bb316LU 0x99a970b9LU 0xfa119448LU 0x2247e964LU
+    0xc4a8fc8cLU 0x1aa0f03fLU 0xd8567d2cLU 0xef223390LU
+    0xc787494eLU 0xc1d938d1LU 0xfe8ccaa2LU 0x3698d40bLU
+    0xcfa6f581LU 0x28a57adeLU 0x26dab78eLU 0xa43fadbfLU
+    0xe42c3a9dLU 0x0d507892LU 0x9b6a5fccLU 0x62547e46LU
+    0xc2f68d13LU 0xe890d8b8LU 0x5e2e39f7LU 0xf582c3afLU
+    0xbe9f5d80LU 0x7c69d093LU 0xa96fd52dLU 0xb3cf2512LU
+    0x3bc8ac99LU 0xa710187dLU 0x6ee89c63LU 0x7bdb3bbbLU
+    0x09cd2678LU 0xf46e5918LU 0x01ec9ab7LU 0xa8834f9aLU
+    0x65e6956eLU 0x7eaaffe6LU 0x0821bccfLU 0xe6ef15e8LU
+    0xd9bae79bLU 0xce4a6f36LU 0xd4ea9f09LU 0xd629b07cLU
+    0xaf31a4b2LU 0x312a3f23LU 0x30c6a594LU 0xc035a266LU
+    0x37744ebcLU 0xa6fc82caLU 0xb0e090d0LU 0x1533a7d8LU
+    0x4af10498LU 0xf741ecdaLU 0x0e7fcd50LU 0x2f1791f6LU
+    0x8d764dd6LU 0x4d43efb0LU 0x54ccaa4dLU 0xdfe49604LU
+    0xe39ed1b5LU 0x1b4c6a88LU 0xb8c12c1fLU 0x7f466551LU
+    0x049d5eeaLU 0x5d018c35LU 0x73fa8774LU 0x2efb0b41LU
+    0x5ab3671dLU 0x5292dbd2LU 0x33e91056LU 0x136dd647LU
+    0x8c9ad761LU 0x7a37a10cLU 0x8e59f814LU 0x89eb133cLU
+    0xeecea927LU 0x35b761c9LU 0xede11ce5LU 0x3c7a47b1LU
+    0x599cd2dfLU 0x3f55f273LU 0x791814ceLU 0xbf73c737LU
+    0xea53f7cdLU 0x5b5ffdaaLU 0x14df3d6fLU 0x867844dbLU
+    0x81caaff3LU 0x3eb968c4LU 0x2c382434LU 0x5fc2a340LU
+    0x72161dc3LU 0x0cbce225LU 0x8b283c49LU 0x41ff0d95LU
+    0x7139a801LU 0xde080cb3LU 0x9cd8b4e4LU 0x906456c1LU
+    0x617bcb84LU 0x70d532b6LU 0x74486c5cLU 0x42d0b857LU
+END
+
+LONGWORDLIST ID AES_Td2_id
+BEGIN
+    0xa75051f4LU 0x65537e41LU 0xa4c31a17LU 0x5e963a27LU
+    0x6bcb3babLU 0x45f11f9dLU 0x58abacfaLU 0x03934be3LU
+    0xfa552030LU 0x6df6ad76LU 0x769188ccLU 0x4c25f502LU
+    0xd7fc4fe5LU 0xcbd7c52aLU 0x44802635LU 0xa38fb562LU
+    0x5a49deb1LU 0x1b6725baLU 0x0e9845eaLU 0xc0e15dfeLU
+    0x7502c32fLU 0xf012814cLU 0x97a38d46LU 0xf9c66bd3LU
+    0x5fe7038fLU 0x9c951592LU 0x7aebbf6dLU 0x59da9552LU
+    0x832dd4beLU 0x21d35874LU 0x692949e0LU 0xc8448ec9LU
+    0x896a75c2LU 0x7978f48eLU 0x3e6b9958LU 0x71dd27b9LU
+    0x4fb6bee1LU 0xad17f088LU 0xac66c920LU 0x3ab47dceLU
+    0x4a1863dfLU 0x3182e51aLU 0x33609751LU 0x7f456253LU
+    0x77e0b164LU 0xae84bb6bLU 0xa01cfe81LU 0x2b94f908LU
+    0x68587048LU 0xfd198f45LU 0x6c8794deLU 0xf8b7527bLU
+    0xd323ab73LU 0x02e2724bLU 0x8f57e31fLU 0xab2a6655LU
+    0x2807b2ebLU 0xc2032fb5LU 0x7b9a86c5LU 0x08a5d337LU
+    0x87f23028LU 0xa5b223bfLU 0x6aba0203LU 0x825ced16LU
+    0x1c2b8acfLU 0xb492a779LU 0xf2f0f307LU 0xe2a14e69LU
+    0xf4cd65daLU 0xbed50605LU 0x621fd134LU 0xfe8ac4a6LU
+    0x539d342eLU 0x55a0a2f3LU 0xe132058aLU 0xeb75a4f6LU
+    0xec390b83LU 0xefaa4060LU 0x9f065e71LU 0x1051bd6eLU
+
+    0x8af93e21LU 0x063d96ddLU 0x05aedd3eLU 0xbd464de6LU
+    0x8db59154LU 0x5d0571c4LU 0xd46f0406LU 0x15ff6050LU
+    0xfb241998LU 0xe997d6bdLU 0x43cc8940LU 0x9e7767d9LU
+    0x42bdb0e8LU 0x8b880789LU 0x5b38e719LU 0xeedb79c8LU
+    0x0a47a17cLU 0x0fe97c42LU 0x1ec9f884LU 0x00000000LU
+    0x86830980LU 0xed48322bLU 0x70ac1e11LU 0x724e6c5aLU
+    0xfffbfd0eLU 0x38560f85LU 0xd51e3daeLU 0x3927362dLU
+    0xd9640a0fLU 0xa621685cLU 0x54d19b5bLU 0x2e3a2436LU
+    0x67b10c0aLU 0xe70f9357LU 0x96d2b4eeLU 0x919e1b9bLU
+    0xc54f80c0LU 0x20a261dcLU 0x4b695a77LU 0x1a161c12LU
+    0xba0ae293LU 0x2ae5c0a0LU 0xe0433c22LU 0x171d121bLU
+    0x0d0b0e09LU 0xc7adf28bLU 0xa8b92db6LU 0xa9c8141eLU
+    0x198557f1LU 0x074caf75LU 0xddbbee99LU 0x60fda37fLU
+    0x269ff701LU 0xf5bc5c72LU 0x3bc54466LU 0x7e345bfbLU
+    0x29768b43LU 0xc6dccb23LU 0xfc68b6edLU 0xf163b8e4LU
+    0xdccad731LU 0x85104263LU 0x22401397LU 0x112084c6LU
+    0x247d854aLU 0x3df8d2bbLU 0x3211aef9LU 0xa16dc729LU
+    0x2f4b1d9eLU 0x30f3dcb2LU 0x52ec0d86LU 0xe3d077c1LU
+    0x166c2bb3LU 0xb999a970LU 0x48fa1194LU 0x642247e9LU
+    0x8cc4a8fcLU 0x3f1aa0f0LU 0x2cd8567dLU 0x90ef2233LU
+    0x4ec78749LU 0xd1c1d938LU 0xa2fe8ccaLU 0x0b3698d4LU
+    0x81cfa6f5LU 0xde28a57aLU 0x8e26dab7LU 0xbfa43fadLU
+    0x9de42c3aLU 0x920d5078LU 0xcc9b6a5fLU 0x4662547eLU
+    0x13c2f68dLU 0xb8e890d8LU 0xf75e2e39LU 0xaff582c3LU
+    0x80be9f5dLU 0x937c69d0LU 0x2da96fd5LU 0x12b3cf25LU
+    0x993bc8acLU 0x7da71018LU 0x636ee89cLU 0xbb7bdb3bLU
+    0x7809cd26LU 0x18f46e59LU 0xb701ec9aLU 0x9aa8834fLU
+    0x6e65e695LU 0xe67eaaffLU 0xcf0821bcLU 0xe8e6ef15LU
+    0x9bd9bae7LU 0x36ce4a6fLU 0x09d4ea9fLU 0x7cd629b0LU
+    0xb2af31a4LU 0x23312a3fLU 0x9430c6a5LU 0x66c035a2LU
+    0xbc37744eLU 0xcaa6fc82LU 0xd0b0e090LU 0xd81533a7LU
+    0x984af104LU 0xdaf741ecLU 0x500e7fcdLU 0xf62f1791LU
+    0xd68d764dLU 0xb04d43efLU 0x4d54ccaaLU 0x04dfe496LU
+    0xb5e39ed1LU 0x881b4c6aLU 0x1fb8c12cLU 0x517f4665LU
+    0xea049d5eLU 0x355d018cLU 0x7473fa87LU 0x412efb0bLU
+    0x1d5ab367LU 0xd25292dbLU 0x5633e910LU 0x47136dd6LU
+    0x618c9ad7LU 0x0c7a37a1LU 0x148e59f8LU 0x3c89eb13LU
+    0x27eecea9LU 0xc935b761LU 0xe5ede11cLU 0xb13c7a47LU
+    0xdf599cd2LU 0x733f55f2LU 0xce791814LU 0x37bf73c7LU
+    0xcdea53f7LU 0xaa5b5ffdLU 0x6f14df3dLU 0xdb867844LU
+    0xf381caafLU 0xc43eb968LU 0x342c3824LU 0x405fc2a3LU
+    0xc372161dLU 0x250cbce2LU 0x498b283cLU 0x9541ff0dLU
+    0x017139a8LU 0xb3de080cLU 0xe49cd8b4LU 0xc1906456LU
+    0x84617bcbLU 0xb670d532LU 0x5c74486cLU 0x5742d0b8LU
+END
+
+LONGWORDLIST ID AES_Td3_id
+BEGIN
+    0xf4a75051LU 0x4165537eLU 0x17a4c31aLU 0x275e963aLU
+    0xab6bcb3bLU 0x9d45f11fLU 0xfa58abacLU 0xe303934bLU
+    0x30fa5520LU 0x766df6adLU 0xcc769188LU 0x024c25f5LU
+    0xe5d7fc4fLU 0x2acbd7c5LU 0x35448026LU 0x62a38fb5LU
+    0xb15a49deLU 0xba1b6725LU 0xea0e9845LU 0xfec0e15dLU
+    0x2f7502c3LU 0x4cf01281LU 0x4697a38dLU 0xd3f9c66bLU
+    0x8f5fe703LU 0x929c9515LU 0x6d7aebbfLU 0x5259da95LU
+    0xbe832dd4LU 0x7421d358LU 0xe0692949LU 0xc9c8448eLU
+    0xc2896a75LU 0x8e7978f4LU 0x583e6b99LU 0xb971dd27LU
+    0xe14fb6beLU 0x88ad17f0LU 0x20ac66c9LU 0xce3ab47dLU
+    0xdf4a1863LU 0x1a3182e5LU 0x51336097LU 0x537f4562LU
+    0x6477e0b1LU 0x6bae84bbLU 0x81a01cfeLU 0x082b94f9LU
+    0x48685870LU 0x45fd198fLU 0xde6c8794LU 0x7bf8b752LU
+    0x73d323abLU 0x4b02e272LU 0x1f8f57e3LU 0x55ab2a66LU
+    0xeb2807b2LU 0xb5c2032fLU 0xc57b9a86LU 0x3708a5d3LU
+    0x2887f230LU 0xbfa5b223LU 0x036aba02LU 0x16825cedLU
+    0xcf1c2b8aLU 0x79b492a7LU 0x07f2f0f3LU 0x69e2a14eLU
+    0xdaf4cd65LU 0x05bed506LU 0x34621fd1LU 0xa6fe8ac4LU
+    0x2e539d34LU 0xf355a0a2LU 0x8ae13205LU 0xf6eb75a4LU
+    0x83ec390bLU 0x60efaa40LU 0x719f065eLU 0x6e1051bdLU
+    0x218af93eLU 0xdd063d96LU 0x3e05aeddLU 0xe6bd464dLU
+    0x548db591LU 0xc45d0571LU 0x06d46f04LU 0x5015ff60LU
+    0x98fb2419LU 0xbde997d6LU 0x4043cc89LU 0xd99e7767LU
+    0xe842bdb0LU 0x898b8807LU 0x195b38e7LU 0xc8eedb79LU
+    0x7c0a47a1LU 0x420fe97cLU 0x841ec9f8LU 0x00000000LU
+    0x80868309LU 0x2bed4832LU 0x1170ac1eLU 0x5a724e6cLU
+    0x0efffbfdLU 0x8538560fLU 0xaed51e3dLU 0x2d392736LU
+    0x0fd9640aLU 0x5ca62168LU 0x5b54d19bLU 0x362e3a24LU
+    0x0a67b10cLU 0x57e70f93LU 0xee96d2b4LU 0x9b919e1bLU
+    0xc0c54f80LU 0xdc20a261LU 0x774b695aLU 0x121a161cLU
+    0x93ba0ae2LU 0xa02ae5c0LU 0x22e0433cLU 0x1b171d12LU
+    0x090d0b0eLU 0x8bc7adf2LU 0xb6a8b92dLU 0x1ea9c814LU
+    0xf1198557LU 0x75074cafLU 0x99ddbbeeLU 0x7f60fda3LU
+    0x01269ff7LU 0x72f5bc5cLU 0x663bc544LU 0xfb7e345bLU
+    0x4329768bLU 0x23c6dccbLU 0xedfc68b6LU 0xe4f163b8LU
+    0x31dccad7LU 0x63851042LU 0x97224013LU 0xc6112084LU
+    0x4a247d85LU 0xbb3df8d2LU 0xf93211aeLU 0x29a16dc7LU
+    0x9e2f4b1dLU 0xb230f3dcLU 0x8652ec0dLU 0xc1e3d077LU
+    0xb3166c2bLU 0x70b999a9LU 0x9448fa11LU 0xe9642247LU
+    0xfc8cc4a8LU 0xf03f1aa0LU 0x7d2cd856LU 0x3390ef22LU
+    0x494ec787LU 0x38d1c1d9LU 0xcaa2fe8cLU 0xd40b3698LU
+    0xf581cfa6LU 0x7ade28a5LU 0xb78e26daLU 0xadbfa43fLU
+    0x3a9de42cLU 0x78920d50LU 0x5fcc9b6aLU 0x7e466254LU
+    0x8d13c2f6LU 0xd8b8e890LU 0x39f75e2eLU 0xc3aff582LU
+    0x5d80be9fLU 0xd0937c69LU 0xd52da96fLU 0x2512b3cfLU
+    0xac993bc8LU 0x187da710LU 0x9c636ee8LU 0x3bbb7bdbLU
+    0x267809cdLU 0x5918f46eLU 0x9ab701ecLU 0x4f9aa883LU
+    0x956e65e6LU 0xffe67eaaLU 0xbccf0821LU 0x15e8e6efLU
+    0xe79bd9baLU 0x6f36ce4aLU 0x9f09d4eaLU 0xb07cd629LU
+    0xa4b2af31LU 0x3f23312aLU 0xa59430c6LU 0xa266c035LU
+    0x4ebc3774LU 0x82caa6fcLU 0x90d0b0e0LU 0xa7d81533LU
+    0x04984af1LU 0xecdaf741LU 0xcd500e7fLU 0x91f62f17LU
+    0x4dd68d76LU 0xefb04d43LU 0xaa4d54ccLU 0x9604dfe4LU
+    0xd1b5e39eLU 0x6a881b4cLU 0x2c1fb8c1LU 0x65517f46LU
+    0x5eea049dLU 0x8c355d01LU 0x877473faLU 0x0b412efbLU
+    0x671d5ab3LU 0xdbd25292LU 0x105633e9LU 0xd647136dLU
+    0xd7618c9aLU 0xa10c7a37LU 0xf8148e59LU 0x133c89ebLU
+    0xa927eeceLU 0x61c935b7LU 0x1ce5ede1LU 0x47b13c7aLU
+    0xd2df599cLU 0xf2733f55LU 0x14ce7918LU 0xc737bf73LU
+    0xf7cdea53LU 0xfdaa5b5fLU 0x3d6f14dfLU 0x44db8678LU
+    0xaff381caLU 0x68c43eb9LU 0x24342c38LU 0xa3405fc2LU
+    0x1dc37216LU 0xe2250cbcLU 0x3c498b28LU 0x0d9541ffLU
+    0xa8017139LU 0x0cb3de08LU 0xb4e49cd8LU 0x56c19064LU
+    0xcb84617bLU 0x32b670d5LU 0x6c5c7448LU 0xb85742d0LU
+END
+
+LONGWORDLIST ID AES_Td4_id
+BEGIN
+    0x52525252LU 0x09090909LU 0x6a6a6a6aLU 0xd5d5d5d5LU
+    0x30303030LU 0x36363636LU 0xa5a5a5a5LU 0x38383838LU
+    0xbfbfbfbfLU 0x40404040LU 0xa3a3a3a3LU 0x9e9e9e9eLU
+    0x81818181LU 0xf3f3f3f3LU 0xd7d7d7d7LU 0xfbfbfbfbLU
+    0x7c7c7c7cLU 0xe3e3e3e3LU 0x39393939LU 0x82828282LU
+    0x9b9b9b9bLU 0x2f2f2f2fLU 0xffffffffLU 0x87878787LU
+    0x34343434LU 0x8e8e8e8eLU 0x43434343LU 0x44444444LU
+    0xc4c4c4c4LU 0xdedededeLU 0xe9e9e9e9LU 0xcbcbcbcbLU
+    0x54545454LU 0x7b7b7b7bLU 0x94949494LU 0x32323232LU
+    0xa6a6a6a6LU 0xc2c2c2c2LU 0x23232323LU 0x3d3d3d3dLU
+    0xeeeeeeeeLU 0x4c4c4c4cLU 0x95959595LU 0x0b0b0b0bLU
+    0x42424242LU 0xfafafafaLU 0xc3c3c3c3LU 0x4e4e4e4eLU
+    0x08080808LU 0x2e2e2e2eLU 0xa1a1a1a1LU 0x66666666LU
+    0x28282828LU 0xd9d9d9d9LU 0x24242424LU 0xb2b2b2b2LU
+    0x76767676LU 0x5b5b5b5bLU 0xa2a2a2a2LU 0x49494949LU
+    0x6d6d6d6dLU 0x8b8b8b8bLU 0xd1d1d1d1LU 0x25252525LU
+    0x72727272LU 0xf8f8f8f8LU 0xf6f6f6f6LU 0x64646464LU
+    0x86868686LU 0x68686868LU 0x98989898LU 0x16161616LU
+    0xd4d4d4d4LU 0xa4a4a4a4LU 0x5c5c5c5cLU 0xccccccccLU
+    0x5d5d5d5dLU 0x65656565LU 0xb6b6b6b6LU 0x92929292LU
+    0x6c6c6c6cLU 0x70707070LU 0x48484848LU 0x50505050LU
+    0xfdfdfdfdLU 0xededededLU 0xb9b9b9b9LU 0xdadadadaLU
+    0x5e5e5e5eLU 0x15151515LU 0x46464646LU 0x57575757LU
+    0xa7a7a7a7LU 0x8d8d8d8dLU 0x9d9d9d9dLU 0x84848484LU
+    0x90909090LU 0xd8d8d8d8LU 0xababababLU 0x00000000LU
+    0x8c8c8c8cLU 0xbcbcbcbcLU 0xd3d3d3d3LU 0x0a0a0a0aLU
+    0xf7f7f7f7LU 0xe4e4e4e4LU 0x58585858LU 0x05050505LU
+    0xb8b8b8b8LU 0xb3b3b3b3LU 0x45454545LU 0x06060606LU
+    0xd0d0d0d0LU 0x2c2c2c2cLU 0x1e1e1e1eLU 0x8f8f8f8fLU
+    0xcacacacaLU 0x3f3f3f3fLU 0x0f0f0f0fLU 0x02020202LU
+    0xc1c1c1c1LU 0xafafafafLU 0xbdbdbdbdLU 0x03030303LU
+    0x01010101LU 0x13131313LU 0x8a8a8a8aLU 0x6b6b6b6bLU
+    0x3a3a3a3aLU 0x91919191LU 0x11111111LU 0x41414141LU
+    0x4f4f4f4fLU 0x67676767LU 0xdcdcdcdcLU 0xeaeaeaeaLU
+    0x97979797LU 0xf2f2f2f2LU 0xcfcfcfcfLU 0xcecececeLU
+    0xf0f0f0f0LU 0xb4b4b4b4LU 0xe6e6e6e6LU 0x73737373LU
+    0x96969696LU 0xacacacacLU 0x74747474LU 0x22222222LU
+    0xe7e7e7e7LU 0xadadadadLU 0x35353535LU 0x85858585LU
+    0xe2e2e2e2LU 0xf9f9f9f9LU 0x37373737LU 0xe8e8e8e8LU
+    0x1c1c1c1cLU 0x75757575LU 0xdfdfdfdfLU 0x6e6e6e6eLU
+    0x47474747LU 0xf1f1f1f1LU 0x1a1a1a1aLU 0x71717171LU
+    0x1d1d1d1dLU 0x29292929LU 0xc5c5c5c5LU 0x89898989LU
+    0x6f6f6f6fLU 0xb7b7b7b7LU 0x62626262LU 0x0e0e0e0eLU
+    0xaaaaaaaaLU 0x18181818LU 0xbebebebeLU 0x1b1b1b1bLU
+    0xfcfcfcfcLU 0x56565656LU 0x3e3e3e3eLU 0x4b4b4b4bLU
+    0xc6c6c6c6LU 0xd2d2d2d2LU 0x79797979LU 0x20202020LU
+    0x9a9a9a9aLU 0xdbdbdbdbLU 0xc0c0c0c0LU 0xfefefefeLU
+    0x78787878LU 0xcdcdcdcdLU 0x5a5a5a5aLU 0xf4f4f4f4LU
+    0x1f1f1f1fLU 0xddddddddLU 0xa8a8a8a8LU 0x33333333LU
+    0x88888888LU 0x07070707LU 0xc7c7c7c7LU 0x31313131LU
+    0xb1b1b1b1LU 0x12121212LU 0x10101010LU 0x59595959LU
+    0x27272727LU 0x80808080LU 0xececececLU 0x5f5f5f5fLU
+    0x60606060LU 0x51515151LU 0x7f7f7f7fLU 0xa9a9a9a9LU
+    0x19191919LU 0xb5b5b5b5LU 0x4a4a4a4aLU 0x0d0d0d0dLU
+    0x2d2d2d2dLU 0xe5e5e5e5LU 0x7a7a7a7aLU 0x9f9f9f9fLU
+    0x93939393LU 0xc9c9c9c9LU 0x9c9c9c9cLU 0xefefefefLU
+    0xa0a0a0a0LU 0xe0e0e0e0LU 0x3b3b3b3bLU 0x4d4d4d4dLU
+    0xaeaeaeaeLU 0x2a2a2a2aLU 0xf5f5f5f5LU 0xb0b0b0b0LU
+    0xc8c8c8c8LU 0xebebebebLU 0xbbbbbbbbLU 0x3c3c3c3cLU
+    0x83838383LU 0x53535353LU 0x99999999LU 0x61616161LU
+    0x17171717LU 0x2b2b2b2bLU 0x04040404LU 0x7e7e7e7eLU
+    0xbabababaLU 0x77777777LU 0xd6d6d6d6LU 0x26262626LU
+    0xe1e1e1e1LU 0x69696969LU 0x14141414LU 0x63636363LU
+    0x55555555LU 0x21212121LU 0x0c0c0c0cLU 0x7d7d7d7dLU
+END
diff --git a/crypto/openssl/bn/bn.h b/crypto/openssl/bn/bn.h
new file mode 100644 (file)
index 0000000..89596ca
--- /dev/null
@@ -0,0 +1,258 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// BN external header. Some contents moved to bn_internal.h
+// removed 64-bit, 16-bit, 8-bit definitions
+// use stdint types
+// moved structure definitions to bn_internal.h
+// remove prototypes for all functions not actually used in pssh
+
+#ifndef HEADER_BN_H
+#define HEADER_BN_H
+
+#include "includes.h"
+#define OPENSSL_NO_FP_API
+#define THIRTY_TWO_BIT
+
+
+#ifdef THIRTY_TWO_BIT
+#define BN_ULLONG uint64_t
+#define BN_LLONG  int64_t
+#define BN_ULONG  uint32_t
+#define BN_LONG   int32_t
+#define BN_BITS                64
+#define BN_BYTES       4
+#define BN_BITS2       32
+#define BN_BITS4       16
+#ifdef OPENSSL_SYS_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
+
+typedef struct bignum_st BIGNUM;
+
+/* Used for temp variables (declaration hidden in bn_lcl.h) */
+typedef struct bignum_ctx BN_CTX;
+
+typedef struct bn_blinding_st BN_BLINDING;
+
+/* Used for montgomery multiplication */
+typedef struct bn_mont_ctx_st BN_MONT_CTX;
+
+/* Used for reciprocal division/mod functions
+ * It cannot be shared between threads
+ */
+typedef struct bn_recp_ctx_st BN_RECP_CTX;
+
+#define BN_num_bytes(a)        ((BN_num_bits(a)+7)/8)
+int BN_is_negative(BIGNUM *a);
+BN_CTX *BN_CTX_new(void);
+void   BN_CTX_free(BN_CTX *c);
+void   BN_CTX_start(BN_CTX *ctx);
+BIGNUM *BN_CTX_get(BN_CTX *ctx);
+void   BN_CTX_end(BN_CTX *ctx);
+int     BN_rand(BIGNUM *rnd, int bits, int top,int bottom);
+int    BN_num_bits(const BIGNUM *a);
+BIGNUM *BN_new(void);
+void   BN_clear_free(BIGNUM *a);
+BIGNUM *BN_bin2bn(const unsigned char *s,int len,BIGNUM *ret);
+int    BN_bn2bin(const BIGNUM *a, unsigned char *to);
+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_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int    BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
+       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+char * BN_bn2hex(const BIGNUM *a);
+uint32_t       BN_hex2bn(BIGNUM **a, const char *str);
+BN_MONT_CTX *BN_MONT_CTX_new(void );
+void BN_MONT_CTX_free(BN_MONT_CTX *mont);
+int BN_MONT_CTX_set(BN_MONT_CTX *mont,const BIGNUM *mod,BN_CTX *ctx);
+#define BN_mod(rem,m,d,ctx) BN_div(NULL,(rem),(m),(d),(ctx))
+int BN_is_zero(const BIGNUM *a);
+int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+               const BIGNUM *m, BN_CTX *ctx);
+int BN_ucmp(const BIGNUM *a, const BIGNUM *b);
+BIGNUM *BN_mod_inverse(BIGNUM *ret,
+                       const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
+int    BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
+       BN_CTX *ctx);
+int    BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int    BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int    BN_rand_range(BIGNUM *r, BIGNUM *range);
+
+
+#ifdef BNTEST
+// GrP bntest
+void BN_set_negative(BIGNUM *a, int neg);
+int BN_bntest_rand(BIGNUM *rnd, int bits, int top,int bottom);
+BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b);
+int    BN_set_bit(BIGNUM *a, int n);
+int    BN_add_word(BIGNUM *a, BN_ULONG w);
+int    BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
+int    BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+BN_RECP_CTX *BN_RECP_CTX_new(void);
+int    BN_sqr(BIGNUM *r, const BIGNUM *a,BN_CTX *ctx);
+int    BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
+int BN_to_montgomery(BIGNUM *r,const BIGNUM *a,
+       BN_MONT_CTX *mont, BN_CTX *ctx);
+int BN_from_montgomery(BIGNUM *r,const BIGNUM *a,
+       BN_MONT_CTX *mont, BN_CTX *ctx);
+int BN_mod_mul_montgomery(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,
+       BN_MONT_CTX *mont, BN_CTX *ctx);
+int    BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+       const BIGNUM *m,BN_CTX *ctx);
+int    BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,BN_CTX *ctx);
+int    BN_RECP_CTX_set(BN_RECP_CTX *recp,const BIGNUM *rdiv,BN_CTX *ctx);
+int    BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
+       BN_RECP_CTX *recp, BN_CTX *ctx);
+void   BN_RECP_CTX_free(BN_RECP_CTX *recp);
+int    BN_set_word(BIGNUM *a, BN_ULONG w);
+#define BN_one(a)       (BN_set_word((a),1))
+#endif
+
+
+/* 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.
+ */
+void ERR_load_BN_strings(void);
+
+/* 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_GET                                         116
+#define BN_F_BN_CTX_NEW                                         106
+#define BN_F_BN_DIV                                     107
+#define BN_F_BN_EXPAND2                                         108
+#define BN_F_BN_EXPAND_INTERNAL                                 120
+#define BN_F_BN_MOD_EXP2_MONT                           118
+#define BN_F_BN_MOD_EXP_MONT                            109
+#define BN_F_BN_MOD_EXP_MONT_WORD                       117
+#define BN_F_BN_MOD_INVERSE                             110
+#define BN_F_BN_MOD_LSHIFT_QUICK                        119
+#define BN_F_BN_MOD_MUL_RECIPROCAL                      111
+#define BN_F_BN_MOD_SQRT                                121
+#define BN_F_BN_MPI2BN                                  112
+#define BN_F_BN_NEW                                     113
+#define BN_F_BN_RAND                                    114
+#define BN_F_BN_RAND_RANGE                              122
+#define BN_F_BN_USUB                                    115
+
+/* Reason codes. */
+#define BN_R_ARG2_LT_ARG3                               100
+#define BN_R_BAD_RECIPROCAL                             101
+#define BN_R_BIGNUM_TOO_LONG                            114
+#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_INPUT_NOT_REDUCED                          110
+#define BN_R_INVALID_LENGTH                             106
+#define BN_R_INVALID_RANGE                              115
+#define BN_R_NOT_A_SQUARE                               111
+#define BN_R_NOT_INITIALIZED                            107
+#define BN_R_NO_INVERSE                                         108
+#define BN_R_P_IS_NOT_PRIME                             112
+#define BN_R_TOO_MANY_ITERATIONS                        113
+#define BN_R_TOO_MANY_TEMPORARY_VARIABLES               109
+
+#endif
diff --git a/crypto/openssl/bn/bn_armstubs.c b/crypto/openssl/bn/bn_armstubs.c
new file mode 100644 (file)
index 0000000..8e48d0c
--- /dev/null
@@ -0,0 +1,392 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// 68K side of 68K->ARM calls into bignum library
+
+#include "includes.h"
+#include "bn.h"
+#include "bn_armstubs.h"
+#include "armstubs.h"
+#include "peal.h"
+
+extern void assert_failed(uint32_t which);
+
+
+static const char bn_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,
+};
+
+
+int BN_is_negative(BIGNUM *a) {
+    uint32_t param;
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param = (uint32_t)a;
+    return PealCall(arm_module, sym, &param);
+}
+
+BN_CTX *BN_CTX_new(void) {
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    return (BN_CTX *) PealCall(arm_module, sym, NULL);
+}
+
+void   BN_CTX_free(BN_CTX *c) {
+    uint32_t param;
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param = (uint32_t)c;
+    PealCall(arm_module, sym, &param);
+}
+
+void   BN_CTX_start(BN_CTX *ctx) {
+    uint32_t param;
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param = (uint32_t)ctx;
+    PealCall(arm_module, sym, &param);
+}
+
+BIGNUM *BN_CTX_get(BN_CTX *ctx) {
+    uint32_t param;
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param = (uint32_t)ctx;
+    return (BIGNUM *) PealCall(arm_module, sym, &param);
+}
+
+void   BN_CTX_end(BN_CTX *ctx) {
+    uint32_t param;
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param = (uint32_t)ctx;
+    PealCall(arm_module, sym, &param);
+}
+
+int     BN_rand(BIGNUM *rnd, int bits, int top,int bottom) {
+    uint32_t param[4];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param[0] = (uint32_t)rnd;
+    param[1] = (uint32_t)bits;
+    param[2] = (uint32_t)top;
+    param[3] = (uint32_t)bottom;
+    return (int) PealCall(arm_module, sym, param);
+}
+
+int    BN_num_bits(const BIGNUM *a) {
+    uint32_t param;
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param = (uint32_t)a;
+    return (int) PealCall(arm_module, sym, &param);
+}
+
+BIGNUM *BN_new(void) {
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    return (BIGNUM *) PealCall(arm_module, sym, NULL);
+}
+
+void   BN_clear_free(BIGNUM *a) {
+    uint32_t param;
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param = (uint32_t)a;
+    PealCall(arm_module, sym, &param);
+}
+
+BIGNUM *BN_bin2bn(const unsigned char *s,int len,BIGNUM *ret) {
+    uint32_t param[3];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param[0] = (uint32_t)s;
+    param[1] = (uint32_t)len;
+    param[2] = (uint32_t)ret;
+    return (BIGNUM *) PealCall(arm_module, sym, param);
+}
+
+int    BN_bn2bin(const BIGNUM *a, unsigned char *to) {
+    uint32_t param[2];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param[0] = (uint32_t)a;
+    param[1] = (uint32_t)to;
+    return (int) PealCall(arm_module, sym, param);
+}
+
+int    BN_cmp(const BIGNUM *a, const BIGNUM *b) {
+    uint32_t param[2];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param[0] = (uint32_t)a;
+    param[1] = (uint32_t)b;
+    return (int) PealCall(arm_module, sym, param);
+}
+
+void   BN_free(BIGNUM *a) {
+    uint32_t param;
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param = (uint32_t)a;
+    PealCall(arm_module, sym, &param);
+}
+
+int    BN_is_bit_set(const BIGNUM *a, int n) {
+    uint32_t param[2];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param[0] = (uint32_t)a;
+    param[1] = (uint32_t)n;
+    return (int) PealCall(arm_module, sym, param);
+}
+
+int    BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                        const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) 
+{
+    uint32_t param[6];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param[0] = (uint32_t)r;
+    param[1] = (uint32_t)a;
+    param[2] = (uint32_t)p;
+    param[3] = (uint32_t)m;
+    param[4] = (uint32_t)ctx;
+    param[5] = (uint32_t)m_ctx;
+    return (int) PealCall(arm_module, sym, param);
+}
+
+int    BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
+                             const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) 
+{
+    uint32_t param[6];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param[0] = (uint32_t)r;
+    param[1] = (uint32_t)a;
+    param[2] = (uint32_t)p;
+    param[3] = (uint32_t)m;
+    param[4] = (uint32_t)ctx;
+    param[5] = (uint32_t)m_ctx;
+    return (int) PealCall(arm_module, sym, param);
+}
+
+char *         BN_bn2hex(const BIGNUM *a) {
+    uint32_t param;
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param = (uint32_t)a;
+    return (char *) PealCall(arm_module, sym, &param);
+}
+
+uint32_t       BN_hex2bn(BIGNUM **a, const char *str) {
+    uint32_t param[2];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param[0] = (uint32_t)a;
+    param[1] = (uint32_t)str;
+    return (uint32_t) PealCall(arm_module, sym, param);
+}
+
+BN_MONT_CTX *BN_MONT_CTX_new(void) {
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    return (BN_MONT_CTX *) PealCall(arm_module, sym, NULL);
+}
+
+void BN_MONT_CTX_free(BN_MONT_CTX *mont) {
+    uint32_t param;
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param = (uint32_t)mont;
+    PealCall(arm_module, sym, &param);
+}
+
+int BN_MONT_CTX_set(BN_MONT_CTX *mont,const BIGNUM *mod,BN_CTX *ctx) {
+    uint32_t param[3];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param[0] = (uint32_t)mont;
+    param[1] = (uint32_t)mod;
+    param[2] = (uint32_t)ctx;
+    return (int) PealCall(arm_module, sym, param);
+}
+
+int BN_is_zero(const BIGNUM *a) {
+    uint32_t param;
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param = (uint32_t)a;
+    return (int) PealCall(arm_module, sym, &param);
+}
+
+int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx) {
+    uint32_t param[5];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param[0] = (uint32_t)r;
+    param[1] = (uint32_t)a;
+    param[2] = (uint32_t)b;
+    param[3] = (uint32_t)m;
+    param[4] = (uint32_t)ctx;
+    return (int) PealCall(arm_module, sym, param);
+}
+
+int BN_ucmp(const BIGNUM *a, const BIGNUM *b) {
+    uint32_t param[2];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param[0] = (uint32_t)a;
+    param[1] = (uint32_t)b;
+    return (uint32_t) PealCall(arm_module, sym, param);
+}
+
+BIGNUM *BN_mod_inverse(BIGNUM *ret, const BIGNUM *a, const BIGNUM *n,
+                       BN_CTX *ctx)
+{
+    uint32_t param[4];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param[0] = (uint32_t)ret;
+    param[1] = (uint32_t)a;
+    param[2] = (uint32_t)n;
+    param[3] = (uint32_t)ctx;
+    return (BIGNUM *) PealCall(arm_module, sym, param);
+}
+
+int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) {
+    uint32_t param[5];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param[0] = (uint32_t)dv;
+    param[1] = (uint32_t)rem;
+    param[2] = (uint32_t)m;
+    param[3] = (uint32_t)d;
+    param[4] = (uint32_t)ctx;
+    return (int) PealCall(arm_module, sym, param);
+}
+
+int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
+    uint32_t param[3];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param[0] = (uint32_t)r;
+    param[1] = (uint32_t)a;
+    param[2] = (uint32_t)b;
+    return (int) PealCall(arm_module, sym, param);
+}
+
+int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
+    uint32_t param[3];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param[0] = (uint32_t)r;
+    param[1] = (uint32_t)a;
+    param[2] = (uint32_t)b;
+    return (int) PealCall(arm_module, sym, param);
+}
+
+int BN_rand_range(BIGNUM *r, BIGNUM *range) {
+    uint32_t param[2];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param[0] = (uint32_t)r;
+    param[1] = (uint32_t)range;
+    return (int) PealCall(arm_module, sym, param);
+}
diff --git a/crypto/openssl/bn/bn_armstubs.h b/crypto/openssl/bn/bn_armstubs.h
new file mode 100644 (file)
index 0000000..c9c857c
--- /dev/null
@@ -0,0 +1,31 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef BN_ARMSTUBS_H
+#define BN_ARMSTUBS_H
+
+#include <stdint.h>
+#include <PceNativeCall.h>
+
+#endif
diff --git a/crypto/openssl/cryptlib.h b/crypto/openssl/cryptlib.h
new file mode 100644 (file)
index 0000000..d411248
--- /dev/null
@@ -0,0 +1,115 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+/* Assorted OpenSSL definitions */
+
+#ifndef CRYPTLIB_H
+#define CRYPTLIB_H
+
+#include "includes.h"
+
+#include "xmalloc.h"
+
+#define OPENSSL_VERSION_NUMBER 0x0090703fL
+
+/* size of string representations */
+#define DECIMAL_SIZE(type)      ((sizeof(type)*8+2)/3+1)
+#define HEX_SIZE(type)          (sizeof(type)*2)
+
+#define DHerr(a,b) fatal("dh error " #a " " #b)
+#define EVPerr(a,b) fatal("EVP error " #a " " #b)
+#define DSAerr(a,b) fatal("DSA error " #a " " #b)
+#define RSAerr(a,b) fatal("RSA error " #a " " #b)
+
+#define OPENSSL_malloc(p) arena_malloc(p)
+#define OPENSSL_free(p) arena_free(p)
+#define OPENSSL_assert(a) do { if (!(a)) fatal("OpenSSL error"); } while (0)
+
+// in mem_clr.c
+extern void OPENSSL_cleanse(void *ptr, size_t len);
+
+#define OPENSSL_NO_BIO
+#define OPENSSL_NO_FP_API
+#define OPENSSL_NO_ENGINE
+
+#define OPENSSL_NO_MD2
+#define OPENSSL_NO_MD4
+#define OPENSSL_NO_RIPEMD
+#define OPENSSL_NO_RC4
+#define OPENSSL_NO_RC2
+#define OPENSSL_NO_RC5
+#define OPENSSL_NO_BF
+#define OPENSSL_NO_CAST
+#define OPENSSL_NO_IDEA
+#define OPENSSL_NO_MDC2
+
+#define OPENSSL_DISABLE_OLD_DES_SUPPORT
+#define OPENSSL_NO_SHA0
+
+#define OPENSSL_VERSION_PTEXT /**/
+
+#define STACK_OF(a) void
+
+#define DES_LONG uint32_t
+
+#define ASN1_TYPE void
+#define ASN1_OBJECT void
+
+#define ENGINE void
+typedef struct evp_cipher_st EVP_CIPHER;
+typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
+typedef struct env_md_st EVP_MD;
+typedef struct env_md_ctx_st EVP_MD_CTX;
+typedef struct evp_pkey_st EVP_PKEY;
+
+
+
+/* Macros to allow global variables to be reached through function calls when
+   required (if a shared library version requvres it, for example.
+   The way it's done allows definitions like this:
+
+        // in foobar.c
+        OPENSSL_IMPLEMENT_GLOBAL(int,foobar) = 0;
+        // in foobar.h
+        OPENSSL_DECLARE_GLOBAL(int,foobar);
+        #define foobar OPENSSL_GLOBAL_REF(foobar)
+*/
+#ifdef OPENSSL_EXPORT_VAR_AS_FUNCTION
+# define OPENSSL_IMPLEMENT_GLOBAL(type,name) static type _hide_##name; \
+        type *_shadow_##name(void) { return &_hide_##name; } \
+        static type _hide_##name
+# define OPENSSL_DECLARE_GLOBAL(type,name) type *_shadow_##name(void)
+# define OPENSSL_GLOBAL_REF(name) (*(_shadow_##name()))
+#else
+# define OPENSSL_IMPLEMENT_GLOBAL(type,name) OPENSSL_GLOBAL type _shadow_##name
+# define OPENSSL_DECLARE_GLOBAL(type,name) OPENSSL_EXPORT type _shadow_##name
+# define OPENSSL_GLOBAL_REF(name) _shadow_##name
+#endif
+
+#define OPENSSL_EXPORT extern
+#define OPENSSL_IMPORT extern
+#define OPENSSL_GLOBAL
+#define OPENSSL_EXTERN OPENSSL_IMPORT
+
+#endif
diff --git a/crypto/openssl/des/des.h b/crypto/openssl/des/des.h
new file mode 100644 (file)
index 0000000..df8f389
--- /dev/null
@@ -0,0 +1,271 @@
+/* crypto/des/des.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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed headers
+// added DES_SEGMENT everywhere
+// added destest() prototype
+
+#ifndef HEADER_NEW_DES_H
+#define HEADER_NEW_DES_H
+
+#ifdef OPENSSL_NO_DES
+#error DES is disabled.
+#endif
+
+#include "openssl/cryptlib.h"
+
+#ifdef OPENSSL_BUILD_SHLIBCRYPTO
+# undef OPENSSL_EXTERN
+# define OPENSSL_EXTERN OPENSSL_EXPORT
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned char DES_cblock[8];
+typedef /* const */ unsigned char const_DES_cblock[8];
+/* With "const", gcc 2.8.1 on Solaris thinks that DES_cblock *
+ * and const_DES_cblock * are incompatible pointer types. */
+
+typedef struct DES_ks
+    {
+    union
+       {
+       DES_cblock cblock;
+       /* make sure things are correct size on machines with
+        * 8 byte longs */
+       DES_LONG deslong[2];
+       } ks[16];
+    } DES_key_schedule;
+
+#ifndef OPENSSL_DISABLE_OLD_DES_SUPPORT
+# ifndef OPENSSL_ENABLE_OLD_DES_SUPPORT
+#  define OPENSSL_ENABLE_OLD_DES_SUPPORT
+# endif
+#endif
+
+#ifdef OPENSSL_ENABLE_OLD_DES_SUPPORT
+# include <openssl/des_old.h>
+#endif
+
+#define DES_KEY_SZ     (sizeof(DES_cblock))
+#define DES_SCHEDULE_SZ (sizeof(DES_key_schedule))
+
+#define DES_ENCRYPT    1
+#define DES_DECRYPT    0
+
+#define DES_CBC_MODE   0
+#define DES_PCBC_MODE  1
+
+#define DES_ecb2_encrypt(i,o,k1,k2,e) \
+       DES_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
+
+#define DES_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
+       DES_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
+
+#define DES_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
+       DES_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
+
+#define DES_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
+       DES_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
+
+OPENSSL_DECLARE_GLOBAL(int,DES_check_key);     /* defaults to false */
+#define DES_check_key OPENSSL_GLOBAL_REF(DES_check_key)
+OPENSSL_DECLARE_GLOBAL(int,DES_rw_mode);       /* defaults to DES_PCBC_MODE */
+#define DES_rw_mode OPENSSL_GLOBAL_REF(DES_rw_mode)
+
+const char *DES_options(void) DES_SEGMENT;
+void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output,
+                     DES_key_schedule *ks1,DES_key_schedule *ks2,
+                     DES_key_schedule *ks3, int enc) DES_SEGMENT;
+DES_LONG DES_cbc_cksum(const unsigned char *input,DES_cblock *output,
+                      long length,DES_key_schedule *schedule,
+                      const_DES_cblock *ivec) DES_SEGMENT;
+/* DES_cbc_encrypt does not update the IV!  Use DES_ncbc_encrypt instead. */
+void DES_cbc_encrypt(const unsigned char *input,unsigned char *output,
+                    long length,DES_key_schedule *schedule,DES_cblock *ivec,
+                    int enc) DES_SEGMENT;
+void DES_ncbc_encrypt(const unsigned char *input,unsigned char *output,
+                     long length,DES_key_schedule *schedule,DES_cblock *ivec,
+                     int enc) DES_SEGMENT;
+void DES_xcbc_encrypt(const unsigned char *input,unsigned char *output,
+                     long length,DES_key_schedule *schedule,DES_cblock *ivec,
+                     const_DES_cblock *inw,const_DES_cblock *outw,int enc) DES_SEGMENT;
+void DES_cfb_encrypt(const unsigned char *in,unsigned char *out,int numbits,
+                    long length,DES_key_schedule *schedule,DES_cblock *ivec,
+                    int enc) DES_SEGMENT;
+void DES_ecb_encrypt(const_DES_cblock *input,DES_cblock *output,
+                    DES_key_schedule *ks,int enc) DES_SEGMENT;
+
+/*     This is the DES encryption function that gets called by just about
+       every other DES routine in the library.  You should not use this
+       function except to implement 'modes' of DES.  I say this because the
+       functions that call this routine do the conversion from 'char *' to
+       long, and this needs to be done to make sure 'non-aligned' memory
+       access do not occur.  The characters are loaded 'little endian'.
+       Data is a pointer to 2 unsigned long's and ks is the
+       DES_key_schedule to use.  enc, is non zero specifies encryption,
+       zero if decryption. */
+void DES_encrypt1(DES_LONG *data,DES_key_schedule *ks, int enc) DES_SEGMENT;
+
+/*     This functions is the same as DES_encrypt1() except that the DES
+       initial permutation (IP) and final permutation (FP) have been left
+       out.  As for DES_encrypt1(), you should not use this function.
+       It is used by the routines in the library that implement triple DES.
+       IP() DES_encrypt2() DES_encrypt2() DES_encrypt2() FP() is the same
+       as DES_encrypt1() DES_encrypt1() DES_encrypt1() except faster :-). */
+void DES_encrypt2(DES_LONG *data,DES_key_schedule *ks, int enc) DES_SEGMENT;
+
+void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
+                 DES_key_schedule *ks2, DES_key_schedule *ks3) DES_SEGMENT;
+void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
+                 DES_key_schedule *ks2, DES_key_schedule *ks3) DES_SEGMENT;
+void DES_ede3_cbc_encrypt(const unsigned char *input,unsigned char *output, 
+                         long length,
+                         DES_key_schedule *ks1,DES_key_schedule *ks2,
+                         DES_key_schedule *ks3,DES_cblock *ivec,int enc) DES_SEGMENT;
+void DES_ede3_cbcm_encrypt(const unsigned char *in,unsigned char *out,
+                          long length,
+                          DES_key_schedule *ks1,DES_key_schedule *ks2,
+                          DES_key_schedule *ks3,
+                          DES_cblock *ivec1,DES_cblock *ivec2,
+                          int enc) DES_SEGMENT;
+void DES_ede3_cfb64_encrypt(const unsigned char *in,unsigned char *out,
+                           long length,DES_key_schedule *ks1,
+                           DES_key_schedule *ks2,DES_key_schedule *ks3,
+                           DES_cblock *ivec,int *num,int enc) DES_SEGMENT;
+void DES_ede3_ofb64_encrypt(const unsigned char *in,unsigned char *out,
+                           long length,DES_key_schedule *ks1,
+                           DES_key_schedule *ks2,DES_key_schedule *ks3,
+                           DES_cblock *ivec,int *num) DES_SEGMENT;
+
+void DES_xwhite_in2out(const_DES_cblock *DES_key,const_DES_cblock *in_white,
+                      DES_cblock *out_white) DES_SEGMENT;
+
+int DES_enc_read(int fd,void *buf,int len,DES_key_schedule *sched,
+                DES_cblock *iv) DES_SEGMENT;
+int DES_enc_write(int fd,const void *buf,int len,DES_key_schedule *sched,
+                 DES_cblock *iv) DES_SEGMENT;
+char *DES_fcrypt(const char *buf,const char *salt, char *ret) DES_SEGMENT;
+char *DES_crypt(const char *buf,const char *salt) DES_SEGMENT;
+void DES_ofb_encrypt(const unsigned char *in,unsigned char *out,int numbits,
+                    long length,DES_key_schedule *schedule,DES_cblock *ivec) DES_SEGMENT;
+void DES_pcbc_encrypt(const unsigned char *input,unsigned char *output,
+                     long length,DES_key_schedule *schedule,DES_cblock *ivec,
+                     int enc) DES_SEGMENT;
+DES_LONG DES_quad_cksum(const unsigned char *input,DES_cblock output[],
+                       long length,int out_count,DES_cblock *seed) DES_SEGMENT;
+int DES_random_key(DES_cblock *ret) DES_SEGMENT;
+void DES_set_odd_parity(DES_cblock *key) DES_SEGMENT;
+int DES_check_key_parity(const_DES_cblock *key) DES_SEGMENT;
+int DES_is_weak_key(const_DES_cblock *key) DES_SEGMENT;
+/* DES_set_key (= set_key = DES_key_sched = key_sched) calls
+ * DES_set_key_checked if global variable DES_check_key is set,
+ * DES_set_key_unchecked otherwise. */
+int DES_set_key(const_DES_cblock *key,DES_key_schedule *schedule) DES_SEGMENT;
+int DES_key_sched(const_DES_cblock *key,DES_key_schedule *schedule) DES_SEGMENT;
+int DES_set_key_checked(const_DES_cblock *key,DES_key_schedule *schedule) DES_SEGMENT;
+void DES_set_key_unchecked(const_DES_cblock *key,DES_key_schedule *schedule) DES_SEGMENT;
+void DES_string_to_key(const char *str,DES_cblock *key) DES_SEGMENT;
+void DES_string_to_2keys(const char *str,DES_cblock *key1,DES_cblock *key2) DES_SEGMENT;
+void DES_cfb64_encrypt(const unsigned char *in,unsigned char *out,long length,
+                      DES_key_schedule *schedule,DES_cblock *ivec,int *num,
+                      int enc) DES_SEGMENT;
+void DES_ofb64_encrypt(const unsigned char *in,unsigned char *out,long length,
+                      DES_key_schedule *schedule,DES_cblock *ivec,int *num) DES_SEGMENT;
+
+int DES_read_password(DES_cblock *key, const char *prompt, int verify) DES_SEGMENT;
+int DES_read_2passwords(DES_cblock *key1, DES_cblock *key2, const char *prompt,
+       int verify) DES_SEGMENT;
+
+#define DES_fixup_key_parity DES_set_odd_parity
+
+#ifdef PSSH_CRYPTOTESTS
+int destest(void) DES_SEGMENT;
+#endif
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/crypto/openssl/des/des_enc.c b/crypto/openssl/des/des_enc.c
new file mode 100644 (file)
index 0000000..9e0296d
--- /dev/null
@@ -0,0 +1,441 @@
+/* crypto/des/des_enc.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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// added data table lock/unlock to DES_encrypt1 and DES_encrypt2
+
+#include "des_locl.h"
+
+void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc)
+       {
+       register DES_LONG l,r,t,u;
+#ifdef DES_PTR
+       register const unsigned char *des_SP=(const unsigned char *)DES_SPtrans;
+#endif
+#ifndef DES_UNROLL
+       register int i;
+#endif
+       register DES_LONG *s;
+
+       des_lock_tables();
+
+       r=data[0];
+       l=data[1];
+
+       IP(r,l);
+       /* Things have been modified so that the initial rotate is
+        * done outside the loop.  This required the
+        * DES_SPtrans values in sp.h to be rotated 1 bit to the right.
+        * One perl script later and things have a 5% speed up on a sparc2.
+        * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
+        * for pointing this out. */
+       /* clear the top bits on machines with 8byte longs */
+       /* shift left by 2 */
+       r=ROTATE(r,29)&0xffffffffL;
+       l=ROTATE(l,29)&0xffffffffL;
+
+       s=ks->ks->deslong;
+       /* I don't know if it is worth the effort of loop unrolling the
+        * inner loop */
+       if (enc)
+               {
+#ifdef DES_UNROLL
+               D_ENCRYPT(l,r, 0); /*  1 */
+               D_ENCRYPT(r,l, 2); /*  2 */
+               D_ENCRYPT(l,r, 4); /*  3 */
+               D_ENCRYPT(r,l, 6); /*  4 */
+               D_ENCRYPT(l,r, 8); /*  5 */
+               D_ENCRYPT(r,l,10); /*  6 */
+               D_ENCRYPT(l,r,12); /*  7 */
+               D_ENCRYPT(r,l,14); /*  8 */
+               D_ENCRYPT(l,r,16); /*  9 */
+               D_ENCRYPT(r,l,18); /*  10 */
+               D_ENCRYPT(l,r,20); /*  11 */
+               D_ENCRYPT(r,l,22); /*  12 */
+               D_ENCRYPT(l,r,24); /*  13 */
+               D_ENCRYPT(r,l,26); /*  14 */
+               D_ENCRYPT(l,r,28); /*  15 */
+               D_ENCRYPT(r,l,30); /*  16 */
+#else
+               for (i=0; i<32; i+=8)
+                       {
+                       D_ENCRYPT(l,r,i+0); /*  1 */
+                       D_ENCRYPT(r,l,i+2); /*  2 */
+                       D_ENCRYPT(l,r,i+4); /*  3 */
+                       D_ENCRYPT(r,l,i+6); /*  4 */
+                       }
+#endif
+               }
+       else
+               {
+#ifdef DES_UNROLL
+               D_ENCRYPT(l,r,30); /* 16 */
+               D_ENCRYPT(r,l,28); /* 15 */
+               D_ENCRYPT(l,r,26); /* 14 */
+               D_ENCRYPT(r,l,24); /* 13 */
+               D_ENCRYPT(l,r,22); /* 12 */
+               D_ENCRYPT(r,l,20); /* 11 */
+               D_ENCRYPT(l,r,18); /* 10 */
+               D_ENCRYPT(r,l,16); /*  9 */
+               D_ENCRYPT(l,r,14); /*  8 */
+               D_ENCRYPT(r,l,12); /*  7 */
+               D_ENCRYPT(l,r,10); /*  6 */
+               D_ENCRYPT(r,l, 8); /*  5 */
+               D_ENCRYPT(l,r, 6); /*  4 */
+               D_ENCRYPT(r,l, 4); /*  3 */
+               D_ENCRYPT(l,r, 2); /*  2 */
+               D_ENCRYPT(r,l, 0); /*  1 */
+#else
+               for (i=30; i>0; i-=8)
+                       {
+                       D_ENCRYPT(l,r,i-0); /* 16 */
+                       D_ENCRYPT(r,l,i-2); /* 15 */
+                       D_ENCRYPT(l,r,i-4); /* 14 */
+                       D_ENCRYPT(r,l,i-6); /* 13 */
+                       }
+#endif
+               }
+
+       /* rotate and clear the top bits on machines with 8byte longs */
+       l=ROTATE(l,3)&0xffffffffL;
+       r=ROTATE(r,3)&0xffffffffL;
+
+       FP(r,l);
+       data[0]=l;
+       data[1]=r;
+       l=r=t=u=0;
+
+       des_unlock_tables();
+       }
+
+void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc)
+       {
+       register DES_LONG l,r,t,u;
+#ifdef DES_PTR
+       register const unsigned char *des_SP=(const unsigned char *)DES_SPtrans;
+#endif
+#ifndef DES_UNROLL
+       register int i;
+#endif
+       register DES_LONG *s;
+
+       des_lock_tables();
+
+       r=data[0];
+       l=data[1];
+
+       /* Things have been modified so that the initial rotate is
+        * done outside the loop.  This required the
+        * DES_SPtrans values in sp.h to be rotated 1 bit to the right.
+        * One perl script later and things have a 5% speed up on a sparc2.
+        * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
+        * for pointing this out. */
+       /* clear the top bits on machines with 8byte longs */
+       r=ROTATE(r,29)&0xffffffffL;
+       l=ROTATE(l,29)&0xffffffffL;
+
+       s=ks->ks->deslong;
+       /* I don't know if it is worth the effort of loop unrolling the
+        * inner loop */
+       if (enc)
+               {
+#ifdef DES_UNROLL
+               D_ENCRYPT(l,r, 0); /*  1 */
+               D_ENCRYPT(r,l, 2); /*  2 */
+               D_ENCRYPT(l,r, 4); /*  3 */
+               D_ENCRYPT(r,l, 6); /*  4 */
+               D_ENCRYPT(l,r, 8); /*  5 */
+               D_ENCRYPT(r,l,10); /*  6 */
+               D_ENCRYPT(l,r,12); /*  7 */
+               D_ENCRYPT(r,l,14); /*  8 */
+               D_ENCRYPT(l,r,16); /*  9 */
+               D_ENCRYPT(r,l,18); /*  10 */
+               D_ENCRYPT(l,r,20); /*  11 */
+               D_ENCRYPT(r,l,22); /*  12 */
+               D_ENCRYPT(l,r,24); /*  13 */
+               D_ENCRYPT(r,l,26); /*  14 */
+               D_ENCRYPT(l,r,28); /*  15 */
+               D_ENCRYPT(r,l,30); /*  16 */
+#else
+               for (i=0; i<32; i+=8)
+                       {
+                       D_ENCRYPT(l,r,i+0); /*  1 */
+                       D_ENCRYPT(r,l,i+2); /*  2 */
+                       D_ENCRYPT(l,r,i+4); /*  3 */
+                       D_ENCRYPT(r,l,i+6); /*  4 */
+                       }
+#endif
+               }
+       else
+               {
+#ifdef DES_UNROLL
+               D_ENCRYPT(l,r,30); /* 16 */
+               D_ENCRYPT(r,l,28); /* 15 */
+               D_ENCRYPT(l,r,26); /* 14 */
+               D_ENCRYPT(r,l,24); /* 13 */
+               D_ENCRYPT(l,r,22); /* 12 */
+               D_ENCRYPT(r,l,20); /* 11 */
+               D_ENCRYPT(l,r,18); /* 10 */
+               D_ENCRYPT(r,l,16); /*  9 */
+               D_ENCRYPT(l,r,14); /*  8 */
+               D_ENCRYPT(r,l,12); /*  7 */
+               D_ENCRYPT(l,r,10); /*  6 */
+               D_ENCRYPT(r,l, 8); /*  5 */
+               D_ENCRYPT(l,r, 6); /*  4 */
+               D_ENCRYPT(r,l, 4); /*  3 */
+               D_ENCRYPT(l,r, 2); /*  2 */
+               D_ENCRYPT(r,l, 0); /*  1 */
+#else
+               for (i=30; i>0; i-=8)
+                       {
+                       D_ENCRYPT(l,r,i-0); /* 16 */
+                       D_ENCRYPT(r,l,i-2); /* 15 */
+                       D_ENCRYPT(l,r,i-4); /* 14 */
+                       D_ENCRYPT(r,l,i-6); /* 13 */
+                       }
+#endif
+               }
+       /* rotate and clear the top bits on machines with 8byte longs */
+       data[0]=ROTATE(l,3)&0xffffffffL;
+       data[1]=ROTATE(r,3)&0xffffffffL;
+       l=r=t=u=0;
+
+       des_unlock_tables();
+       }
+
+void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
+                 DES_key_schedule *ks2, DES_key_schedule *ks3)
+       {
+       register DES_LONG l,r;
+
+       l=data[0];
+       r=data[1];
+       IP(l,r);
+       data[0]=l;
+       data[1]=r;
+       DES_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
+       DES_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
+       DES_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
+       l=data[0];
+       r=data[1];
+       FP(r,l);
+       data[0]=l;
+       data[1]=r;
+       }
+
+void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
+                 DES_key_schedule *ks2, DES_key_schedule *ks3)
+       {
+       register DES_LONG l,r;
+
+       l=data[0];
+       r=data[1];
+       IP(l,r);
+       data[0]=l;
+       data[1]=r;
+       DES_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
+       DES_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
+       DES_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
+       l=data[0];
+       r=data[1];
+       FP(r,l);
+       data[0]=l;
+       data[1]=r;
+       }
+
+#ifndef DES_DEFAULT_OPTIONS
+
+#undef CBC_ENC_C__DONT_UPDATE_IV
+#include "ncbc_enc.c" /* DES_ncbc_encrypt */
+
+void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
+                         long length, DES_key_schedule *ks1,
+                         DES_key_schedule *ks2, DES_key_schedule *ks3,
+                         DES_cblock *ivec, int enc)
+       {
+       register DES_LONG tin0,tin1;
+       register DES_LONG tout0,tout1,xor0,xor1;
+       register const unsigned char *in;
+       unsigned char *out;
+       register long l=length;
+       DES_LONG tin[2];
+       unsigned char *iv;
+
+       in=input;
+       out=output;
+       iv = &(*ivec)[0];
+
+       if (enc)
+               {
+               c2l(iv,tout0);
+               c2l(iv,tout1);
+               for (l-=8; l>=0; l-=8)
+                       {
+                       c2l(in,tin0);
+                       c2l(in,tin1);
+                       tin0^=tout0;
+                       tin1^=tout1;
+
+                       tin[0]=tin0;
+                       tin[1]=tin1;
+                       DES_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
+                       tout0=tin[0];
+                       tout1=tin[1];
+
+                       l2c(tout0,out);
+                       l2c(tout1,out);
+                       }
+               if (l != -8)
+                       {
+                       c2ln(in,tin0,tin1,l+8);
+                       tin0^=tout0;
+                       tin1^=tout1;
+
+                       tin[0]=tin0;
+                       tin[1]=tin1;
+                       DES_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
+                       tout0=tin[0];
+                       tout1=tin[1];
+
+                       l2c(tout0,out);
+                       l2c(tout1,out);
+                       }
+               iv = &(*ivec)[0];
+               l2c(tout0,iv);
+               l2c(tout1,iv);
+               }
+       else
+               {
+               register DES_LONG t0,t1;
+
+               c2l(iv,xor0);
+               c2l(iv,xor1);
+               for (l-=8; l>=0; l-=8)
+                       {
+                       c2l(in,tin0);
+                       c2l(in,tin1);
+
+                       t0=tin0;
+                       t1=tin1;
+
+                       tin[0]=tin0;
+                       tin[1]=tin1;
+                       DES_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
+                       tout0=tin[0];
+                       tout1=tin[1];
+
+                       tout0^=xor0;
+                       tout1^=xor1;
+                       l2c(tout0,out);
+                       l2c(tout1,out);
+                       xor0=t0;
+                       xor1=t1;
+                       }
+               if (l != -8)
+                       {
+                       c2l(in,tin0);
+                       c2l(in,tin1);
+                       
+                       t0=tin0;
+                       t1=tin1;
+
+                       tin[0]=tin0;
+                       tin[1]=tin1;
+                       DES_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
+                       tout0=tin[0];
+                       tout1=tin[1];
+               
+                       tout0^=xor0;
+                       tout1^=xor1;
+                       l2cn(tout0,tout1,out,l+8);
+                       xor0=t0;
+                       xor1=t1;
+                       }
+
+               iv = &(*ivec)[0];
+               l2c(xor0,iv);
+               l2c(xor1,iv);
+               }
+       tin0=tin1=tout0=tout1=xor0=xor1=0;
+       tin[0]=tin[1]=0;
+       }
+
+#endif /* DES_DEFAULT_OPTIONS */
diff --git a/crypto/openssl/des/des_locl.h b/crypto/openssl/des/des_locl.h
new file mode 100644 (file)
index 0000000..100da31
--- /dev/null
@@ -0,0 +1,431 @@
+/* crypto/des/des_locl.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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh: 
+// changed headers
+// added DES_SEGMENT
+// changed DES_SPtrans[8][64] to DES_SPtrans1[64], DES_SPtrans2[64], ...
+// added des_lock_tables and des_unlock_tables functions
+
+#ifndef HEADER_DES_LOCL_H
+#define HEADER_DES_LOCL_H
+
+#include "cryptlib.h"
+#include "des.h"
+
+#define ITERATIONS 16
+#define HALF_ITERATIONS 8
+
+/* used in des_read and des_write */
+#define MAXWRITE       (1024*16)
+#define BSIZE          (MAXWRITE+4)
+
+#define c2l(c,l)       (l =((DES_LONG)(*((c)++)))    , \
+                        l|=((DES_LONG)(*((c)++)))<< 8L, \
+                        l|=((DES_LONG)(*((c)++)))<<16L, \
+                        l|=((DES_LONG)(*((c)++)))<<24L)
+
+/* NOTE - c is not incremented as per c2l */
+#define c2ln(c,l1,l2,n)        { \
+                       c+=n; \
+                       l1=l2=0; \
+                       switch (n) { \
+                       case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
+                       case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
+                       case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
+                       case 5: l2|=((DES_LONG)(*(--(c))));     \
+                       case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
+                       case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
+                       case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
+                       case 1: l1|=((DES_LONG)(*(--(c))));     \
+                               } \
+                       }
+
+#define l2c(l,c)       (*((c)++)=(unsigned char)(((l)     )&0xff), \
+                        *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                        *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                        *((c)++)=(unsigned char)(((l)>>24L)&0xff))
+
+/* replacements for htonl and ntohl since I have no idea what to do
+ * when faced with machines with 8 byte longs. */
+#define HDRSIZE 4
+
+#define n2l(c,l)       (l =((DES_LONG)(*((c)++)))<<24L, \
+                        l|=((DES_LONG)(*((c)++)))<<16L, \
+                        l|=((DES_LONG)(*((c)++)))<< 8L, \
+                        l|=((DES_LONG)(*((c)++))))
+
+#define l2n(l,c)       (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
+                        *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                        *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                        *((c)++)=(unsigned char)(((l)     )&0xff))
+
+/* NOTE - c is not incremented as per l2c */
+#define l2cn(l1,l2,c,n)        { \
+                       c+=n; \
+                       switch (n) { \
+                       case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
+                       case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
+                       case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
+                       case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
+                       case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
+                       case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
+                       case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
+                       case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
+                               } \
+                       }
+
+#if defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)
+#define        ROTATE(a,n)     (_lrotr(a,n))
+#elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
+# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
+#  define ROTATE(a,n)  ({ register unsigned int ret;   \
+                               asm ("rorl %1,%0"       \
+                                       : "=r"(ret)     \
+                                       : "I"(n),"0"(a) \
+                                       : "cc");        \
+                          ret;                         \
+                       })
+# endif
+#endif
+#ifndef ROTATE
+#define        ROTATE(a,n)     (((a)>>(n))+((a)<<(32-(n))))
+#endif
+
+/* Don't worry about the LOAD_DATA() stuff, that is used by
+ * fcrypt() to add it's little bit to the front */
+
+#ifdef DES_FCRYPT
+
+#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
+       { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
+
+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
+       t=R^(R>>16L); \
+       u=t&E0; t&=E1; \
+       tmp=(u<<16); u^=R^s[S  ]; u^=tmp; \
+       tmp=(t<<16); t^=R^s[S+1]; t^=tmp
+#else
+#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
+       u=R^s[S  ]; \
+       t=R^s[S+1]
+#endif
+
+/* The changes to this macro may help or hinder, depending on the
+ * compiler and the architecture.  gcc2 always seems to do well :-).
+ * Inspired by Dana How <how@isl.stanford.edu>
+ * DO NOT use the alternative version on machines with 8 byte longs.
+ * It does not seem to work on the Alpha, even when DES_LONG is 4
+ * bytes, probably an issue of accessing non-word aligned objects :-( */
+#ifdef DES_PTR
+
+/* It recently occurred to me that 0^0^0^0^0^0^0 == 0, so there
+ * is no reason to not xor all the sub items together.  This potentially
+ * saves a register since things can be xored directly into L */
+
+#if defined(DES_RISC1) || defined(DES_RISC2)
+#ifdef DES_RISC1
+#define D_ENCRYPT(LL,R,S) { \
+       unsigned int u1,u2,u3; \
+       LOAD_DATA(R,S,u,t,E0,E1,u1); \
+       u2=(int)u>>8L; \
+       u1=(int)u&0xfc; \
+       u2&=0xfc; \
+       t=ROTATE(t,4); \
+       u>>=16L; \
+       LL^= *(const DES_LONG *)(des_SP      +u1); \
+       LL^= *(const DES_LONG *)(des_SP+0x200+u2); \
+       u3=(int)(u>>8L); \
+       u1=(int)u&0xfc; \
+       u3&=0xfc; \
+       LL^= *(const DES_LONG *)(des_SP+0x400+u1); \
+       LL^= *(const DES_LONG *)(des_SP+0x600+u3); \
+       u2=(int)t>>8L; \
+       u1=(int)t&0xfc; \
+       u2&=0xfc; \
+       t>>=16L; \
+       LL^= *(const DES_LONG *)(des_SP+0x100+u1); \
+       LL^= *(const DES_LONG *)(des_SP+0x300+u2); \
+       u3=(int)t>>8L; \
+       u1=(int)t&0xfc; \
+       u3&=0xfc; \
+       LL^= *(const DES_LONG *)(des_SP+0x500+u1); \
+       LL^= *(const DES_LONG *)(des_SP+0x700+u3); }
+#endif
+#ifdef DES_RISC2
+#define D_ENCRYPT(LL,R,S) { \
+       unsigned int u1,u2,s1,s2; \
+       LOAD_DATA(R,S,u,t,E0,E1,u1); \
+       u2=(int)u>>8L; \
+       u1=(int)u&0xfc; \
+       u2&=0xfc; \
+       t=ROTATE(t,4); \
+       LL^= *(const DES_LONG *)(des_SP      +u1); \
+       LL^= *(const DES_LONG *)(des_SP+0x200+u2); \
+       s1=(int)(u>>16L); \
+       s2=(int)(u>>24L); \
+       s1&=0xfc; \
+       s2&=0xfc; \
+       LL^= *(const DES_LONG *)(des_SP+0x400+s1); \
+       LL^= *(const DES_LONG *)(des_SP+0x600+s2); \
+       u2=(int)t>>8L; \
+       u1=(int)t&0xfc; \
+       u2&=0xfc; \
+       LL^= *(const DES_LONG *)(des_SP+0x100+u1); \
+       LL^= *(const DES_LONG *)(des_SP+0x300+u2); \
+       s1=(int)(t>>16L); \
+       s2=(int)(t>>24L); \
+       s1&=0xfc; \
+       s2&=0xfc; \
+       LL^= *(const DES_LONG *)(des_SP+0x500+s1); \
+       LL^= *(const DES_LONG *)(des_SP+0x700+s2); }
+#endif
+#else
+#define D_ENCRYPT(LL,R,S) { \
+       LOAD_DATA_tmp(R,S,u,t,E0,E1); \
+       t=ROTATE(t,4); \
+       LL^= \
+       *(const DES_LONG *)(des_SP      +((u     )&0xfc))^ \
+       *(const DES_LONG *)(des_SP+0x200+((u>> 8L)&0xfc))^ \
+       *(const DES_LONG *)(des_SP+0x400+((u>>16L)&0xfc))^ \
+       *(const DES_LONG *)(des_SP+0x600+((u>>24L)&0xfc))^ \
+       *(const DES_LONG *)(des_SP+0x100+((t     )&0xfc))^ \
+       *(const DES_LONG *)(des_SP+0x300+((t>> 8L)&0xfc))^ \
+       *(const DES_LONG *)(des_SP+0x500+((t>>16L)&0xfc))^ \
+       *(const DES_LONG *)(des_SP+0x700+((t>>24L)&0xfc)); }
+#endif
+
+#else /* original version */
+
+#if defined(DES_RISC1) || defined(DES_RISC2)
+#ifdef DES_RISC1
+#define D_ENCRYPT(LL,R,S) {\
+       unsigned int u1,u2,u3; \
+       LOAD_DATA(R,S,u,t,E0,E1,u1); \
+       u>>=2L; \
+       t=ROTATE(t,6); \
+       u2=(int)u>>8L; \
+       u1=(int)u&0x3f; \
+       u2&=0x3f; \
+       u>>=16L; \
+       LL^=DES_SPtrans0[u1]; \
+       LL^=DES_SPtrans2[u2]; \
+       u3=(int)u>>8L; \
+       u1=(int)u&0x3f; \
+       u3&=0x3f; \
+       LL^=DES_SPtrans4[u1]; \
+       LL^=DES_SPtrans6[u3]; \
+       u2=(int)t>>8L; \
+       u1=(int)t&0x3f; \
+       u2&=0x3f; \
+       t>>=16L; \
+       LL^=DES_SPtrans1[u1]; \
+       LL^=DES_SPtrans3[u2]; \
+       u3=(int)t>>8L; \
+       u1=(int)t&0x3f; \
+       u3&=0x3f; \
+       LL^=DES_SPtrans5[u1]; \
+       LL^=DES_SPtrans7[u3]; }
+#endif
+#ifdef DES_RISC2
+#define D_ENCRYPT(LL,R,S) {\
+       unsigned int u1,u2,s1,s2; \
+       LOAD_DATA(R,S,u,t,E0,E1,u1); \
+       u>>=2L; \
+       t=ROTATE(t,6); \
+       u2=(int)u>>8L; \
+       u1=(int)u&0x3f; \
+       u2&=0x3f; \
+       LL^=DES_SPtrans0[u1]; \
+       LL^=DES_SPtrans2[u2]; \
+       s1=(int)u>>16L; \
+       s2=(int)u>>24L; \
+       s1&=0x3f; \
+       s2&=0x3f; \
+       LL^=DES_SPtrans4[s1]; \
+       LL^=DES_SPtrans6[s2]; \
+       u2=(int)t>>8L; \
+       u1=(int)t&0x3f; \
+       u2&=0x3f; \
+       LL^=DES_SPtrans1[u1]; \
+       LL^=DES_SPtrans3[u2]; \
+       s1=(int)t>>16; \
+       s2=(int)t>>24L; \
+       s1&=0x3f; \
+       s2&=0x3f; \
+       LL^=DES_SPtrans5[s1]; \
+       LL^=DES_SPtrans7[s2]; }
+#endif
+
+#else
+
+#define D_ENCRYPT(LL,R,S) {\
+       LOAD_DATA_tmp(R,S,u,t,E0,E1); \
+       t=ROTATE(t,4); \
+       LL^=\
+               DES_SPtrans0[(u>> 2L)&0x3f]^ \
+               DES_SPtrans2[(u>>10L)&0x3f]^ \
+               DES_SPtrans4[(u>>18L)&0x3f]^ \
+               DES_SPtrans6[(u>>26L)&0x3f]^ \
+               DES_SPtrans1[(t>> 2L)&0x3f]^ \
+               DES_SPtrans3[(t>>10L)&0x3f]^ \
+               DES_SPtrans5[(t>>18L)&0x3f]^ \
+               DES_SPtrans7[(t>>26L)&0x3f]; }
+#endif
+#endif
+
+       /* IP and FP
+        * The problem is more of a geometric problem that random bit fiddling.
+        0  1  2  3  4  5  6  7      62 54 46 38 30 22 14  6
+        8  9 10 11 12 13 14 15      60 52 44 36 28 20 12  4
+       16 17 18 19 20 21 22 23      58 50 42 34 26 18 10  2
+       24 25 26 27 28 29 30 31  to  56 48 40 32 24 16  8  0
+
+       32 33 34 35 36 37 38 39      63 55 47 39 31 23 15  7
+       40 41 42 43 44 45 46 47      61 53 45 37 29 21 13  5
+       48 49 50 51 52 53 54 55      59 51 43 35 27 19 11  3
+       56 57 58 59 60 61 62 63      57 49 41 33 25 17  9  1
+
+       The output has been subject to swaps of the form
+       0 1 -> 3 1 but the odd and even bits have been put into
+       2 3    2 0
+       different words.  The main trick is to remember that
+       t=((l>>size)^r)&(mask);
+       r^=t;
+       l^=(t<<size);
+       can be used to swap and move bits between words.
+
+       So l =  0  1  2  3  r = 16 17 18 19
+               4  5  6  7      20 21 22 23
+               8  9 10 11      24 25 26 27
+              12 13 14 15      28 29 30 31
+       becomes (for size == 2 and mask == 0x3333)
+          t =   2^16  3^17 -- --   l =  0  1 16 17  r =  2  3 18 19
+                6^20  7^21 -- --        4  5 20 21       6  7 22 23
+               10^24 11^25 -- --        8  9 24 25      10 11 24 25
+               14^28 15^29 -- --       12 13 28 29      14 15 28 29
+
+       Thanks for hints from Richard Outerbridge - he told me IP&FP
+       could be done in 15 xor, 10 shifts and 5 ands.
+       When I finally started to think of the problem in 2D
+       I first got ~42 operations without xors.  When I remembered
+       how to use xors :-) I got it to its final state.
+       */
+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+       (b)^=(t),\
+       (a)^=((t)<<(n)))
+
+#define IP(l,r) \
+       { \
+       register DES_LONG tt; \
+       PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
+       PERM_OP(l,r,tt,16,0x0000ffffL); \
+       PERM_OP(r,l,tt, 2,0x33333333L); \
+       PERM_OP(l,r,tt, 8,0x00ff00ffL); \
+       PERM_OP(r,l,tt, 1,0x55555555L); \
+       }
+
+#define FP(l,r) \
+       { \
+       register DES_LONG tt; \
+       PERM_OP(l,r,tt, 1,0x55555555L); \
+       PERM_OP(r,l,tt, 8,0x00ff00ffL); \
+       PERM_OP(l,r,tt, 2,0x33333333L); \
+       PERM_OP(r,l,tt,16,0x0000ffffL); \
+       PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
+       }
+
+void des_lock_tables(void) DES_SEGMENT;
+void des_unlock_tables(void) DES_SEGMENT;
+
+OPENSSL_EXTERN DES_LONG *DES_SPtrans0;
+OPENSSL_EXTERN DES_LONG *DES_SPtrans1;
+OPENSSL_EXTERN DES_LONG *DES_SPtrans2;
+OPENSSL_EXTERN DES_LONG *DES_SPtrans3;
+OPENSSL_EXTERN DES_LONG *DES_SPtrans4;
+OPENSSL_EXTERN DES_LONG *DES_SPtrans5;
+OPENSSL_EXTERN DES_LONG *DES_SPtrans6;
+OPENSSL_EXTERN DES_LONG *DES_SPtrans7;
+
+void fcrypt_body(DES_LONG *out,DES_key_schedule *ks,
+                DES_LONG Eswap0, DES_LONG Eswap1) DES_SEGMENT;
+#endif
diff --git a/crypto/openssl/des/des_tables.c b/crypto/openssl/des/des_tables.c
new file mode 100644 (file)
index 0000000..90ebacc
--- /dev/null
@@ -0,0 +1,135 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "cryptlib.h"
+#include "cryptorsrc.h"
+#include "des.h"
+#include "des_locl.h"
+#include "assert.h"
+
+
+static MemHandle DES_SPtrans0_h = NULL;
+static MemHandle DES_SPtrans1_h = NULL;
+static MemHandle DES_SPtrans2_h = NULL;
+static MemHandle DES_SPtrans3_h = NULL;
+static MemHandle DES_SPtrans4_h = NULL;
+static MemHandle DES_SPtrans5_h = NULL;
+static MemHandle DES_SPtrans6_h = NULL;
+static MemHandle DES_SPtrans7_h = NULL;
+
+DES_LONG *DES_SPtrans0 = NULL;
+DES_LONG *DES_SPtrans1 = NULL;
+DES_LONG *DES_SPtrans2 = NULL;
+DES_LONG *DES_SPtrans3 = NULL;
+DES_LONG *DES_SPtrans4 = NULL;
+DES_LONG *DES_SPtrans5 = NULL;
+DES_LONG *DES_SPtrans6 = NULL;
+DES_LONG *DES_SPtrans7 = NULL;
+
+static int des_tables_inited = 0;
+
+static void des_init_tables(void) DES_SEGMENT;
+static void des_init_tables(void)
+{
+    if (des_tables_inited) return;
+    
+    // fixme error handling
+    DES_SPtrans0_h = DmGetResource('DLST', DES_SPtrans0_id);
+    DES_SPtrans1_h = DmGetResource('DLST', DES_SPtrans1_id);
+    DES_SPtrans2_h = DmGetResource('DLST', DES_SPtrans2_id);
+    DES_SPtrans3_h = DmGetResource('DLST', DES_SPtrans3_id);
+    DES_SPtrans4_h = DmGetResource('DLST', DES_SPtrans4_id);
+    DES_SPtrans5_h = DmGetResource('DLST', DES_SPtrans5_id);
+    DES_SPtrans6_h = DmGetResource('DLST', DES_SPtrans6_id);
+    DES_SPtrans7_h = DmGetResource('DLST', DES_SPtrans7_id);
+
+    des_tables_inited = 1;
+}
+
+
+void des_lock_tables(void)
+{
+    // fixme lock-once version
+
+    if (des_tables_inited) return;
+
+    des_init_tables();
+
+    DES_SPtrans0 = MemHandleLock(DES_SPtrans0_h);
+    DES_SPtrans1 = MemHandleLock(DES_SPtrans1_h);
+    DES_SPtrans2 = MemHandleLock(DES_SPtrans2_h);
+    DES_SPtrans3 = MemHandleLock(DES_SPtrans3_h);
+    DES_SPtrans4 = MemHandleLock(DES_SPtrans4_h);
+    DES_SPtrans5 = MemHandleLock(DES_SPtrans5_h);
+    DES_SPtrans6 = MemHandleLock(DES_SPtrans6_h);
+    DES_SPtrans7 = MemHandleLock(DES_SPtrans7_h);
+
+    // DLST resource is prefixed with 4-byte word count
+    // DES table should be 0x40 words long, plus the count word
+
+    // verify handle sizes
+    assert(MemHandleSize(DES_SPtrans0_h) == 4*(1+0x40));
+    assert(MemHandleSize(DES_SPtrans1_h) == 4*(1+0x40));
+    assert(MemHandleSize(DES_SPtrans2_h) == 4*(1+0x40));
+    assert(MemHandleSize(DES_SPtrans3_h) == 4*(1+0x40));
+    assert(MemHandleSize(DES_SPtrans4_h) == 4*(1+0x40));
+    assert(MemHandleSize(DES_SPtrans5_h) == 4*(1+0x40));
+    assert(MemHandleSize(DES_SPtrans6_h) == 4*(1+0x40));
+    assert(MemHandleSize(DES_SPtrans7_h) == 4*(1+0x40));
+
+    // verify word counts
+    assert(DES_SPtrans0[0] == 0x40);
+    assert(DES_SPtrans1[0] == 0x40);
+    assert(DES_SPtrans2[0] == 0x40);
+    assert(DES_SPtrans3[0] == 0x40);
+    assert(DES_SPtrans4[0] == 0x40);
+    assert(DES_SPtrans5[0] == 0x40);
+    assert(DES_SPtrans6[0] == 0x40);
+    assert(DES_SPtrans7[0] == 0x40);
+
+    // skip word count
+    DES_SPtrans0 += 1;
+    DES_SPtrans1 += 1;
+    DES_SPtrans2 += 1;
+    DES_SPtrans3 += 1;
+    DES_SPtrans4 += 1;
+    DES_SPtrans5 += 1;
+    DES_SPtrans6 += 1;
+    DES_SPtrans7 += 1;
+}
+
+
+void des_unlock_tables(void)
+{
+    // fixme lock-once version
+    return;
+    MemHandleUnlock(DES_SPtrans0_h); DES_SPtrans0 = NULL;
+    MemHandleUnlock(DES_SPtrans1_h); DES_SPtrans1 = NULL;
+    MemHandleUnlock(DES_SPtrans2_h); DES_SPtrans2 = NULL;
+    MemHandleUnlock(DES_SPtrans3_h); DES_SPtrans3 = NULL;
+    MemHandleUnlock(DES_SPtrans4_h); DES_SPtrans4 = NULL;
+    MemHandleUnlock(DES_SPtrans5_h); DES_SPtrans5 = NULL;
+    MemHandleUnlock(DES_SPtrans6_h); DES_SPtrans6 = NULL;
+    MemHandleUnlock(DES_SPtrans7_h); DES_SPtrans7 = NULL;
+}
diff --git a/crypto/openssl/des/des_tables.rcp b/crypto/openssl/des/des_tables.rcp
new file mode 100644 (file)
index 0000000..2fe6411
--- /dev/null
@@ -0,0 +1,242 @@
+/* crypto/des/spr.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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "cryptorsrc.h"
+
+LONGWORDLIST ID DES_SPtrans0_id
+BEGIN
+0x02080800LU 0x00080000LU 0x02000002LU 0x02080802LU
+0x02000000LU 0x00080802LU 0x00080002LU 0x02000002LU
+0x00080802LU 0x02080800LU 0x02080000LU 0x00000802LU
+0x02000802LU 0x02000000LU 0x00000000LU 0x00080002LU
+0x00080000LU 0x00000002LU 0x02000800LU 0x00080800LU
+0x02080802LU 0x02080000LU 0x00000802LU 0x02000800LU
+0x00000002LU 0x00000800LU 0x00080800LU 0x02080002LU
+0x00000800LU 0x02000802LU 0x02080002LU 0x00000000LU
+0x00000000LU 0x02080802LU 0x02000800LU 0x00080002LU
+0x02080800LU 0x00080000LU 0x00000802LU 0x02000800LU
+0x02080002LU 0x00000800LU 0x00080800LU 0x02000002LU
+0x00080802LU 0x00000002LU 0x02000002LU 0x02080000LU
+0x02080802LU 0x00080800LU 0x02080000LU 0x02000802LU
+0x02000000LU 0x00000802LU 0x00080002LU 0x00000000LU
+0x00080000LU 0x02000000LU 0x02000802LU 0x02080800LU
+0x00000002LU 0x02080002LU 0x00000800LU 0x00080802LU
+END
+
+LONGWORDLIST ID DES_SPtrans1_id
+BEGIN
+0x40108010LU 0x00000000LU 0x00108000LU 0x40100000LU
+0x40000010LU 0x00008010LU 0x40008000LU 0x00108000LU
+0x00008000LU 0x40100010LU 0x00000010LU 0x40008000LU
+0x00100010LU 0x40108000LU 0x40100000LU 0x00000010LU
+0x00100000LU 0x40008010LU 0x40100010LU 0x00008000LU
+0x00108010LU 0x40000000LU 0x00000000LU 0x00100010LU
+0x40008010LU 0x00108010LU 0x40108000LU 0x40000010LU
+0x40000000LU 0x00100000LU 0x00008010LU 0x40108010LU
+0x00100010LU 0x40108000LU 0x40008000LU 0x00108010LU
+0x40108010LU 0x00100010LU 0x40000010LU 0x00000000LU
+0x40000000LU 0x00008010LU 0x00100000LU 0x40100010LU
+0x00008000LU 0x40000000LU 0x00108010LU 0x40008010LU
+0x40108000LU 0x00008000LU 0x00000000LU 0x40000010LU
+0x00000010LU 0x40108010LU 0x00108000LU 0x40100000LU
+0x40100010LU 0x00100000LU 0x00008010LU 0x40008000LU
+0x40008010LU 0x00000010LU 0x40100000LU 0x00108000LU
+END
+
+LONGWORDLIST ID DES_SPtrans2_id
+BEGIN
+0x04000001LU 0x04040100LU 0x00000100LU 0x04000101LU
+0x00040001LU 0x04000000LU 0x04000101LU 0x00040100LU
+0x04000100LU 0x00040000LU 0x04040000LU 0x00000001LU
+0x04040101LU 0x00000101LU 0x00000001LU 0x04040001LU
+0x00000000LU 0x00040001LU 0x04040100LU 0x00000100LU
+0x00000101LU 0x04040101LU 0x00040000LU 0x04000001LU
+0x04040001LU 0x04000100LU 0x00040101LU 0x04040000LU
+0x00040100LU 0x00000000LU 0x04000000LU 0x00040101LU
+0x04040100LU 0x00000100LU 0x00000001LU 0x00040000LU
+0x00000101LU 0x00040001LU 0x04040000LU 0x04000101LU
+0x00000000LU 0x04040100LU 0x00040100LU 0x04040001LU
+0x00040001LU 0x04000000LU 0x04040101LU 0x00000001LU
+0x00040101LU 0x04000001LU 0x04000000LU 0x04040101LU
+0x00040000LU 0x04000100LU 0x04000101LU 0x00040100LU
+0x04000100LU 0x00000000LU 0x04040001LU 0x00000101LU
+0x04000001LU 0x00040101LU 0x00000100LU 0x04040000LU
+END
+
+LONGWORDLIST ID DES_SPtrans3_id
+BEGIN
+0x00401008LU 0x10001000LU 0x00000008LU 0x10401008LU
+0x00000000LU 0x10400000LU 0x10001008LU 0x00400008LU
+0x10401000LU 0x10000008LU 0x10000000LU 0x00001008LU
+0x10000008LU 0x00401008LU 0x00400000LU 0x10000000LU
+0x10400008LU 0x00401000LU 0x00001000LU 0x00000008LU
+0x00401000LU 0x10001008LU 0x10400000LU 0x00001000LU
+0x00001008LU 0x00000000LU 0x00400008LU 0x10401000LU
+0x10001000LU 0x10400008LU 0x10401008LU 0x00400000LU
+0x10400008LU 0x00001008LU 0x00400000LU 0x10000008LU
+0x00401000LU 0x10001000LU 0x00000008LU 0x10400000LU
+0x10001008LU 0x00000000LU 0x00001000LU 0x00400008LU
+0x00000000LU 0x10400008LU 0x10401000LU 0x00001000LU
+0x10000000LU 0x10401008LU 0x00401008LU 0x00400000LU
+0x10401008LU 0x00000008LU 0x10001000LU 0x00401008LU
+0x00400008LU 0x00401000LU 0x10400000LU 0x10001008LU
+0x00001008LU 0x10000000LU 0x10000008LU 0x10401000LU
+END
+
+LONGWORDLIST ID DES_SPtrans4_id 
+BEGIN
+0x08000000LU 0x00010000LU 0x00000400LU 0x08010420LU
+0x08010020LU 0x08000400LU 0x00010420LU 0x08010000LU
+0x00010000LU 0x00000020LU 0x08000020LU 0x00010400LU
+0x08000420LU 0x08010020LU 0x08010400LU 0x00000000LU
+0x00010400LU 0x08000000LU 0x00010020LU 0x00000420LU
+0x08000400LU 0x00010420LU 0x00000000LU 0x08000020LU
+0x00000020LU 0x08000420LU 0x08010420LU 0x00010020LU
+0x08010000LU 0x00000400LU 0x00000420LU 0x08010400LU
+0x08010400LU 0x08000420LU 0x00010020LU 0x08010000LU
+0x00010000LU 0x00000020LU 0x08000020LU 0x08000400LU
+0x08000000LU 0x00010400LU 0x08010420LU 0x00000000LU
+0x00010420LU 0x08000000LU 0x00000400LU 0x00010020LU
+0x08000420LU 0x00000400LU 0x00000000LU 0x08010420LU
+0x08010020LU 0x08010400LU 0x00000420LU 0x00010000LU
+0x00010400LU 0x08010020LU 0x08000400LU 0x00000420LU
+0x00000020LU 0x00010420LU 0x08010000LU 0x08000020LU
+END
+
+LONGWORDLIST ID DES_SPtrans5_id
+BEGIN
+0x80000040LU 0x00200040LU 0x00000000LU 0x80202000LU
+0x00200040LU 0x00002000LU 0x80002040LU 0x00200000LU
+0x00002040LU 0x80202040LU 0x00202000LU 0x80000000LU
+0x80002000LU 0x80000040LU 0x80200000LU 0x00202040LU
+0x00200000LU 0x80002040LU 0x80200040LU 0x00000000LU
+0x00002000LU 0x00000040LU 0x80202000LU 0x80200040LU
+0x80202040LU 0x80200000LU 0x80000000LU 0x00002040LU
+0x00000040LU 0x00202000LU 0x00202040LU 0x80002000LU
+0x00002040LU 0x80000000LU 0x80002000LU 0x00202040LU
+0x80202000LU 0x00200040LU 0x00000000LU 0x80002000LU
+0x80000000LU 0x00002000LU 0x80200040LU 0x00200000LU
+0x00200040LU 0x80202040LU 0x00202000LU 0x00000040LU
+0x80202040LU 0x00202000LU 0x00200000LU 0x80002040LU
+0x80000040LU 0x80200000LU 0x00202040LU 0x00000000LU
+0x00002000LU 0x80000040LU 0x80002040LU 0x80202000LU
+0x80200000LU 0x00002040LU 0x00000040LU 0x80200040LU
+END
+
+LONGWORDLIST ID DES_SPtrans6_id
+BEGIN
+0x00004000LU 0x00000200LU 0x01000200LU 0x01000004LU
+0x01004204LU 0x00004004LU 0x00004200LU 0x00000000LU
+0x01000000LU 0x01000204LU 0x00000204LU 0x01004000LU
+0x00000004LU 0x01004200LU 0x01004000LU 0x00000204LU
+0x01000204LU 0x00004000LU 0x00004004LU 0x01004204LU
+0x00000000LU 0x01000200LU 0x01000004LU 0x00004200LU
+0x01004004LU 0x00004204LU 0x01004200LU 0x00000004LU
+0x00004204LU 0x01004004LU 0x00000200LU 0x01000000LU
+0x00004204LU 0x01004000LU 0x01004004LU 0x00000204LU
+0x00004000LU 0x00000200LU 0x01000000LU 0x01004004LU
+0x01000204LU 0x00004204LU 0x00004200LU 0x00000000LU
+0x00000200LU 0x01000004LU 0x00000004LU 0x01000200LU
+0x00000000LU 0x01000204LU 0x01000200LU 0x00004200LU
+0x00000204LU 0x00004000LU 0x01004204LU 0x01000000LU
+0x01004200LU 0x00000004LU 0x00004004LU 0x01004204LU
+0x01000004LU 0x01004200LU 0x01004000LU 0x00004004LU
+END
+
+LONGWORDLIST ID DES_SPtrans7_id
+BEGIN
+0x20800080LU 0x20820000LU 0x00020080LU 0x00000000LU
+0x20020000LU 0x00800080LU 0x20800000LU 0x20820080LU
+0x00000080LU 0x20000000LU 0x00820000LU 0x00020080LU
+0x00820080LU 0x20020080LU 0x20000080LU 0x20800000LU
+0x00020000LU 0x00820080LU 0x00800080LU 0x20020000LU
+0x20820080LU 0x20000080LU 0x00000000LU 0x00820000LU
+0x20000000LU 0x00800000LU 0x20020080LU 0x20800080LU
+0x00800000LU 0x00020000LU 0x20820000LU 0x00000080LU
+0x00800000LU 0x00020000LU 0x20000080LU 0x20820080LU
+0x00020080LU 0x20000000LU 0x00000000LU 0x00820000LU
+0x20800080LU 0x20020080LU 0x20020000LU 0x00800080LU
+0x20820000LU 0x00000080LU 0x00800080LU 0x20020000LU
+0x20820080LU 0x00800000LU 0x20800000LU 0x20000080LU
+0x00820000LU 0x00020080LU 0x20020080LU 0x20800000LU
+0x00000080LU 0x20820000LU 0x00820080LU 0x00000000LU
+0x20000000LU 0x20800080LU 0x00020000LU 0x00820080LU
+END
diff --git a/crypto/openssl/des/ncbc_enc.c b/crypto/openssl/des/ncbc_enc.c
new file mode 100644 (file)
index 0000000..fda23d5
--- /dev/null
@@ -0,0 +1,148 @@
+/* crypto/des/ncbc_enc.c */
+/*
+ * #included by:
+ *    cbc_enc.c  (DES_cbc_encrypt)
+ *    des_enc.c  (DES_ncbc_encrypt)
+ */
+/* 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 "des_locl.h"
+
+#ifdef CBC_ENC_C__DONT_UPDATE_IV
+void DES_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+                    DES_key_schedule *_schedule, DES_cblock *ivec, int enc)
+#else
+void DES_ncbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+                    DES_key_schedule *_schedule, DES_cblock *ivec, int enc)
+#endif
+       {
+       register DES_LONG tin0,tin1;
+       register DES_LONG tout0,tout1,xor0,xor1;
+       register long l=length;
+       DES_LONG tin[2];
+       unsigned char *iv;
+
+       iv = &(*ivec)[0];
+
+       if (enc)
+               {
+               c2l(iv,tout0);
+               c2l(iv,tout1);
+               for (l-=8; l>=0; l-=8)
+                       {
+                       c2l(in,tin0);
+                       c2l(in,tin1);
+                       tin0^=tout0; tin[0]=tin0;
+                       tin1^=tout1; tin[1]=tin1;
+                       DES_encrypt1((DES_LONG *)tin,_schedule,DES_ENCRYPT);
+                       tout0=tin[0]; l2c(tout0,out);
+                       tout1=tin[1]; l2c(tout1,out);
+                       }
+               if (l != -8)
+                       {
+                       c2ln(in,tin0,tin1,l+8);
+                       tin0^=tout0; tin[0]=tin0;
+                       tin1^=tout1; tin[1]=tin1;
+                       DES_encrypt1((DES_LONG *)tin,_schedule,DES_ENCRYPT);
+                       tout0=tin[0]; l2c(tout0,out);
+                       tout1=tin[1]; l2c(tout1,out);
+                       }
+#ifndef CBC_ENC_C__DONT_UPDATE_IV
+               iv = &(*ivec)[0];
+               l2c(tout0,iv);
+               l2c(tout1,iv);
+#endif
+               }
+       else
+               {
+               c2l(iv,xor0);
+               c2l(iv,xor1);
+               for (l-=8; l>=0; l-=8)
+                       {
+                       c2l(in,tin0); tin[0]=tin0;
+                       c2l(in,tin1); tin[1]=tin1;
+                       DES_encrypt1((DES_LONG *)tin,_schedule,DES_DECRYPT);
+                       tout0=tin[0]^xor0;
+                       tout1=tin[1]^xor1;
+                       l2c(tout0,out);
+                       l2c(tout1,out);
+                       xor0=tin0;
+                       xor1=tin1;
+                       }
+               if (l != -8)
+                       {
+                       c2l(in,tin0); tin[0]=tin0;
+                       c2l(in,tin1); tin[1]=tin1;
+                       DES_encrypt1((DES_LONG *)tin,_schedule,DES_DECRYPT);
+                       tout0=tin[0]^xor0;
+                       tout1=tin[1]^xor1;
+                       l2cn(tout0,tout1,out,l+8);
+#ifndef CBC_ENC_C__DONT_UPDATE_IV
+                       xor0=tin0;
+                       xor1=tin1;
+#endif
+                       }
+#ifndef CBC_ENC_C__DONT_UPDATE_IV 
+               iv = &(*ivec)[0];
+               l2c(xor0,iv);
+               l2c(xor1,iv);
+#endif
+               }
+       tin0=tin1=tout0=tout1=xor0=xor1=0;
+       tin[0]=tin[1]=0;
+       }
diff --git a/crypto/openssl/des/set_key.c b/crypto/openssl/des/set_key.c
new file mode 100644 (file)
index 0000000..ec490a8
--- /dev/null
@@ -0,0 +1,435 @@
+/* crypto/des/set_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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// moved local static variable `shifts2` to file-scope static variable 
+//     `DES_shifts2` to avoid initialization trouble
+
+/* set_key.c v 1.4 eay 24/9/91
+ * 1.4 Speed up by 400% :-)
+ * 1.3 added register declarations.
+ * 1.2 unrolled make_key_sched a bit more
+ * 1.1 added norm_expand_bits
+ * 1.0 First working version
+ */
+#include "des_locl.h"
+
+OPENSSL_IMPLEMENT_GLOBAL(int,DES_check_key);   /* defaults to false */
+
+static const unsigned char odd_parity[256]={
+  1,  1,  2,  2,  4,  4,  7,  7,  8,  8, 11, 11, 13, 13, 14, 14,
+ 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
+ 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
+ 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
+ 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
+ 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
+ 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
+112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
+128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
+145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
+161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
+176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
+193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
+208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
+224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
+241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
+
+void DES_set_odd_parity(DES_cblock *key)
+       {
+       unsigned int i;
+
+       for (i=0; i<DES_KEY_SZ; i++)
+               (*key)[i]=odd_parity[(*key)[i]];
+       }
+
+int DES_check_key_parity(const_DES_cblock *key)
+       {
+       unsigned int i;
+
+       for (i=0; i<DES_KEY_SZ; i++)
+               {
+               if ((*key)[i] != odd_parity[(*key)[i]])
+                       return(0);
+               }
+       return(1);
+       }
+
+/* Weak and semi week keys as take from
+ * %A D.W. Davies
+ * %A W.L. Price
+ * %T Security for Computer Networks
+ * %I John Wiley & Sons
+ * %D 1984
+ * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
+ * (and actual cblock values).
+ */
+#define NUM_WEAK_KEY   16
+static DES_cblock weak_keys[NUM_WEAK_KEY]={
+       /* weak keys */
+       {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
+       {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
+       {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
+       {0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1},
+       /* semi-weak keys */
+       {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},
+       {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
+       {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
+       {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
+       {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
+       {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
+       {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
+       {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
+       {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
+       {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
+       {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
+       {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};
+
+int DES_is_weak_key(const_DES_cblock *key)
+       {
+       int i;
+
+       for (i=0; i<NUM_WEAK_KEY; i++)
+               /* Added == 0 to comparison, I obviously don't run
+                * this section very often :-(, thanks to
+                * engineering@MorningStar.Com for the fix
+                * eay 93/06/29
+                * Another problem, I was comparing only the first 4
+                * bytes, 97/03/18 */
+               if (memcmp(weak_keys[i],key,sizeof(DES_cblock)) == 0) return(1);
+       return(0);
+       }
+
+/* NOW DEFINED IN des_local.h
+ * See ecb_encrypt.c for a pseudo description of these macros. 
+ * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+ *     (b)^=(t),\
+ *     (a)=((a)^((t)<<(n))))
+ */
+
+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
+       (a)=(a)^(t)^(t>>(16-(n))))
+
+static const DES_LONG des_skb[8][64]={
+       {
+       /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+       0x00000000L,0x00000010L,0x20000000L,0x20000010L,
+       0x00010000L,0x00010010L,0x20010000L,0x20010010L,
+       0x00000800L,0x00000810L,0x20000800L,0x20000810L,
+       0x00010800L,0x00010810L,0x20010800L,0x20010810L,
+       0x00000020L,0x00000030L,0x20000020L,0x20000030L,
+       0x00010020L,0x00010030L,0x20010020L,0x20010030L,
+       0x00000820L,0x00000830L,0x20000820L,0x20000830L,
+       0x00010820L,0x00010830L,0x20010820L,0x20010830L,
+       0x00080000L,0x00080010L,0x20080000L,0x20080010L,
+       0x00090000L,0x00090010L,0x20090000L,0x20090010L,
+       0x00080800L,0x00080810L,0x20080800L,0x20080810L,
+       0x00090800L,0x00090810L,0x20090800L,0x20090810L,
+       0x00080020L,0x00080030L,0x20080020L,0x20080030L,
+       0x00090020L,0x00090030L,0x20090020L,0x20090030L,
+       0x00080820L,0x00080830L,0x20080820L,0x20080830L,
+       0x00090820L,0x00090830L,0x20090820L,0x20090830L,
+       },{
+       /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
+       0x00000000L,0x02000000L,0x00002000L,0x02002000L,
+       0x00200000L,0x02200000L,0x00202000L,0x02202000L,
+       0x00000004L,0x02000004L,0x00002004L,0x02002004L,
+       0x00200004L,0x02200004L,0x00202004L,0x02202004L,
+       0x00000400L,0x02000400L,0x00002400L,0x02002400L,
+       0x00200400L,0x02200400L,0x00202400L,0x02202400L,
+       0x00000404L,0x02000404L,0x00002404L,0x02002404L,
+       0x00200404L,0x02200404L,0x00202404L,0x02202404L,
+       0x10000000L,0x12000000L,0x10002000L,0x12002000L,
+       0x10200000L,0x12200000L,0x10202000L,0x12202000L,
+       0x10000004L,0x12000004L,0x10002004L,0x12002004L,
+       0x10200004L,0x12200004L,0x10202004L,0x12202004L,
+       0x10000400L,0x12000400L,0x10002400L,0x12002400L,
+       0x10200400L,0x12200400L,0x10202400L,0x12202400L,
+       0x10000404L,0x12000404L,0x10002404L,0x12002404L,
+       0x10200404L,0x12200404L,0x10202404L,0x12202404L,
+       },{
+       /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
+       0x00000000L,0x00000001L,0x00040000L,0x00040001L,
+       0x01000000L,0x01000001L,0x01040000L,0x01040001L,
+       0x00000002L,0x00000003L,0x00040002L,0x00040003L,
+       0x01000002L,0x01000003L,0x01040002L,0x01040003L,
+       0x00000200L,0x00000201L,0x00040200L,0x00040201L,
+       0x01000200L,0x01000201L,0x01040200L,0x01040201L,
+       0x00000202L,0x00000203L,0x00040202L,0x00040203L,
+       0x01000202L,0x01000203L,0x01040202L,0x01040203L,
+       0x08000000L,0x08000001L,0x08040000L,0x08040001L,
+       0x09000000L,0x09000001L,0x09040000L,0x09040001L,
+       0x08000002L,0x08000003L,0x08040002L,0x08040003L,
+       0x09000002L,0x09000003L,0x09040002L,0x09040003L,
+       0x08000200L,0x08000201L,0x08040200L,0x08040201L,
+       0x09000200L,0x09000201L,0x09040200L,0x09040201L,
+       0x08000202L,0x08000203L,0x08040202L,0x08040203L,
+       0x09000202L,0x09000203L,0x09040202L,0x09040203L,
+       },{
+       /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
+       0x00000000L,0x00100000L,0x00000100L,0x00100100L,
+       0x00000008L,0x00100008L,0x00000108L,0x00100108L,
+       0x00001000L,0x00101000L,0x00001100L,0x00101100L,
+       0x00001008L,0x00101008L,0x00001108L,0x00101108L,
+       0x04000000L,0x04100000L,0x04000100L,0x04100100L,
+       0x04000008L,0x04100008L,0x04000108L,0x04100108L,
+       0x04001000L,0x04101000L,0x04001100L,0x04101100L,
+       0x04001008L,0x04101008L,0x04001108L,0x04101108L,
+       0x00020000L,0x00120000L,0x00020100L,0x00120100L,
+       0x00020008L,0x00120008L,0x00020108L,0x00120108L,
+       0x00021000L,0x00121000L,0x00021100L,0x00121100L,
+       0x00021008L,0x00121008L,0x00021108L,0x00121108L,
+       0x04020000L,0x04120000L,0x04020100L,0x04120100L,
+       0x04020008L,0x04120008L,0x04020108L,0x04120108L,
+       0x04021000L,0x04121000L,0x04021100L,0x04121100L,
+       0x04021008L,0x04121008L,0x04021108L,0x04121108L,
+       },{
+       /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+       0x00000000L,0x10000000L,0x00010000L,0x10010000L,
+       0x00000004L,0x10000004L,0x00010004L,0x10010004L,
+       0x20000000L,0x30000000L,0x20010000L,0x30010000L,
+       0x20000004L,0x30000004L,0x20010004L,0x30010004L,
+       0x00100000L,0x10100000L,0x00110000L,0x10110000L,
+       0x00100004L,0x10100004L,0x00110004L,0x10110004L,
+       0x20100000L,0x30100000L,0x20110000L,0x30110000L,
+       0x20100004L,0x30100004L,0x20110004L,0x30110004L,
+       0x00001000L,0x10001000L,0x00011000L,0x10011000L,
+       0x00001004L,0x10001004L,0x00011004L,0x10011004L,
+       0x20001000L,0x30001000L,0x20011000L,0x30011000L,
+       0x20001004L,0x30001004L,0x20011004L,0x30011004L,
+       0x00101000L,0x10101000L,0x00111000L,0x10111000L,
+       0x00101004L,0x10101004L,0x00111004L,0x10111004L,
+       0x20101000L,0x30101000L,0x20111000L,0x30111000L,
+       0x20101004L,0x30101004L,0x20111004L,0x30111004L,
+       },{
+       /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
+       0x00000000L,0x08000000L,0x00000008L,0x08000008L,
+       0x00000400L,0x08000400L,0x00000408L,0x08000408L,
+       0x00020000L,0x08020000L,0x00020008L,0x08020008L,
+       0x00020400L,0x08020400L,0x00020408L,0x08020408L,
+       0x00000001L,0x08000001L,0x00000009L,0x08000009L,
+       0x00000401L,0x08000401L,0x00000409L,0x08000409L,
+       0x00020001L,0x08020001L,0x00020009L,0x08020009L,
+       0x00020401L,0x08020401L,0x00020409L,0x08020409L,
+       0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
+       0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
+       0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
+       0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
+       0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
+       0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
+       0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
+       0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
+       },{
+       /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
+       0x00000000L,0x00000100L,0x00080000L,0x00080100L,
+       0x01000000L,0x01000100L,0x01080000L,0x01080100L,
+       0x00000010L,0x00000110L,0x00080010L,0x00080110L,
+       0x01000010L,0x01000110L,0x01080010L,0x01080110L,
+       0x00200000L,0x00200100L,0x00280000L,0x00280100L,
+       0x01200000L,0x01200100L,0x01280000L,0x01280100L,
+       0x00200010L,0x00200110L,0x00280010L,0x00280110L,
+       0x01200010L,0x01200110L,0x01280010L,0x01280110L,
+       0x00000200L,0x00000300L,0x00080200L,0x00080300L,
+       0x01000200L,0x01000300L,0x01080200L,0x01080300L,
+       0x00000210L,0x00000310L,0x00080210L,0x00080310L,
+       0x01000210L,0x01000310L,0x01080210L,0x01080310L,
+       0x00200200L,0x00200300L,0x00280200L,0x00280300L,
+       0x01200200L,0x01200300L,0x01280200L,0x01280300L,
+       0x00200210L,0x00200310L,0x00280210L,0x00280310L,
+       0x01200210L,0x01200310L,0x01280210L,0x01280310L,
+       },{
+       /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
+       0x00000000L,0x04000000L,0x00040000L,0x04040000L,
+       0x00000002L,0x04000002L,0x00040002L,0x04040002L,
+       0x00002000L,0x04002000L,0x00042000L,0x04042000L,
+       0x00002002L,0x04002002L,0x00042002L,0x04042002L,
+       0x00000020L,0x04000020L,0x00040020L,0x04040020L,
+       0x00000022L,0x04000022L,0x00040022L,0x04040022L,
+       0x00002020L,0x04002020L,0x00042020L,0x04042020L,
+       0x00002022L,0x04002022L,0x00042022L,0x04042022L,
+       0x00000800L,0x04000800L,0x00040800L,0x04040800L,
+       0x00000802L,0x04000802L,0x00040802L,0x04040802L,
+       0x00002800L,0x04002800L,0x00042800L,0x04042800L,
+       0x00002802L,0x04002802L,0x00042802L,0x04042802L,
+       0x00000820L,0x04000820L,0x00040820L,0x04040820L,
+       0x00000822L,0x04000822L,0x00040822L,0x04040822L,
+       0x00002820L,0x04002820L,0x00042820L,0x04042820L,
+       0x00002822L,0x04002822L,0x00042822L,0x04042822L,
+       }};
+
+int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule)
+       {
+       if (DES_check_key)
+               {
+               return DES_set_key_checked(key, schedule);
+               }
+       else
+               {
+               DES_set_key_unchecked(key, schedule);
+               return 0;
+               }
+       }
+
+/* return 0 if key parity is odd (correct),
+ * return -1 if key parity error,
+ * return -2 if illegal weak key.
+ */
+int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule)
+       {
+       if (!DES_check_key_parity(key))
+               return(-1);
+       if (DES_is_weak_key(key))
+               return(-2);
+       DES_set_key_unchecked(key, schedule);
+       return 0;
+       }
+
+static int DES_shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
+
+void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule)
+       {
+       register DES_LONG c,d,t,s,t2;
+       register const unsigned char *in;
+       register DES_LONG *k;
+       register int i;
+
+#ifdef OPENBSD_DEV_CRYPTO
+       memcpy(schedule->key,key,sizeof schedule->key);
+       schedule->session=NULL;
+#endif
+       k = &schedule->ks->deslong[0];
+       in = &(*key)[0];
+
+       c2l(in,c);
+       c2l(in,d);
+
+       /* do PC1 in 47 simple operations :-)
+        * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
+        * for the inspiration. :-) */
+       PERM_OP (d,c,t,4,0x0f0f0f0fL);
+       HPERM_OP(c,t,-2,0xcccc0000L);
+       HPERM_OP(d,t,-2,0xcccc0000L);
+       PERM_OP (d,c,t,1,0x55555555L);
+       PERM_OP (c,d,t,8,0x00ff00ffL);
+       PERM_OP (d,c,t,1,0x55555555L);
+       d=      (((d&0x000000ffL)<<16L)| (d&0x0000ff00L)     |
+                ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
+       c&=0x0fffffffL;
+
+       for (i=0; i<ITERATIONS; i++)
+               {
+               if (DES_shifts2[i])
+                       { c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
+               else
+                       { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
+               c&=0x0fffffffL;
+               d&=0x0fffffffL;
+               /* could be a few less shifts but I am to lazy at this
+                * point in time to investigate */
+               s=      des_skb[0][ (c    )&0x3f                ]|
+                       des_skb[1][((c>> 6L)&0x03)|((c>> 7L)&0x3c)]|
+                       des_skb[2][((c>>13L)&0x0f)|((c>>14L)&0x30)]|
+                       des_skb[3][((c>>20L)&0x01)|((c>>21L)&0x06) |
+                                                 ((c>>22L)&0x38)];
+               t=      des_skb[4][ (d    )&0x3f                ]|
+                       des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
+                       des_skb[6][ (d>>15L)&0x3f                ]|
+                       des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
+
+               /* table contained 0213 4657 */
+               t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
+               *(k++)=ROTATE(t2,30)&0xffffffffL;
+
+               t2=((s>>16L)|(t&0xffff0000L));
+               *(k++)=ROTATE(t2,26)&0xffffffffL;
+               }
+       }
+
+int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule)
+       {
+       return(DES_set_key(key,schedule));
+       }
+/*
+#undef des_fixup_key_parity
+void des_fixup_key_parity(des_cblock *key)
+       {
+       des_set_odd_parity(key);
+       }
+*/
diff --git a/crypto/openssl/dh/dh.h b/crypto/openssl/dh/dh.h
new file mode 100644 (file)
index 0000000..3a2ad93
--- /dev/null
@@ -0,0 +1,224 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes 
+// removed reference counting system
+// added DH_SEGMENT everywhere
+
+#ifndef HEADER_DH_H
+#define HEADER_DH_H
+
+#ifdef OPENSSL_NO_DH
+#error DH is disabled.
+#endif
+
+#include "openssl/cryptlib.h"
+#include "openssl/bn/bn.h"
+
+#define DH_FLAG_CACHE_MONT_P   0x01
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct dh_st DH;
+
+typedef struct dh_method {
+       const char *name;
+       /* Methods here */
+       int (*generate_key)(DH *dh);
+       int (*compute_key)(unsigned char *key,const BIGNUM *pub_key,DH *dh);
+       int (*bn_mod_exp)(const DH *dh, BIGNUM *r, const BIGNUM *a,
+                               const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+                               BN_MONT_CTX *m_ctx); /* Can be null */
+
+       int (*init)(DH *dh);
+       int (*finish)(DH *dh);
+       int flags;
+       char *app_data;
+} DH_METHOD;
+
+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;
+       long length; /* optional */
+       BIGNUM *pub_key;        /* g^x */
+       BIGNUM *priv_key;       /* x */
+
+       int flags;
+       char *method_mont_p;
+       /* Place holders if we want to do X9.42 DH */
+       BIGNUM *q;
+       BIGNUM *j;
+       unsigned char *seed;
+       int seedlen;
+       BIGNUM *counter;
+
+       const DH_METHOD *meth;
+       ENGINE *engine;
+       };
+
+#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_SAFE_PRIME      0x02
+#define DH_UNABLE_TO_CHECK_GENERATOR   0x04
+#define DH_NOT_SUITABLE_GENERATOR      0x08
+
+/* primes p where (p-1)/2 is prime too are called "safe"; we define
+   this for backward compatibility: */
+#define DH_CHECK_P_NOT_STRONG_PRIME    DH_CHECK_P_NOT_SAFE_PRIME
+
+#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
+
+const DH_METHOD *DH_OpenSSL(void) DH_SEGMENT;
+
+void DH_set_default_method(const DH_METHOD *meth) DH_SEGMENT;
+const DH_METHOD *DH_get_default_method(void) DH_SEGMENT;
+int DH_set_method(DH *dh, const DH_METHOD *meth) DH_SEGMENT;
+DH *DH_new_method(ENGINE *engine) DH_SEGMENT;
+
+DH *   DH_new(void) DH_SEGMENT;
+void   DH_free(DH *dh) DH_SEGMENT;
+int    DH_size(const DH *dh) DH_SEGMENT;
+DH *   DH_generate_parameters(int prime_len,int generator,
+               void (*callback)(int,int,void *),void *cb_arg) DH_SEGMENT;
+int    DH_check(const DH *dh,int *codes) DH_SEGMENT;
+int    DH_generate_key(DH *dh) DH_SEGMENT;
+int    DH_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh) DH_SEGMENT;
+DH *   d2i_DHparams(DH **a,const unsigned char **pp, long length) DH_SEGMENT;
+int    i2d_DHparams(const DH *a,unsigned char **pp) DH_SEGMENT;
+#ifndef OPENSSL_NO_FP_API
+int    DHparams_print_fp(FILE *fp, const DH *x) DH_SEGMENT;
+#endif
+#ifndef OPENSSL_NO_BIO
+int    DHparams_print(BIO *bp, const DH *x) DH_SEGMENT;
+#else
+int    DHparams_print(char *bp, const DH *x) DH_SEGMENT;
+#endif
+
+/* 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.
+ */
+void ERR_load_DH_strings(void) DH_SEGMENT;
+
+/* 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_METHOD                              105
+
+/* Reason codes. */
+#define DH_R_BAD_GENERATOR                              101
+#define DH_R_NO_PRIVATE_VALUE                           100
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/crypto/openssl/dh/dh_key.c b/crypto/openssl/dh/dh_key.c
new file mode 100644 (file)
index 0000000..8727cb4
--- /dev/null
@@ -0,0 +1,252 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// added DH_SEGMENT everywhere
+// disabled bn_mod_exp single-word optimization for ARM compat (PSSH_NO_BN_TOP)
+
+#include "cryptlib.h"
+#include "dh.h"
+#include "bn/bn.h"
+
+#define PSSH_NO_BN_TOP
+
+static int generate_key(DH *dh) DH_SEGMENT;
+static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) DH_SEGMENT;
+static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
+                       const BIGNUM *a, const BIGNUM *p,
+                       const BIGNUM *m, BN_CTX *ctx,
+                       BN_MONT_CTX *m_ctx) DH_SEGMENT;
+static int dh_init(DH *dh) DH_SEGMENT;
+static int dh_finish(DH *dh) DH_SEGMENT;
+
+int DH_generate_key(DH *dh)
+       {
+       return dh->meth->generate_key(dh);
+       }
+
+int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
+       {
+       return dh->meth->compute_key(key, pub_key, dh);
+       }
+
+static DH_METHOD dh_ossl = {
+"OpenSSL DH Method",
+generate_key,
+compute_key,
+dh_bn_mod_exp,
+dh_init,
+dh_finish,
+0,
+NULL
+};
+
+const DH_METHOD *DH_OpenSSL(void)
+{
+       return &dh_ossl;
+}
+
+static int generate_key(DH *dh)
+       {
+       int ok=0;
+       int generate_new_key=0;
+       unsigned l;
+       BN_CTX *ctx;
+       BN_MONT_CTX *mont;
+       BIGNUM *pub_key=NULL,*priv_key=NULL;
+
+       ctx = BN_CTX_new();
+       if (ctx == NULL) goto err;
+
+       if (dh->priv_key == NULL)
+               {
+               priv_key=BN_new();
+               if (priv_key == NULL) goto err;
+               generate_new_key=1;
+               }
+       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 (generate_new_key)
+               {
+               l = dh->length ? dh->length : BN_num_bits(dh->p)-1; /* secret exponent length */
+               if (!BN_rand(priv_key, l, 0, 0)) goto err;
+               }
+       if (!dh->meth->bn_mod_exp(dh, 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);
+       }
+
+static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
+       {
+       BN_CTX *ctx;
+       BN_MONT_CTX *mont;
+       BIGNUM *tmp;
+       int ret= -1;
+
+       ctx = BN_CTX_new();
+       if (ctx == NULL) goto err;
+       BN_CTX_start(ctx);
+       tmp = BN_CTX_get(ctx);
+       
+       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 (!dh->meth->bn_mod_exp(dh, 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_end(ctx);
+       BN_CTX_free(ctx);
+       return(ret);
+       }
+
+static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
+                       const BIGNUM *a, const BIGNUM *p,
+                       const BIGNUM *m, BN_CTX *ctx,
+                       BN_MONT_CTX *m_ctx)
+       {
+#ifndef PSSH_NO_BN_TOP
+       if (a->top == 1)
+               {
+               BN_ULONG A = a->d[0];
+               return BN_mod_exp_mont_word(r,A,p,m,ctx,m_ctx);
+               }
+       else
+#endif
+               return BN_mod_exp_mont(r,a,p,m,ctx,m_ctx);
+       }
+
+
+static int dh_init(DH *dh)
+       {
+       dh->flags |= DH_FLAG_CACHE_MONT_P;
+       return(1);
+       }
+
+static int dh_finish(DH *dh)
+       {
+       if(dh->method_mont_p)
+               BN_MONT_CTX_free((BN_MONT_CTX *)dh->method_mont_p);
+       return(1);
+       }
diff --git a/crypto/openssl/dh/dh_lib.c b/crypto/openssl/dh/dh_lib.c
new file mode 100644 (file)
index 0000000..513342f
--- /dev/null
@@ -0,0 +1,223 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// removed reference counting system
+
+#include "cryptlib.h"
+#include "dh.h"
+#include "bn/bn.h"
+
+const char *DH_version="Diffie-Hellman" OPENSSL_VERSION_PTEXT;
+
+static const DH_METHOD *default_DH_method = NULL;
+
+void DH_set_default_method(const DH_METHOD *meth)
+       {
+       default_DH_method = meth;
+       }
+
+const DH_METHOD *DH_get_default_method(void)
+       {
+       if(!default_DH_method)
+               default_DH_method = DH_OpenSSL();
+       return default_DH_method;
+       }
+
+int DH_set_method(DH *dh, const DH_METHOD *meth)
+       {
+       /* NB: The caller is specifically setting a method, so it's not up to us
+        * to deal with which ENGINE it comes from. */
+        const DH_METHOD *mtmp;
+        mtmp = dh->meth;
+        if (mtmp->finish) mtmp->finish(dh);
+#ifndef OPENSSL_NO_ENGINE
+       if (dh->engine)
+               {
+               ENGINE_finish(dh->engine);
+               dh->engine = NULL;
+               }
+#endif
+        dh->meth = meth;
+        if (meth->init) meth->init(dh);
+        return 1;
+       }
+
+DH *DH_new(void)
+       {
+       return DH_new_method(NULL);
+       }
+
+DH *DH_new_method(ENGINE *engine)
+       {
+       DH *ret;
+
+       ret=(DH *)OPENSSL_malloc(sizeof(DH));
+       if (ret == NULL)
+               {
+               DHerr(DH_F_DH_NEW_METHOD,ERR_R_MALLOC_FAILURE);
+               return(NULL);
+               }
+
+       ret->meth = DH_get_default_method();
+#ifndef OPENSSL_NO_ENGINE
+       if (engine)
+               {
+               if (!ENGINE_init(engine))
+                       {
+                       DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB);
+                       OPENSSL_free(ret);
+                       return NULL;
+                       }
+               ret->engine = engine;
+               }
+       else
+               ret->engine = ENGINE_get_default_DH();
+       if(ret->engine)
+               {
+               ret->meth = ENGINE_get_DH(ret->engine);
+               if(!ret->meth)
+                       {
+                       DHerr(DH_F_DH_NEW_METHOD,ERR_R_ENGINE_LIB);
+                       ENGINE_finish(ret->engine);
+                       OPENSSL_free(ret);
+                       return NULL;
+                       }
+               }
+#endif
+
+       ret->pad=0;
+       ret->version=0;
+       ret->p=NULL;
+       ret->g=NULL;
+       ret->length=0;
+       ret->pub_key=NULL;
+       ret->priv_key=NULL;
+       ret->q=NULL;
+       ret->j=NULL;
+       ret->seed = NULL;
+       ret->seedlen = 0;
+       ret->counter = NULL;
+       ret->method_mont_p=NULL;
+
+       ret->flags=ret->meth->flags;
+
+       if ((ret->meth->init != NULL) && !ret->meth->init(ret))
+               {
+#ifndef OPENSSL_NO_ENGINE
+               if (ret->engine)
+                       ENGINE_finish(ret->engine);
+#endif
+               OPENSSL_free(ret);
+               ret=NULL;
+               }
+       return(ret);
+       }
+
+void DH_free(DH *r)
+       {
+       int i;
+       if(r == NULL) return;
+
+       if (r->meth->finish)
+               r->meth->finish(r);
+#ifndef OPENSSL_NO_ENGINE
+       if (r->engine)
+               ENGINE_finish(r->engine);
+#endif
+
+       if (r->p != NULL) BN_clear_free(r->p);
+       if (r->g != NULL) BN_clear_free(r->g);
+       if (r->q != NULL) BN_clear_free(r->q);
+       if (r->j != NULL) BN_clear_free(r->j);
+       if (r->seed) OPENSSL_free(r->seed);
+       if (r->counter != NULL) BN_clear_free(r->counter);
+       if (r->pub_key != NULL) BN_clear_free(r->pub_key);
+       if (r->priv_key != NULL) BN_clear_free(r->priv_key);
+       OPENSSL_free(r);
+       }
+
+
+int DH_size(const DH *dh)
+       {
+       return(BN_num_bytes(dh->p));
+       }
diff --git a/crypto/openssl/dsa/dsa.h b/crypto/openssl/dsa/dsa.h
new file mode 100644 (file)
index 0000000..5d4beb1
--- /dev/null
@@ -0,0 +1,160 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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 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 :-) */
+
+// GrP pssh:
+// severely cut down to support DSA signature verification and signing only
+// changed includes
+// removed some unneeded struct fields
+// removed unneeded prototypes
+
+#ifndef HEADER_DSA_H
+#define HEADER_DSA_H
+
+#include "crypto/openssl/bn/bn.h"
+
+#define DSA_FLAG_CACHE_MONT_P  0x01
+
+typedef struct dsa_st DSA;
+
+typedef struct DSA_SIG_st
+       {
+       BIGNUM *r;
+       BIGNUM *s;
+       } DSA_SIG;
+
+typedef struct dsa_method {
+       const char *name;
+       DSA_SIG * (*dsa_do_sign)(const unsigned char *dgst, int dlen, DSA *dsa);
+       int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
+                                                               BIGNUM **rp);
+       int (*dsa_do_verify)(const unsigned char *dgst, int dgst_len,
+                            DSA_SIG *sig, DSA *dsa);
+       int (*init)(DSA *dsa);
+       int (*finish)(DSA *dsa);
+       int flags;
+} DSA_METHOD;
+
+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;
+       long 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;
+       const DSA_METHOD *meth;
+       };
+
+
+DSA_SIG * DSA_SIG_new(void) DSA_SEGMENT;
+void   DSA_SIG_free(DSA_SIG *a) DSA_SEGMENT;
+int    DSA_sign_setup( DSA *dsa,BN_CTX *ctx_in,BIGNUM **kinvp,BIGNUM **rp) DSA_SEGMENT;
+int    DSA_verify(int type,const unsigned char *dgst,int dgst_len,
+               const unsigned char *sigbuf, int siglen, DSA *dsa) DSA_SEGMENT;
+DSA_SIG * DSA_do_sign(const unsigned char *dgst,int dlen,DSA *dsa) DSA_SEGMENT;
+int    DSA_do_verify(const unsigned char *dgst,int dgst_len,
+                     DSA_SIG *sig,DSA *dsa) DSA_SEGMENT;
+
+const DSA_METHOD *DSA_OpenSSL(void) DSA_SEGMENT;
+
+DSA *  DSA_new(void) DSA_SEGMENT;
+void   DSA_free (DSA *r) DSA_SEGMENT;
+
+
+#endif
diff --git a/crypto/openssl/dsa/dsa_lib.c b/crypto/openssl/dsa/dsa_lib.c
new file mode 100644 (file)
index 0000000..b35bbf9
--- /dev/null
@@ -0,0 +1,163 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
+
+// GrP pssh:
+// severely cut down to support DSA signature verification only
+// changed includes
+
+#include "cryptlib.h"
+#include "bn/bn.h"
+#include "dsa.h"
+
+const char *DSA_version="DSA" OPENSSL_VERSION_PTEXT;
+
+DSA *DSA_new(void)
+       {
+       DSA *ret;
+
+       ret=(DSA *)OPENSSL_malloc(sizeof(DSA));
+       if (ret == NULL)
+               {
+               DSAerr(DSA_F_DSA_NEW_METHOD,ERR_R_MALLOC_FAILURE);
+               return(NULL);
+               }
+       ret->meth = DSA_OpenSSL();
+
+       ret->pad=0;
+       ret->version=0;
+       ret->write_params=1;
+       ret->p=NULL;
+       ret->q=NULL;
+       ret->g=NULL;
+
+       ret->pub_key=NULL;
+       ret->priv_key=NULL;
+
+       ret->kinv=NULL;
+       ret->r=NULL;
+       ret->method_mont_p=NULL;
+
+       ret->flags=ret->meth->flags;
+
+       if ((ret->meth->init != NULL) && !ret->meth->init(ret))
+               {
+               OPENSSL_free(ret);
+               ret=NULL;
+               }
+       
+       return(ret);
+       }
+
+void DSA_free(DSA *r)
+       {
+       if (r == NULL) return;
+
+       if(r->meth->finish)
+               r->meth->finish(r);
+
+       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);
+       OPENSSL_free(r);
+       }
+
+DSA_SIG * DSA_SIG_new(void)
+{
+    DSA_SIG *ret;
+
+    ret = OPENSSL_malloc(sizeof(DSA_SIG));
+    ret->r = NULL;
+    ret->s = NULL;
+    return ret;
+}
+
+void DSA_SIG_free(DSA_SIG *a)
+{
+    if (a->r) BN_free(a->r);
+    if (a->s) BN_free(a->s);
+    OPENSSL_free(a);
+}
diff --git a/crypto/openssl/dsa/dsa_ossl.c b/crypto/openssl/dsa/dsa_ossl.c
new file mode 100644 (file)
index 0000000..fbce440
--- /dev/null
@@ -0,0 +1,354 @@
+/* crypto/dsa/dsa_ossl.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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
+
+// GrP pssh:
+// severely cut down to support DSA signature verification and signing only
+// changed includes
+// don't use stack-allocated BIGNUMs
+// use BN_is_negative(bn) instead of bn->neg
+// don't use BN_mod_exp2_mont
+
+#include "cryptlib.h"
+#include "bn/bn.h"
+#include "dsa.h"
+
+static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) DSA_SEGMENT;
+static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) DSA_SEGMENT;
+static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
+                 DSA *dsa) DSA_SEGMENT;
+static int dsa_init(DSA *dsa) DSA_SEGMENT;
+static int dsa_finish(DSA *dsa) DSA_SEGMENT;
+
+static DSA_METHOD openssl_dsa_meth = {
+"OpenSSL DSA method",
+dsa_do_sign,
+dsa_sign_setup,
+dsa_do_verify,
+dsa_init,
+dsa_finish,
+0
+};
+
+const DSA_METHOD *DSA_OpenSSL(void)
+{
+       return &openssl_dsa_meth;
+}
+static 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;
+       DSA_SIG *ret=NULL;
+
+       m = BN_new();
+       xr = BN_new();
+
+       if (!dsa->p || !dsa->q || !dsa->g)
+               {
+               DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_MISSING_PARAMETERS);
+               goto err;
+               }
+
+       s=BN_new();
+       if (s == NULL) goto bnerr;
+
+       i=BN_num_bytes(dsa->q); /* should be 20 */
+       if ((dlen > i) || (dlen > 50))
+               {
+               DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+               goto err;
+               }
+
+       ctx=BN_CTX_new();
+       if (ctx == NULL) goto bnerr;
+
+       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 bnerr;
+
+       /* Compute  s = inv(k) (m + xr) mod q */
+       if (!BN_mod_mul(xr,dsa->priv_key,r,dsa->q,ctx)) goto bnerr;/* s = xr */
+       if (!BN_add(s, xr, m)) goto bnerr;              /* 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 bnerr;
+
+       ret=DSA_SIG_new();
+       if (ret == NULL) goto err;
+       ret->r = r;
+       ret->s = s;
+
+cleanup:
+       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);
+
+bnerr:
+       DSAerr(DSA_F_DSA_DO_SIGN,ERR_R_BN_LIB);
+err:
+       BN_free(r);
+       BN_free(s);
+       goto cleanup;
+       }
+
+static 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 (!dsa->p || !dsa->q || !dsa->g)
+               {
+               DSAerr(DSA_F_DSA_SIGN_SETUP,DSA_R_MISSING_PARAMETERS);
+               return 0;
+               }
+
+       k = BN_new();
+
+       if (ctx_in == NULL)
+               {
+               if ((ctx=BN_CTX_new()) == NULL) goto err;
+               }
+       else
+               ctx=ctx_in;
+
+       if ((r=BN_new()) == NULL) goto err;
+       kinv=NULL;
+
+       /* Get random k */
+       do
+               if (!BN_rand_range(k, dsa->q)) goto err;
+       while (BN_is_zero(k));
+
+       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);
+       }
+
+static 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 (!dsa->p || !dsa->q || !dsa->g)
+               {
+               DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MISSING_PARAMETERS);
+               return -1;
+               }
+
+       u1 = BN_new();
+       u2 = BN_new();
+       t1 = BN_new();
+
+       if ((ctx=BN_CTX_new()) == NULL) goto err;
+
+       if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || BN_ucmp(sig->r, dsa->q) >= 0)
+               {
+               ret = 0;
+               goto err;
+               }
+       if (BN_is_zero(sig->s) || BN_is_negative(sig->s) || BN_ucmp(sig->s, dsa->q) >= 0)
+               {
+               ret = 0;
+               goto err;
+               }
+
+       /* 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 1
+       {
+       BIGNUM *t2;
+
+       t2 = BN_new();
+       /* 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_free(t2);
+       }
+       /* let u1 = u1 mod q */
+       if (!BN_mod(u1,u1,dsa->q,ctx)) goto err;
+#else
+       {
+       if (!dsa->meth->dsa_mod_exp(dsa, 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);
+       goto done;
+
+       err:
+       if (ret != 1) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB);
+       done:
+       if (ctx != NULL) BN_CTX_free(ctx);
+       BN_free(u1);
+       BN_free(u2);
+       BN_free(t1);
+       return(ret);
+       }
+
+static int dsa_init(DSA *dsa)
+{
+       dsa->flags|=DSA_FLAG_CACHE_MONT_P;
+       return(1);
+}
+
+static int dsa_finish(DSA *dsa)
+{
+       if(dsa->method_mont_p)
+               BN_MONT_CTX_free((BN_MONT_CTX *)dsa->method_mont_p);
+       return(1);
+}
diff --git a/crypto/openssl/dsa/dsa_sign.c b/crypto/openssl/dsa/dsa_sign.c
new file mode 100644 (file)
index 0000000..760501c
--- /dev/null
@@ -0,0 +1,101 @@
+/* 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.]
+ */
+
+/**********
+ * Portions Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
+
+// GrP pssh:
+// changed includes
+// removed DSA_sign
+
+#include "cryptlib.h"
+#include "dsa.h"
+
+DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
+       {
+       return dsa->meth->dsa_do_sign(dgst, dlen, dsa);
+       }
+
+int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
+       {
+       return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
+       }
+
diff --git a/crypto/openssl/dsa/dsa_vrf.c b/crypto/openssl/dsa/dsa_vrf.c
new file mode 100644 (file)
index 0000000..a1af7db
--- /dev/null
@@ -0,0 +1,96 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
+
+// GrP pssh:
+// severely cut down to support DSA signature verification only
+// changed includes
+
+#include "cryptlib.h"
+#include "bn/bn.h"
+#include "dsa.h"
+
+int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
+                 DSA *dsa)
+       {
+       return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
+       }
diff --git a/crypto/openssl/evp/digest.c b/crypto/openssl/evp/digest.c
new file mode 100644 (file)
index 0000000..d71ee6e
--- /dev/null
@@ -0,0 +1,348 @@
+/* crypto/evp/digest.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.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 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).
+ *
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+
+#include "cryptlib.h"
+#include "evp.h"
+#include "objects/objects.h"
+
+
+void EVP_MD_CTX_init(EVP_MD_CTX *ctx)
+       {
+       memset(ctx,'\0',sizeof *ctx);
+       }
+
+EVP_MD_CTX *EVP_MD_CTX_create(void)
+       {
+       EVP_MD_CTX *ctx=OPENSSL_malloc(sizeof *ctx);
+
+       EVP_MD_CTX_init(ctx);
+
+       return ctx;
+       }
+
+int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
+       {
+       EVP_MD_CTX_init(ctx);
+       return EVP_DigestInit_ex(ctx, type, NULL);
+       }
+
+int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
+       {
+       EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
+#ifndef OPENSSL_NO_ENGINE
+       /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
+        * so this context may already have an ENGINE! Try to avoid releasing
+        * the previous handle, re-querying for an ENGINE, and having a
+        * reinitialisation, when it may all be unecessary. */
+       if (ctx->engine && ctx->digest && (!type ||
+                       (type && (type->type == ctx->digest->type))))
+               goto skip_to_init;
+       if (type)
+               {
+               /* Ensure an ENGINE left lying around from last time is cleared
+                * (the previous check attempted to avoid this if the same
+                * ENGINE and EVP_MD could be used). */
+               if(ctx->engine)
+                       ENGINE_finish(ctx->engine);
+               if(impl)
+                       {
+                       if (!ENGINE_init(impl))
+                               {
+                               EVPerr(EVP_F_EVP_DIGESTINIT, EVP_R_INITIALIZATION_ERROR);
+                               return 0;
+                               }
+                       }
+               else
+                       /* Ask if an ENGINE is reserved for this job */
+                       impl = ENGINE_get_digest_engine(type->type);
+               if(impl)
+                       {
+                       /* There's an ENGINE for this job ... (apparently) */
+                       const EVP_MD *d = ENGINE_get_digest(impl, type->type);
+                       if(!d)
+                               {
+                               /* Same comment from evp_enc.c */
+                               EVPerr(EVP_F_EVP_DIGESTINIT, EVP_R_INITIALIZATION_ERROR);
+                               return 0;
+                               }
+                       /* We'll use the ENGINE's private digest definition */
+                       type = d;
+                       /* Store the ENGINE functional reference so we know
+                        * 'type' came from an ENGINE and we need to release
+                        * it when done. */
+                       ctx->engine = impl;
+                       }
+               else
+                       ctx->engine = NULL;
+               }
+       else
+       if(!ctx->digest)
+               {
+               EVPerr(EVP_F_EVP_DIGESTINIT, EVP_R_NO_DIGEST_SET);
+               return 0;
+               }
+#endif
+       if (ctx->digest != type)
+               {
+               if (ctx->digest && ctx->digest->ctx_size)
+                       OPENSSL_free(ctx->md_data);
+               ctx->digest=type;
+               if (type->ctx_size)
+                       ctx->md_data=OPENSSL_malloc(type->ctx_size);
+               }
+#ifndef OPENSSL_NO_ENGINE
+skip_to_init:
+#endif
+       return ctx->digest->init(ctx);
+       }
+
+int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data,
+            unsigned int count)
+       {
+       return ctx->digest->update(ctx,data,(unsigned long)count);
+       }
+
+/* The caller can assume that this removes any secret data from the context */
+int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
+       {
+       int ret;
+       ret = EVP_DigestFinal_ex(ctx, md, size);
+       EVP_MD_CTX_cleanup(ctx);
+       return ret;
+       }
+
+/* The caller can assume that this removes any secret data from the context */
+int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
+       {
+       int ret;
+
+       OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
+       ret=ctx->digest->final(ctx,md);
+       if (size != NULL)
+               *size=ctx->digest->md_size;
+       if (ctx->digest->cleanup)
+               {
+               ctx->digest->cleanup(ctx);
+               EVP_MD_CTX_set_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
+               }
+       memset(ctx->md_data,0,ctx->digest->ctx_size);
+       return ret;
+       }
+
+int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
+       {
+       EVP_MD_CTX_init(out);
+       return EVP_MD_CTX_copy_ex(out, in);
+       }
+
+int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
+       {
+       if ((in == NULL) || (in->digest == NULL))
+               {
+               EVPerr(EVP_F_EVP_MD_CTX_COPY,EVP_R_INPUT_NOT_INITIALIZED);
+               return 0;
+               }
+#ifndef OPENSSL_NO_ENGINE
+       /* Make sure it's safe to copy a digest context using an ENGINE */
+       if (in->engine && !ENGINE_init(in->engine))
+               {
+               EVPerr(EVP_F_EVP_MD_CTX_COPY,ERR_R_ENGINE_LIB);
+               return 0;
+               }
+#endif
+
+       EVP_MD_CTX_cleanup(out);
+       memcpy(out,in,sizeof *out);
+
+       if (out->digest->ctx_size)
+               {
+               out->md_data=OPENSSL_malloc(out->digest->ctx_size);
+               memcpy(out->md_data,in->md_data,out->digest->ctx_size);
+               }
+       
+       if (out->digest->copy)
+               return out->digest->copy(out,in);
+       
+       return 1;
+       }
+
+int EVP_Digest(void *data, unsigned int count,
+               unsigned char *md, unsigned int *size, const EVP_MD *type, ENGINE *impl)
+       {
+       EVP_MD_CTX ctx;
+       int ret;
+
+       EVP_MD_CTX_init(&ctx);
+       EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_ONESHOT);
+       ret=EVP_DigestInit_ex(&ctx, type, impl)
+         && EVP_DigestUpdate(&ctx, data, count)
+         && EVP_DigestFinal_ex(&ctx, md, size);
+       EVP_MD_CTX_cleanup(&ctx);
+
+       return ret;
+       }
+
+void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
+       {
+       EVP_MD_CTX_cleanup(ctx);
+       OPENSSL_free(ctx);
+       }
+
+/* This call frees resources associated with the context */
+int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
+       {
+       /* Don't assume ctx->md_data was cleaned in EVP_Digest_Final,
+        * because sometimes only copies of the context are ever finalised.
+        */
+       if (ctx->digest && ctx->digest->cleanup
+           && !EVP_MD_CTX_test_flags(ctx,EVP_MD_CTX_FLAG_CLEANED))
+               ctx->digest->cleanup(ctx);
+       if (ctx->digest && ctx->digest->ctx_size && ctx->md_data)
+               {
+               OPENSSL_cleanse(ctx->md_data,ctx->digest->ctx_size);
+               OPENSSL_free(ctx->md_data);
+               }
+#ifndef OPENSSL_NO_ENGINE
+       if(ctx->engine)
+               /* The EVP_MD we used belongs to an ENGINE, release the
+                * functional reference we held for this reason. */
+               ENGINE_finish(ctx->engine);
+#endif
+       memset(ctx,'\0',sizeof *ctx);
+
+       return 1;
+       }
diff --git a/crypto/openssl/evp/e_aes.c b/crypto/openssl/evp/e_aes.c
new file mode 100644 (file)
index 0000000..f62da15
--- /dev/null
@@ -0,0 +1,115 @@
+/* ====================================================================
+ * Copyright (c) 2001 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.
+ * ====================================================================
+ *
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// added EVP_SEGMENT everywhere
+// removed AES-192 and AES-256
+// removed all AES-128 modes except cbc
+
+#ifndef OPENSSL_NO_AES
+
+#include "cryptlib.h"
+#include "aes/aes.h"
+#include "objects/obj_mac.h"
+#include "evp.h"
+#include "evp_locl.h"
+
+static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                                       const unsigned char *iv, int enc) EVP_SEGMENT;
+
+typedef struct
+       {
+       AES_KEY ks;
+       } EVP_AES_KEY;
+
+#define data(ctx)      EVP_C_DATA(EVP_AES_KEY,ctx)
+
+BLOCK_CIPHER_func_cbc(aes_128, AES, EVP_AES_KEY, ks)
+BLOCK_CIPHER_def_cbc(aes_128, EVP_AES_KEY, NID_aes_128, 16, 16, 16, 0, 
+                     aes_init_key, NULL, NULL, NULL, NULL)
+
+static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                  const unsigned char *iv, int enc) {
+
+       if ((ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_CFB_MODE
+           || (ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_OFB_MODE
+           || enc) 
+               AES_set_encrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
+       else
+               AES_set_decrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
+
+       return 1;
+}
+
+#endif
diff --git a/crypto/openssl/evp/e_des3.c b/crypto/openssl/evp/e_des3.c
new file mode 100644 (file)
index 0000000..7637afe
--- /dev/null
@@ -0,0 +1,249 @@
+/* crypto/evp/e_des3.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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// added EVP_SEGMENT everywhere
+// removed all ciphers except ede_cbc and ede3_cbc
+
+#ifndef OPENSSL_NO_DES
+#include "cryptlib.h"
+#include "evp.h"
+#include "evp_locl.h"
+#include "objects/objects.h"
+#include "des/des.h"
+
+
+static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                           const unsigned char *iv,int enc) EVP_SEGMENT;
+
+static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                            const unsigned char *iv,int enc) EVP_SEGMENT;
+
+typedef struct
+    {
+    DES_key_schedule ks1;/* key schedule */
+    DES_key_schedule ks2;/* key schedule (for ede) */
+    DES_key_schedule ks3;/* key schedule (for ede3) */
+    } DES_EDE_KEY;
+
+#define data(ctx) ((DES_EDE_KEY *)(ctx)->cipher_data)
+
+/* Because of various casts and different args can't use IMPLEMENT_BLOCK_CIPHER */
+/*
+static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                             const unsigned char *in, unsigned int inl) EVP_SEGMENT;
+static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                             const unsigned char *in, unsigned int inl)
+{
+       BLOCK_CIPHER_ecb_loop()
+               DES_ecb3_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i), 
+                                &data(ctx)->ks1, &data(ctx)->ks2,
+                                &data(ctx)->ks3,
+                                ctx->encrypt);
+       return 1;
+}
+*/
+/*
+static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                             const unsigned char *in, unsigned int inl) EVP_SEGMENT;
+static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                             const unsigned char *in, unsigned int inl)
+{
+       DES_ede3_ofb64_encrypt(in, out, (long)inl,
+                              &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+                              (DES_cblock *)ctx->iv, &ctx->num);
+       return 1;
+}
+*/
+static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                             const unsigned char *in, unsigned int inl) EVP_SEGMENT;
+static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                             const unsigned char *in, unsigned int inl)
+{
+#ifdef KSSL_DEBUG
+       {
+        int i;
+        char *cp;
+       printf("des_ede_cbc_cipher(ctx=%lx, buflen=%d)\n", ctx, ctx->buf_len);
+       printf("\t iv= ");
+        for(i=0;i<8;i++)
+                printf("%02X",ctx->iv[i]);
+       printf("\n");
+       }
+#endif    /* KSSL_DEBUG */
+       DES_ede3_cbc_encrypt(in, out, (long)inl,
+                            &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+                            (DES_cblock *)ctx->iv, ctx->encrypt);
+       return 1;
+}
+/*
+static int des_ede_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                             const unsigned char *in, unsigned int inl) EVP_SEGMENT;
+static int des_ede_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                             const unsigned char *in, unsigned int inl)
+{
+       DES_ede3_cfb64_encrypt(in, out, (long)inl, 
+                              &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
+                              (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
+       return 1;
+}
+*/
+/*
+BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64,
+                       0, des_ede_init_key, NULL, 
+                  NULL, // EVP_CIPHER_set_asn1_iv,
+                  NULL, // EVP_CIPHER_get_asn1_iv,
+                       NULL)
+*/
+BLOCK_CIPHER_def_cbc(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 
+                       0, des_ede_init_key, NULL, 
+                  NULL, // EVP_CIPHER_set_asn1_iv,
+                  NULL, // EVP_CIPHER_get_asn1_iv,
+                       NULL)
+
+#define des_ede3_cfb_cipher des_ede_cfb_cipher
+#define des_ede3_ofb_cipher des_ede_ofb_cipher
+#define des_ede3_cbc_cipher des_ede_cbc_cipher
+#define des_ede3_ecb_cipher des_ede_ecb_cipher
+
+/*
+BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64,
+                       0, des_ede3_init_key, NULL, 
+                  NULL, //EVP_CIPHER_set_asn1_iv,
+                  NULL, //EVP_CIPHER_get_asn1_iv,
+                       NULL)
+*/
+BLOCK_CIPHER_def_cbc(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8,
+                       0, des_ede3_init_key, NULL, 
+                  NULL, //EVP_CIPHER_set_asn1_iv,
+                  NULL, //EVP_CIPHER_get_asn1_iv,
+                       NULL)
+
+static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                           const unsigned char *iv, int enc) EVP_SEGMENT;
+static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                           const unsigned char *iv, int enc)
+       {
+       DES_cblock *deskey = (DES_cblock *)key;
+
+       DES_set_key_unchecked(&deskey[0],&data(ctx)->ks1);
+       DES_set_key_unchecked(&deskey[1],&data(ctx)->ks2);
+       memcpy(&data(ctx)->ks3,&data(ctx)->ks1,
+              sizeof(data(ctx)->ks1));
+       return 1;
+       }
+
+static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                            const unsigned char *iv, int enc) EVP_SEGMENT;
+static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                            const unsigned char *iv, int enc)
+       {
+       DES_cblock *deskey = (DES_cblock *)key;
+#ifdef KSSL_DEBUG
+       {
+        int i;
+        printf("des_ede3_init_key(ctx=%lx)\n", ctx);
+       printf("\tKEY= ");
+        for(i=0;i<24;i++) printf("%02X",key[i]); printf("\n");
+       printf("\t IV= ");
+        for(i=0;i<8;i++) printf("%02X",iv[i]); printf("\n");
+       }
+#endif /* KSSL_DEBUG */
+
+       DES_set_key_unchecked(&deskey[0],&data(ctx)->ks1);
+       DES_set_key_unchecked(&deskey[1],&data(ctx)->ks2);
+       DES_set_key_unchecked(&deskey[2],&data(ctx)->ks3);
+
+       return 1;
+       }
+/*
+const EVP_CIPHER *EVP_des_ede(void)
+{
+       return &des_ede_ecb;
+}
+
+const EVP_CIPHER *EVP_des_ede3(void)
+{
+       return &des_ede3_ecb;
+}
+*/
+#endif
diff --git a/crypto/openssl/evp/e_null.c b/crypto/openssl/evp/e_null.c
new file mode 100644 (file)
index 0000000..f7b98d5
--- /dev/null
@@ -0,0 +1,129 @@
+/* crypto/evp/e_null.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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// added EVP_SEGMENT everywhere
+// added extra initializer for n_cipher (fixme why?)
+
+#include "cryptlib.h"
+#include "evp.h"
+#include "objects/objects.h"
+
+static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+       const unsigned char *iv,int enc) EVP_SEGMENT;
+static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+       const unsigned char *in, unsigned int inl);
+static const EVP_CIPHER n_cipher=
+       {
+       NID_undef,
+       1,0,0,
+       0,
+       null_init_key,
+       null_cipher,
+       NULL,
+       0,
+       NULL,
+       NULL,
+       NULL,
+       NULL
+       };
+
+const EVP_CIPHER *EVP_enc_null(void)
+       {
+       return(&n_cipher);
+       }
+
+static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+            const unsigned char *iv, int enc)
+       {
+       /*      memset(&(ctx->c),0,sizeof(ctx->c));*/
+       return 1;
+       }
+
+static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+            const unsigned char *in, unsigned int inl)
+       {
+       if (in != out)
+               memcpy((char *)out,(char *)in,(int)inl);
+       return 1;
+       }
+
diff --git a/crypto/openssl/evp/evp.h b/crypto/openssl/evp/evp.h
new file mode 100644 (file)
index 0000000..657f5b5
--- /dev/null
@@ -0,0 +1,918 @@
+/* crypto/evp/evp.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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// added EVP_SEGMENT everywhere
+// remove public-key fields from struct env_md_st
+
+#ifndef HEADER_ENVELOPE_H
+#define HEADER_ENVELOPE_H
+
+#include "openssl/cryptlib.h"
+
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+#ifndef OPENSSL_NO_MD2
+#include <openssl/md2.h>
+#endif
+#ifndef OPENSSL_NO_MD4
+#include <openssl/md4.h>
+#endif
+#ifndef OPENSSL_NO_MD5
+#include "openssl/md5/md5.h"
+#endif
+#ifndef OPENSSL_NO_SHA
+#include "openssl/sha/sha.h"
+#endif
+#ifndef OPENSSL_NO_RIPEMD
+#include <openssl/ripemd.h>
+#endif
+#ifndef OPENSSL_NO_DES
+#include "openssl/des/des.h"
+#endif
+#ifndef OPENSSL_NO_RC4
+#include <openssl/rc4.h>
+#endif
+#ifndef OPENSSL_NO_RC2
+#include <openssl/rc2.h>
+#endif
+#ifndef OPENSSL_NO_RC5
+#include <openssl/rc5.h>
+#endif
+#ifndef OPENSSL_NO_BF
+#include <openssl/blowfish.h>
+#endif
+#ifndef OPENSSL_NO_CAST
+#include <openssl/cast.h>
+#endif
+#ifndef OPENSSL_NO_IDEA
+#include <openssl/idea.h>
+#endif
+#ifndef OPENSSL_NO_MDC2
+#include <openssl/mdc2.h>
+#endif
+#ifndef OPENSSL_NO_AES
+#include "openssl/aes/aes.h"
+#endif
+
+/*
+#define EVP_RC2_KEY_SIZE               16
+#define EVP_RC4_KEY_SIZE               16
+#define EVP_BLOWFISH_KEY_SIZE          16
+#define EVP_CAST5_KEY_SIZE             16
+#define EVP_RC5_32_12_16_KEY_SIZE      16
+*/
+#define EVP_MAX_MD_SIZE                        (16+20) /* The SSLv3 md5+sha1 type */
+#define EVP_MAX_KEY_LENGTH             32
+#define EVP_MAX_IV_LENGTH              16
+#define EVP_MAX_BLOCK_LENGTH           32
+
+#define PKCS5_SALT_LEN                 8
+/* Default PKCS#5 iteration count */
+#define PKCS5_DEFAULT_ITER             2048
+
+#ifndef OPENSSL_NO_RSA
+#include "openssl/rsa/rsa.h"
+#endif
+
+#ifndef OPENSSL_NO_DSA
+#include "openssl/dsa/dsa.h"
+#endif
+
+#ifndef OPENSSL_NO_DH
+#include "openssl/dh/dh.h"
+#endif
+
+#include "openssl/objects/objects.h"
+
+#define EVP_PK_RSA     0x0001
+#define EVP_PK_DSA     0x0002
+#define EVP_PK_DH      0x0004
+#define EVP_PKT_SIGN   0x0010
+#define EVP_PKT_ENC    0x0020
+#define EVP_PKT_EXCH   0x0040
+#define EVP_PKS_RSA    0x0100
+#define EVP_PKS_DSA    0x0200
+#define EVP_PKT_EXP    0x1000 /* <= 512 bit key */
+
+#define EVP_PKEY_NONE  NID_undef
+#define EVP_PKEY_RSA   NID_rsaEncryption
+#define EVP_PKEY_RSA2  NID_rsa
+#define EVP_PKEY_DSA   NID_dsa
+#define EVP_PKEY_DSA1  NID_dsa_2
+#define EVP_PKEY_DSA2  NID_dsaWithSHA
+#define EVP_PKEY_DSA3  NID_dsaWithSHA1
+#define EVP_PKEY_DSA4  NID_dsaWithSHA1_2
+#define EVP_PKEY_DH    NID_dhKeyAgreement
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Type needs to be a bit field
+ * Sub-type needs to be for variations on the method, as in, can it do
+ * arbitrary encryption.... */
+struct evp_pkey_st
+       {
+       int type;
+       int save_type;
+       int references;
+       union   {
+               char *ptr;
+#ifndef OPENSSL_NO_RSA
+               struct rsa_st *rsa;     /* RSA */
+#endif
+#ifndef OPENSSL_NO_DSA
+               struct dsa_st *dsa;     /* DSA */
+#endif
+#ifndef OPENSSL_NO_DH
+               struct dh_st *dh;       /* DH */
+#endif
+               } pkey;
+       int save_parameters;
+       STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
+       } /* EVP_PKEY */;
+
+#define EVP_PKEY_MO_SIGN       0x0001
+#define EVP_PKEY_MO_VERIFY     0x0002
+#define EVP_PKEY_MO_ENCRYPT    0x0004
+#define EVP_PKEY_MO_DECRYPT    0x0008
+
+#if 0
+/* This structure is required to tie the message digest and signing together.
+ * The lookup can be done by md/pkey_method, oid, oid/pkey_method, or
+ * oid, md and pkey.
+ * This is required because for various smart-card perform the digest and
+ * signing/verification on-board.  To handle this case, the specific
+ * EVP_MD and EVP_PKEY_METHODs need to be closely associated.
+ * When a PKEY is created, it will have a EVP_PKEY_METHOD associated with it.
+ * This can either be software or a token to provide the required low level
+ * routines.
+ */
+typedef struct evp_pkey_md_st
+       {
+       int oid;
+       EVP_MD *md;
+       EVP_PKEY_METHOD *pkey;
+       } EVP_PKEY_MD;
+
+#define EVP_rsa_md2() \
+               EVP_PKEY_MD_add(NID_md2WithRSAEncryption,\
+                       EVP_rsa_pkcs1(),EVP_md2())
+#define EVP_rsa_md5() \
+               EVP_PKEY_MD_add(NID_md5WithRSAEncryption,\
+                       EVP_rsa_pkcs1(),EVP_md5())
+#define EVP_rsa_sha0() \
+               EVP_PKEY_MD_add(NID_shaWithRSAEncryption,\
+                       EVP_rsa_pkcs1(),EVP_sha())
+#define EVP_rsa_sha1() \
+               EVP_PKEY_MD_add(NID_sha1WithRSAEncryption,\
+                       EVP_rsa_pkcs1(),EVP_sha1())
+#define EVP_rsa_ripemd160() \
+               EVP_PKEY_MD_add(NID_ripemd160WithRSA,\
+                       EVP_rsa_pkcs1(),EVP_ripemd160())
+#define EVP_rsa_mdc2() \
+               EVP_PKEY_MD_add(NID_mdc2WithRSA,\
+                       EVP_rsa_octet_string(),EVP_mdc2())
+#define EVP_dsa_sha() \
+               EVP_PKEY_MD_add(NID_dsaWithSHA,\
+                       EVP_dsa(),EVP_sha())
+#define EVP_dsa_sha1() \
+               EVP_PKEY_MD_add(NID_dsaWithSHA1,\
+                       EVP_dsa(),EVP_sha1())
+
+typedef struct evp_pkey_method_st
+       {
+       char *name;
+       int flags;
+       int type;               /* RSA, DSA, an SSLeay specific constant */
+       int oid;                /* For the pub-key type */
+       int encrypt_oid;        /* pub/priv key encryption */
+
+       int (*sign)();
+       int (*verify)();
+       struct  {
+               int (*set)();   /* get and/or set the underlying type */
+               int (*get)();
+               int (*encrypt)();
+               int (*decrypt)();
+               int (*i2d)();
+               int (*d2i)();
+               int (*dup)();
+               } pub,priv;
+       int (*set_asn1_parameters)();
+       int (*get_asn1_parameters)();
+       } EVP_PKEY_METHOD;
+#endif
+
+#ifndef EVP_MD
+struct env_md_st
+       {
+       int type;
+       // int pkey_type;
+       int md_size;
+       unsigned long flags;
+       int (*init)(EVP_MD_CTX *ctx);
+       int (*update)(EVP_MD_CTX *ctx,const void *data,unsigned long count);
+       int (*final)(EVP_MD_CTX *ctx,unsigned char *md);
+       int (*copy)(EVP_MD_CTX *to,const EVP_MD_CTX *from);
+       int (*cleanup)(EVP_MD_CTX *ctx);
+
+       /* FIXME: prototype these some day */
+       // int (*sign)();
+       // int (*verify)();
+       // int required_pkey_type[5]; /*EVP_PKEY_xxx */
+       int block_size;
+       int ctx_size; /* how big does the ctx->md_data need to be */
+       } /* EVP_MD */;
+
+#define EVP_MD_FLAG_ONESHOT    0x0001 /* digest can only handle a single
+                                       * block */
+
+#define EVP_PKEY_NULL_method   NULL,NULL,{0,0,0,0}
+
+#ifndef OPENSSL_NO_DSA
+#define EVP_PKEY_DSA_method    DSA_sign,DSA_verify, \
+                               {EVP_PKEY_DSA,EVP_PKEY_DSA2,EVP_PKEY_DSA3, \
+                                       EVP_PKEY_DSA4,0}
+#else
+#define EVP_PKEY_DSA_method    EVP_PKEY_NULL_method
+#endif
+
+#ifndef OPENSSL_NO_RSA
+#define EVP_PKEY_RSA_method    RSA_sign,RSA_verify, \
+                               {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
+#define EVP_PKEY_RSA_ASN1_OCTET_STRING_method \
+                               RSA_sign_ASN1_OCTET_STRING, \
+                               RSA_verify_ASN1_OCTET_STRING, \
+                               {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
+#else
+#define EVP_PKEY_RSA_method    EVP_PKEY_NULL_method
+#define EVP_PKEY_RSA_ASN1_OCTET_STRING_method EVP_PKEY_NULL_method
+#endif
+
+#endif /* !EVP_MD */
+
+struct env_md_ctx_st
+       {
+       const EVP_MD *digest;
+       ENGINE *engine; /* functional reference if 'digest' is ENGINE-provided */
+       unsigned long flags;
+       void *md_data;
+       } /* EVP_MD_CTX */;
+
+/* values for EVP_MD_CTX flags */
+
+#define EVP_MD_CTX_FLAG_ONESHOT                0x0001 /* digest update will be called
+                                               * once only */
+#define EVP_MD_CTX_FLAG_CLEANED                0x0002 /* context has already been
+                                               * cleaned */
+
+struct evp_cipher_st
+       {
+       int nid;
+       int block_size;
+       int key_len;            /* Default value for variable length ciphers */
+       int iv_len;
+       unsigned long flags;    /* Various flags */
+       int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                   const unsigned char *iv, int enc);  /* init key */
+       int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                        const unsigned char *in, unsigned int inl);/* encrypt/decrypt data */
+       int (*cleanup)(EVP_CIPHER_CTX *); /* cleanup ctx */
+       int ctx_size;           /* how big ctx->cipher_data needs to be */
+       int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Populate a ASN1_TYPE with parameters */
+       int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */
+       int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Miscellaneous operations */
+       void *app_data;         /* Application data */
+       } /* EVP_CIPHER */;
+
+/* Values for cipher flags */
+
+/* Modes for ciphers */
+
+#define                EVP_CIPH_STREAM_CIPHER          0x0
+#define                EVP_CIPH_ECB_MODE               0x1
+#define                EVP_CIPH_CBC_MODE               0x2
+#define                EVP_CIPH_CFB_MODE               0x3
+#define                EVP_CIPH_OFB_MODE               0x4
+#define        EVP_CIPH_MODE                   0x7
+/* Set if variable length cipher */
+#define        EVP_CIPH_VARIABLE_LENGTH        0x8
+/* Set if the iv handling should be done by the cipher itself */
+#define        EVP_CIPH_CUSTOM_IV              0x10
+/* Set if the cipher's init() function should be called if key is NULL */
+#define        EVP_CIPH_ALWAYS_CALL_INIT       0x20
+/* Call ctrl() to init cipher parameters */
+#define        EVP_CIPH_CTRL_INIT              0x40
+/* Don't use standard key length function */
+#define        EVP_CIPH_CUSTOM_KEY_LENGTH      0x80
+/* Don't use standard block padding */
+#define        EVP_CIPH_NO_PADDING             0x100
+
+/* ctrl() values */
+
+#define                EVP_CTRL_INIT                   0x0
+#define        EVP_CTRL_SET_KEY_LENGTH         0x1
+#define        EVP_CTRL_GET_RC2_KEY_BITS       0x2
+#define        EVP_CTRL_SET_RC2_KEY_BITS       0x3
+#define        EVP_CTRL_GET_RC5_ROUNDS         0x4
+#define        EVP_CTRL_SET_RC5_ROUNDS         0x5
+
+typedef struct evp_cipher_info_st
+       {
+       const EVP_CIPHER *cipher;
+       unsigned char iv[EVP_MAX_IV_LENGTH];
+       } EVP_CIPHER_INFO;
+
+struct evp_cipher_ctx_st
+       {
+       const EVP_CIPHER *cipher;
+       ENGINE *engine; /* functional reference if 'cipher' is ENGINE-provided */
+       int encrypt;            /* encrypt or decrypt */
+       int buf_len;            /* number we have left */
+
+       unsigned char  oiv[EVP_MAX_IV_LENGTH];  /* original iv */
+       unsigned char  iv[EVP_MAX_IV_LENGTH];   /* working iv */
+       unsigned char buf[EVP_MAX_BLOCK_LENGTH];/* saved partial block */
+       int num;                                /* used by cfb/ofb mode */
+
+       void *app_data;         /* application stuff */
+       int key_len;            /* May change for variable length cipher */
+       unsigned long flags;    /* Various flags */
+       void *cipher_data; /* per EVP data */
+       int final_used;
+       int block_mask;
+       unsigned char final[EVP_MAX_BLOCK_LENGTH];/* possible final block */
+       } /* EVP_CIPHER_CTX */;
+
+typedef struct evp_Encode_Ctx_st
+       {
+       int num;        /* number saved in a partial encode/decode */
+       int length;     /* The length is either the output line length
+                        * (in input bytes) or the shortest input line
+                        * length that is ok.  Once decoding begins,
+                        * the length is adjusted up each time a longer
+                        * line is decoded */
+       unsigned char enc_data[80];     /* data to encode */
+       int line_num;   /* number read on current line */
+       int expect_nl;
+       } EVP_ENCODE_CTX;
+
+/* Password based encryption function */
+typedef int (EVP_PBE_KEYGEN)(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+               ASN1_TYPE *param, const EVP_CIPHER *cipher,
+                const EVP_MD *md, int en_de);
+
+#ifndef OPENSSL_NO_RSA
+#define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
+                                       (char *)(rsa))
+#endif
+
+#ifndef OPENSSL_NO_DSA
+#define EVP_PKEY_assign_DSA(pkey,dsa) EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\
+                                       (char *)(dsa))
+#endif
+
+#ifndef OPENSSL_NO_DH
+#define EVP_PKEY_assign_DH(pkey,dh) EVP_PKEY_assign((pkey),EVP_PKEY_DH,\
+                                       (char *)(dh))
+#endif
+
+/* Add some extra combinations */
+#define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a))
+#define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a))
+#define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a))
+#define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a))
+
+#define EVP_MD_type(e)                 ((e)->type)
+#define EVP_MD_nid(e)                  EVP_MD_type(e)
+#define EVP_MD_name(e)                 OBJ_nid2sn(EVP_MD_nid(e))
+#define EVP_MD_pkey_type(e)            ((e)->pkey_type)
+#define EVP_MD_size(e)                 ((e)->md_size)
+#define EVP_MD_block_size(e)           ((e)->block_size)
+
+#define EVP_MD_CTX_md(e)               ((e)->digest)
+#define EVP_MD_CTX_size(e)             EVP_MD_size((e)->digest)
+#define EVP_MD_CTX_block_size(e)       EVP_MD_block_size((e)->digest)
+#define EVP_MD_CTX_type(e)             EVP_MD_type((e)->digest)
+
+#define EVP_CIPHER_nid(e)              ((e)->nid)
+#define EVP_CIPHER_name(e)             OBJ_nid2sn(EVP_CIPHER_nid(e))
+#define EVP_CIPHER_block_size(e)       ((e)->block_size)
+#define EVP_CIPHER_key_length(e)       ((e)->key_len)
+#define EVP_CIPHER_iv_length(e)                ((e)->iv_len)
+#define EVP_CIPHER_flags(e)            ((e)->flags)
+#define EVP_CIPHER_mode(e)             (((e)->flags) & EVP_CIPH_MODE)
+
+#define EVP_CIPHER_CTX_cipher(e)       ((e)->cipher)
+#define EVP_CIPHER_CTX_nid(e)          ((e)->cipher->nid)
+#define EVP_CIPHER_CTX_block_size(e)   ((e)->cipher->block_size)
+#define EVP_CIPHER_CTX_key_length(e)   ((e)->key_len)
+#define EVP_CIPHER_CTX_iv_length(e)    ((e)->cipher->iv_len)
+#define EVP_CIPHER_CTX_get_app_data(e) ((e)->app_data)
+#define EVP_CIPHER_CTX_set_app_data(e,d) ((e)->app_data=(char *)(d))
+#define EVP_CIPHER_CTX_type(c)         EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c))
+#define EVP_CIPHER_CTX_flags(e)                ((e)->cipher->flags)
+#define EVP_CIPHER_CTX_mode(e)         ((e)->cipher->flags & EVP_CIPH_MODE)
+
+#define EVP_ENCODE_LENGTH(l)   (((l+2)/3*4)+(l/48+1)*2+80)
+#define EVP_DECODE_LENGTH(l)   ((l+3)/4*3+80)
+
+#define EVP_SignInit_ex(a,b,c)         EVP_DigestInit_ex(a,b,c)
+#define EVP_SignInit(a,b)              EVP_DigestInit(a,b)
+#define EVP_SignUpdate(a,b,c)          EVP_DigestUpdate(a,b,c)
+#define        EVP_VerifyInit_ex(a,b,c)        EVP_DigestInit_ex(a,b,c)
+#define        EVP_VerifyInit(a,b)             EVP_DigestInit(a,b)
+#define        EVP_VerifyUpdate(a,b,c)         EVP_DigestUpdate(a,b,c)
+#define EVP_OpenUpdate(a,b,c,d,e)      EVP_DecryptUpdate(a,b,c,d,e)
+#define EVP_SealUpdate(a,b,c,d,e)      EVP_EncryptUpdate(a,b,c,d,e)    
+
+#ifdef CONST_STRICT
+void BIO_set_md(BIO *,const EVP_MD *md);
+#else
+# define BIO_set_md(b,md)              BIO_ctrl(b,BIO_C_SET_MD,0,(char *)md)
+#endif
+#define BIO_get_md(b,mdp)              BIO_ctrl(b,BIO_C_GET_MD,0,(char *)mdp)
+#define BIO_get_md_ctx(b,mdcp)     BIO_ctrl(b,BIO_C_GET_MD_CTX,0,(char *)mdcp)
+#define BIO_get_cipher_status(b)       BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL)
+#define BIO_get_cipher_ctx(b,c_pp)     BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0,(char *)c_pp)
+
+#define        EVP_Cipher(c,o,i,l)     (c)->cipher->do_cipher((c),(o),(i),(l))
+
+#define EVP_add_cipher_alias(n,alias) \
+       OBJ_NAME_add((alias),OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS,(n))
+#define EVP_add_digest_alias(n,alias) \
+       OBJ_NAME_add((alias),OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,(n))
+#define EVP_delete_cipher_alias(alias) \
+       OBJ_NAME_remove(alias,OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS);
+#define EVP_delete_digest_alias(alias) \
+       OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS);
+
+void   EVP_MD_CTX_init(EVP_MD_CTX *ctx) EVP_SEGMENT;
+int    EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) EVP_SEGMENT;
+EVP_MD_CTX *EVP_MD_CTX_create(void) EVP_SEGMENT;
+void   EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) EVP_SEGMENT;
+int     EVP_MD_CTX_copy_ex(EVP_MD_CTX *out,const EVP_MD_CTX *in) EVP_SEGMENT;  
+#define EVP_MD_CTX_set_flags(ctx,flgs) ((ctx)->flags|=(flgs))
+#define EVP_MD_CTX_clear_flags(ctx,flgs) ((ctx)->flags&=~(flgs))
+#define EVP_MD_CTX_test_flags(ctx,flgs) ((ctx)->flags&(flgs))
+int    EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) EVP_SEGMENT;
+int    EVP_DigestUpdate(EVP_MD_CTX *ctx,const void *d,
+                        unsigned int cnt) EVP_SEGMENT;
+int    EVP_DigestFinal_ex(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s) EVP_SEGMENT;
+int    EVP_Digest(void *data, unsigned int count,
+               unsigned char *md, unsigned int *size, const EVP_MD *type, ENGINE *impl) EVP_SEGMENT;
+
+int     EVP_MD_CTX_copy(EVP_MD_CTX *out,const EVP_MD_CTX *in) EVP_SEGMENT;  
+int    EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) EVP_SEGMENT;
+int    EVP_DigestFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s) EVP_SEGMENT;
+
+int    EVP_read_pw_string(char *buf,int length,const char *prompt,int verify) EVP_SEGMENT;
+void   EVP_set_pw_prompt(char *prompt) EVP_SEGMENT;
+char * EVP_get_pw_prompt(void) EVP_SEGMENT;
+
+int    EVP_BytesToKey(const EVP_CIPHER *type,const EVP_MD *md,
+               const unsigned char *salt, const unsigned char *data,
+               int datal, int count, unsigned char *key,unsigned char *iv) EVP_SEGMENT;
+
+int    EVP_EncryptInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher,
+               const unsigned char *key, const unsigned char *iv) EVP_SEGMENT;
+int    EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
+               const unsigned char *key, const unsigned char *iv) EVP_SEGMENT;
+int    EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
+               int *outl, const unsigned char *in, int inl) EVP_SEGMENT;
+int    EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) EVP_SEGMENT;
+int    EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) EVP_SEGMENT;
+
+int    EVP_DecryptInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher,
+               const unsigned char *key, const unsigned char *iv) EVP_SEGMENT;
+int    EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
+               const unsigned char *key, const unsigned char *iv) EVP_SEGMENT;
+int    EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
+               int *outl, const unsigned char *in, int inl) EVP_SEGMENT;
+int    EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+int    EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl) EVP_SEGMENT;
+
+int    EVP_CipherInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher,
+                      const unsigned char *key,const unsigned char *iv,
+                      int enc) EVP_SEGMENT;
+int    EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
+                      const unsigned char *key,const unsigned char *iv,
+                      int enc) EVP_SEGMENT;
+int    EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
+               int *outl, const unsigned char *in, int inl) EVP_SEGMENT;
+int    EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl) EVP_SEGMENT;
+int    EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl) EVP_SEGMENT;
+
+int    EVP_SignFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s,
+               EVP_PKEY *pkey) EVP_SEGMENT;
+
+int    EVP_VerifyFinal(EVP_MD_CTX *ctx,unsigned char *sigbuf,
+               unsigned int siglen,EVP_PKEY *pkey) EVP_SEGMENT;
+
+int    EVP_OpenInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *type,unsigned char *ek,
+               int ekl,unsigned char *iv,EVP_PKEY *priv) EVP_SEGMENT;
+int    EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) EVP_SEGMENT;
+
+int    EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, unsigned char **ek,
+               int *ekl, unsigned char *iv,EVP_PKEY **pubk, int npubk) EVP_SEGMENT;
+int    EVP_SealFinal(EVP_CIPHER_CTX *ctx,unsigned char *out,int *outl) EVP_SEGMENT;
+
+void   EVP_EncodeInit(EVP_ENCODE_CTX *ctx) EVP_SEGMENT;
+void   EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx,unsigned char *out,
+               int *outl,unsigned char *in,int inl) EVP_SEGMENT;
+void   EVP_EncodeFinal(EVP_ENCODE_CTX *ctx,unsigned char *out,int *outl) EVP_SEGMENT;
+int    EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int n) EVP_SEGMENT;
+
+void   EVP_DecodeInit(EVP_ENCODE_CTX *ctx) EVP_SEGMENT;
+int    EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx,unsigned char *out,int *outl,
+               unsigned char *in, int inl) EVP_SEGMENT;
+int    EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned
+               char *out, int *outl) EVP_SEGMENT;
+int    EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n) EVP_SEGMENT;
+
+void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a) EVP_SEGMENT;
+int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a) EVP_SEGMENT;
+int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen) EVP_SEGMENT;
+int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad) EVP_SEGMENT;
+int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) EVP_SEGMENT;
+
+#ifndef OPENSSL_NO_BIO
+BIO_METHOD *BIO_f_md(void) EVP_SEGMENT;
+BIO_METHOD *BIO_f_base64(void) EVP_SEGMENT;
+BIO_METHOD *BIO_f_cipher(void) EVP_SEGMENT;
+BIO_METHOD *BIO_f_reliable(void) EVP_SEGMENT;
+void BIO_set_cipher(BIO *b,const EVP_CIPHER *c,unsigned char *k,
+       unsigned char *i, int enc) EVP_SEGMENT;
+#endif
+
+const EVP_MD *EVP_md_null(void) EVP_SEGMENT;
+#ifndef OPENSSL_NO_MD2
+const EVP_MD *EVP_md2(void) EVP_SEGMENT;
+#endif
+#ifndef OPENSSL_NO_MD4
+const EVP_MD *EVP_md4(void) EVP_SEGMENT;
+#endif
+#ifndef OPENSSL_NO_MD5
+const EVP_MD *EVP_md5(void) EVP_SEGMENT;
+#endif
+#ifndef OPENSSL_NO_SHA
+const EVP_MD *EVP_sha(void) EVP_SEGMENT;
+const EVP_MD *EVP_sha1(void) EVP_SEGMENT;
+const EVP_MD *EVP_dss(void) EVP_SEGMENT;
+const EVP_MD *EVP_dss1(void) EVP_SEGMENT;
+#endif
+#ifndef OPENSSL_NO_MDC2
+const EVP_MD *EVP_mdc2(void) EVP_SEGMENT;
+#endif
+#ifndef OPENSSL_NO_RIPEMD
+const EVP_MD *EVP_ripemd160(void) EVP_SEGMENT;
+#endif
+const EVP_CIPHER *EVP_enc_null(void) EVP_SEGMENT;              /* does nothing :-) */
+#ifndef OPENSSL_NO_DES
+const EVP_CIPHER *EVP_des_ecb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_des_ede(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_des_ede3(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_des_ede_ecb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_des_ede3_ecb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_des_cfb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_des_ede_cfb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_des_ede3_cfb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_des_ofb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_des_ede_ofb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_des_ede3_ofb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_des_cbc(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_des_ede_cbc(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_des_ede3_cbc(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_desx_cbc(void) EVP_SEGMENT;
+/* This should now be supported through the dev_crypto ENGINE. But also, why are
+ * rc4 and md5 declarations made here inside a "NO_DES" precompiler branch? */
+#if 0
+# ifdef OPENSSL_OPENBSD_DEV_CRYPTO
+const EVP_CIPHER *EVP_dev_crypto_des_ede3_cbc(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_dev_crypto_rc4(void) EVP_SEGMENT;
+const EVP_MD *EVP_dev_crypto_md5(void) EVP_SEGMENT;
+# endif
+#endif
+#endif
+#ifndef OPENSSL_NO_RC4
+const EVP_CIPHER *EVP_rc4(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_rc4_40(void) EVP_SEGMENT;
+#endif
+#ifndef OPENSSL_NO_IDEA
+const EVP_CIPHER *EVP_idea_ecb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_idea_cfb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_idea_ofb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_idea_cbc(void) EVP_SEGMENT;
+#endif
+#ifndef OPENSSL_NO_RC2
+const EVP_CIPHER *EVP_rc2_ecb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_rc2_cbc(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_rc2_40_cbc(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_rc2_64_cbc(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_rc2_cfb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_rc2_ofb(void) EVP_SEGMENT;
+#endif
+#ifndef OPENSSL_NO_BF
+const EVP_CIPHER *EVP_bf_ecb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_bf_cbc(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_bf_cfb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_bf_ofb(void) EVP_SEGMENT;
+#endif
+#ifndef OPENSSL_NO_CAST
+const EVP_CIPHER *EVP_cast5_ecb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_cast5_cbc(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_cast5_cfb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_cast5_ofb(void) EVP_SEGMENT;
+#endif
+#ifndef OPENSSL_NO_RC5
+const EVP_CIPHER *EVP_rc5_32_12_16_cbc(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_rc5_32_12_16_ecb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_rc5_32_12_16_ofb(void) EVP_SEGMENT;
+#endif
+#ifndef OPENSSL_NO_AES
+const EVP_CIPHER *EVP_aes_128_ecb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_aes_128_cbc(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_aes_128_cfb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_aes_128_ofb(void) EVP_SEGMENT;
+#if 0
+const EVP_CIPHER *EVP_aes_128_ctr(void) EVP_SEGMENT;
+#endif
+const EVP_CIPHER *EVP_aes_192_ecb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_aes_192_cbc(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_aes_192_cfb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_aes_192_ofb(void) EVP_SEGMENT;
+#if 0
+const EVP_CIPHER *EVP_aes_192_ctr(void) EVP_SEGMENT;
+#endif
+const EVP_CIPHER *EVP_aes_256_ecb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_aes_256_cbc(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_aes_256_cfb(void) EVP_SEGMENT;
+const EVP_CIPHER *EVP_aes_256_ofb(void) EVP_SEGMENT;
+#if 0
+const EVP_CIPHER *EVP_aes_256_ctr(void) EVP_SEGMENT;
+#endif
+#endif
+
+void OPENSSL_add_all_algorithms_noconf(void) EVP_SEGMENT;
+void OPENSSL_add_all_algorithms_conf(void) EVP_SEGMENT;
+
+#ifdef OPENSSL_LOAD_CONF
+#define OpenSSL_add_all_algorithms() \
+               OPENSSL_add_all_algorithms_conf()
+#else
+#define OpenSSL_add_all_algorithms() \
+               OPENSSL_add_all_algorithms_noconf()
+#endif
+
+void OpenSSL_add_all_ciphers(void) EVP_SEGMENT;
+void OpenSSL_add_all_digests(void) EVP_SEGMENT;
+#define SSLeay_add_all_algorithms() OpenSSL_add_all_algorithms()
+#define SSLeay_add_all_ciphers() OpenSSL_add_all_ciphers()
+#define SSLeay_add_all_digests() OpenSSL_add_all_digests()
+
+int EVP_add_cipher(const EVP_CIPHER *cipher) EVP_SEGMENT;
+int EVP_add_digest(const EVP_MD *digest) EVP_SEGMENT;
+
+const EVP_CIPHER *EVP_get_cipherbyname(const char *name) EVP_SEGMENT;
+const EVP_MD *EVP_get_digestbyname(const char *name) EVP_SEGMENT;
+void EVP_cleanup(void) EVP_SEGMENT;
+
+int            EVP_PKEY_decrypt(unsigned char *dec_key,unsigned char *enc_key,
+                       int enc_key_len,EVP_PKEY *private_key) EVP_SEGMENT;
+int            EVP_PKEY_encrypt(unsigned char *enc_key,
+                       unsigned char *key,int key_len,EVP_PKEY *pub_key) EVP_SEGMENT;
+int            EVP_PKEY_type(int type) EVP_SEGMENT;
+int            EVP_PKEY_bits(EVP_PKEY *pkey) EVP_SEGMENT;
+int            EVP_PKEY_size(EVP_PKEY *pkey) EVP_SEGMENT;
+int            EVP_PKEY_assign(EVP_PKEY *pkey,int type,char *key) EVP_SEGMENT;
+
+#ifndef OPENSSL_NO_RSA
+struct rsa_st;
+int EVP_PKEY_set1_RSA(EVP_PKEY *pkey,struct rsa_st *key) EVP_SEGMENT;
+struct rsa_st *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) EVP_SEGMENT;
+#endif
+#ifndef OPENSSL_NO_DSA
+struct dsa_st;
+int EVP_PKEY_set1_DSA(EVP_PKEY *pkey,struct dsa_st *key) EVP_SEGMENT;
+struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) EVP_SEGMENT;
+#endif
+#ifndef OPENSSL_NO_DH
+struct dh_st;
+int EVP_PKEY_set1_DH(EVP_PKEY *pkey,struct dh_st *key) EVP_SEGMENT;
+struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey) EVP_SEGMENT;
+#endif
+
+
+EVP_PKEY *     EVP_PKEY_new(void) EVP_SEGMENT;
+void           EVP_PKEY_free(EVP_PKEY *pkey) EVP_SEGMENT;
+EVP_PKEY *     d2i_PublicKey(int type,EVP_PKEY **a, unsigned char **pp,
+                       long length) EVP_SEGMENT;
+int            i2d_PublicKey(EVP_PKEY *a, unsigned char **pp) EVP_SEGMENT;
+
+EVP_PKEY *     d2i_PrivateKey(int type,EVP_PKEY **a, unsigned char **pp,
+                       long length) EVP_SEGMENT;
+EVP_PKEY *     d2i_AutoPrivateKey(EVP_PKEY **a, unsigned char **pp,
+                       long length) EVP_SEGMENT;
+int            i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp) EVP_SEGMENT;
+
+int EVP_PKEY_copy_parameters(EVP_PKEY *to,EVP_PKEY *from) EVP_SEGMENT;
+int EVP_PKEY_missing_parameters(EVP_PKEY *pkey) EVP_SEGMENT;
+int EVP_PKEY_save_parameters(EVP_PKEY *pkey,int mode) EVP_SEGMENT;
+int EVP_PKEY_cmp_parameters(EVP_PKEY *a,EVP_PKEY *b) EVP_SEGMENT;
+
+int EVP_CIPHER_type(const EVP_CIPHER *ctx) EVP_SEGMENT;
+
+/* calls methods */
+int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) EVP_SEGMENT;
+int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type) EVP_SEGMENT;
+
+/* These are used by EVP_CIPHER methods */
+int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c,ASN1_TYPE *type) EVP_SEGMENT;
+int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c,ASN1_TYPE *type) EVP_SEGMENT;
+
+/* PKCS5 password based encryption */
+int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+                        ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md,
+                        int en_de) EVP_SEGMENT;
+int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
+                          unsigned char *salt, int saltlen, int iter,
+                          int keylen, unsigned char *out) EVP_SEGMENT;
+int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+                        ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md,
+                        int en_de) EVP_SEGMENT;
+
+void PKCS5_PBE_add(void) EVP_SEGMENT;
+
+int EVP_PBE_CipherInit (ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
+            ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de) EVP_SEGMENT;
+int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
+                   EVP_PBE_KEYGEN *keygen) EVP_SEGMENT;
+void EVP_PBE_cleanup(void) EVP_SEGMENT;
+
+/* 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.
+ */
+void ERR_load_EVP_strings(void) EVP_SEGMENT;
+
+/* Error codes for the EVP functions. */
+
+/* Function codes. */
+#define EVP_F_D2I_PKEY                                  100
+#define EVP_F_EVP_CIPHERINIT                            123
+#define EVP_F_EVP_CIPHER_CTX_CTRL                       124
+#define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH             122
+#define EVP_F_EVP_DECRYPTFINAL                          101
+#define EVP_F_EVP_DIGESTINIT                            128
+#define EVP_F_EVP_ENCRYPTFINAL                          127
+#define EVP_F_EVP_MD_CTX_COPY                           110
+#define EVP_F_EVP_OPENINIT                              102
+#define EVP_F_EVP_PBE_ALG_ADD                           115
+#define EVP_F_EVP_PBE_CIPHERINIT                        116
+#define EVP_F_EVP_PKCS82PKEY                            111
+#define EVP_F_EVP_PKCS8_SET_BROKEN                      112
+#define EVP_F_EVP_PKEY2PKCS8                            113
+#define EVP_F_EVP_PKEY_COPY_PARAMETERS                  103
+#define EVP_F_EVP_PKEY_DECRYPT                          104
+#define EVP_F_EVP_PKEY_ENCRYPT                          105
+#define EVP_F_EVP_PKEY_GET1_DH                          119
+#define EVP_F_EVP_PKEY_GET1_DSA                                 120
+#define EVP_F_EVP_PKEY_GET1_RSA                                 121
+#define EVP_F_EVP_PKEY_NEW                              106
+#define EVP_F_EVP_RIJNDAEL                              126
+#define EVP_F_EVP_SIGNFINAL                             107
+#define EVP_F_EVP_VERIFYFINAL                           108
+#define EVP_F_PKCS5_PBE_KEYIVGEN                        117
+#define EVP_F_PKCS5_V2_PBE_KEYIVGEN                     118
+#define EVP_F_RC2_MAGIC_TO_METH                                 109
+#define EVP_F_RC5_CTRL                                  125
+
+/* Reason codes. */
+#define EVP_R_BAD_BLOCK_LENGTH                          136
+#define EVP_R_BAD_DECRYPT                               100
+#define EVP_R_BAD_KEY_LENGTH                            137
+#define EVP_R_BN_DECODE_ERROR                           112
+#define EVP_R_BN_PUBKEY_ERROR                           113
+#define EVP_R_CIPHER_PARAMETER_ERROR                    122
+#define EVP_R_CTRL_NOT_IMPLEMENTED                      132
+#define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED            133
+#define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH                 138
+#define EVP_R_DECODE_ERROR                              114
+#define EVP_R_DIFFERENT_KEY_TYPES                       101
+#define EVP_R_ENCODE_ERROR                              115
+#define EVP_R_EVP_PBE_CIPHERINIT_ERROR                  119
+#define EVP_R_EXPECTING_AN_RSA_KEY                      127
+#define EVP_R_EXPECTING_A_DH_KEY                        128
+#define EVP_R_EXPECTING_A_DSA_KEY                       129
+#define EVP_R_INITIALIZATION_ERROR                      134
+#define EVP_R_INPUT_NOT_INITIALIZED                     111
+#define EVP_R_INVALID_KEY_LENGTH                        130
+#define EVP_R_IV_TOO_LARGE                              102
+#define EVP_R_KEYGEN_FAILURE                            120
+#define EVP_R_MISSING_PARAMETERS                        103
+#define EVP_R_NO_CIPHER_SET                             131
+#define EVP_R_NO_DIGEST_SET                             139
+#define EVP_R_NO_DSA_PARAMETERS                                 116
+#define EVP_R_NO_SIGN_FUNCTION_CONFIGURED               104
+#define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED             105
+#define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE                         117
+#define EVP_R_PUBLIC_KEY_NOT_RSA                        106
+#define EVP_R_UNKNOWN_PBE_ALGORITHM                     121
+#define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS               135
+#define EVP_R_UNSUPPORTED_CIPHER                        107
+#define EVP_R_UNSUPPORTED_KEYLENGTH                     123
+#define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION       124
+#define EVP_R_UNSUPPORTED_KEY_SIZE                      108
+#define EVP_R_UNSUPPORTED_PRF                           125
+#define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM                 118
+#define EVP_R_UNSUPPORTED_SALT_TYPE                     126
+#define EVP_R_WRONG_FINAL_BLOCK_LENGTH                  109
+#define EVP_R_WRONG_PUBLIC_KEY_TYPE                     110
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/crypto/openssl/evp/evp_enc.c b/crypto/openssl/evp/evp_enc.c
new file mode 100644 (file)
index 0000000..494bc5d
--- /dev/null
@@ -0,0 +1,548 @@
+/* crypto/evp/evp_enc.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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+
+#include "cryptlib.h"
+#include "evp.h"
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include "evp_locl.h"
+
+const char *EVP_version="EVP" OPENSSL_VERSION_PTEXT;
+
+void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
+       {
+       memset(ctx,0,sizeof(EVP_CIPHER_CTX));
+       /* ctx->cipher=NULL; */
+       }
+
+
+int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+            const unsigned char *key, const unsigned char *iv, int enc)
+       {
+       if (cipher)
+               EVP_CIPHER_CTX_init(ctx);
+       return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc);
+       }
+
+int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
+            const unsigned char *key, const unsigned char *iv, int enc)
+       {
+       if (enc == -1)
+               enc = ctx->encrypt;
+       else
+               {
+               if (enc)
+                       enc = 1;
+               ctx->encrypt = enc;
+               }
+#ifndef OPENSSL_NO_ENGINE
+       /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
+        * so this context may already have an ENGINE! Try to avoid releasing
+        * the previous handle, re-querying for an ENGINE, and having a
+        * reinitialisation, when it may all be unecessary. */
+       if (ctx->engine && ctx->cipher && (!cipher ||
+                       (cipher && (cipher->nid == ctx->cipher->nid))))
+               goto skip_to_init;
+#endif
+       if (cipher)
+               {
+               /* Ensure a context left lying around from last time is cleared
+                * (the previous check attempted to avoid this if the same
+                * ENGINE and EVP_CIPHER could be used). */
+               EVP_CIPHER_CTX_cleanup(ctx);
+
+               /* Restore encrypt field: it is zeroed by cleanup */
+               ctx->encrypt = enc;
+#ifndef OPENSSL_NO_ENGINE
+               if(impl)
+                       {
+                       if (!ENGINE_init(impl))
+                               {
+                               EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR);
+                               return 0;
+                               }
+                       }
+               else
+                       /* Ask if an ENGINE is reserved for this job */
+                       impl = ENGINE_get_cipher_engine(cipher->nid);
+               if(impl)
+                       {
+                       /* There's an ENGINE for this job ... (apparently) */
+                       const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid);
+                       if(!c)
+                               {
+                               /* One positive side-effect of US's export
+                                * control history, is that we should at least
+                                * be able to avoid using US mispellings of
+                                * "initialisation"? */
+                               EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR);
+                               return 0;
+                               }
+                       /* We'll use the ENGINE's private cipher definition */
+                       cipher = c;
+                       /* Store the ENGINE functional reference so we know
+                        * 'cipher' came from an ENGINE and we need to release
+                        * it when done. */
+                       ctx->engine = impl;
+                       }
+               else
+                       ctx->engine = NULL;
+#endif
+
+               ctx->cipher=cipher;
+               ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size);
+               ctx->key_len = cipher->key_len;
+               ctx->flags = 0;
+               if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT)
+                       {
+                       if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL))
+                               {
+                               EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR);
+                               return 0;
+                               }
+                       }
+               }
+       else if(!ctx->cipher)
+               {
+               EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_NO_CIPHER_SET);
+               return 0;
+               }
+#ifndef OPENSSL_NO_ENGINE
+skip_to_init:
+#endif
+       /* we assume block size is a power of 2 in *cryptUpdate */
+       OPENSSL_assert(ctx->cipher->block_size == 1
+           || ctx->cipher->block_size == 8
+           || ctx->cipher->block_size == 16);
+
+       if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {
+               switch(EVP_CIPHER_CTX_mode(ctx)) {
+
+                       case EVP_CIPH_STREAM_CIPHER:
+                       case EVP_CIPH_ECB_MODE:
+                       break;
+
+                       case EVP_CIPH_CFB_MODE:
+                       case EVP_CIPH_OFB_MODE:
+
+                       ctx->num = 0;
+
+                       case EVP_CIPH_CBC_MODE:
+
+                       OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <= sizeof ctx->iv);
+                       if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
+                       memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
+                       break;
+
+                       default:
+                       return 0;
+                       break;
+               }
+       }
+
+       if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
+               if(!ctx->cipher->init(ctx,key,iv,enc)) return 0;
+       }
+       ctx->buf_len=0;
+       ctx->final_used=0;
+       ctx->block_mask=ctx->cipher->block_size-1;
+       return 1;
+       }
+
+int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+            const unsigned char *in, int inl)
+       {
+       if (ctx->encrypt)
+               return EVP_EncryptUpdate(ctx,out,outl,in,inl);
+       else    return EVP_DecryptUpdate(ctx,out,outl,in,inl);
+       }
+
+int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+       {
+       if (ctx->encrypt)
+               return EVP_EncryptFinal_ex(ctx,out,outl);
+       else    return EVP_DecryptFinal_ex(ctx,out,outl);
+       }
+
+int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+       {
+       if (ctx->encrypt)
+               return EVP_EncryptFinal(ctx,out,outl);
+       else    return EVP_DecryptFinal(ctx,out,outl);
+       }
+
+int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+            const unsigned char *key, const unsigned char *iv)
+       {
+       return EVP_CipherInit(ctx, cipher, key, iv, 1);
+       }
+
+int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
+               const unsigned char *key, const unsigned char *iv)
+       {
+       return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1);
+       }
+
+int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+            const unsigned char *key, const unsigned char *iv)
+       {
+       return EVP_CipherInit(ctx, cipher, key, iv, 0);
+       }
+
+int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
+            const unsigned char *key, const unsigned char *iv)
+       {
+       return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0);
+       }
+
+int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+            const unsigned char *in, int inl)
+       {
+       int i,j,bl;
+
+       OPENSSL_assert(inl > 0);
+       if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0)
+               {
+               if(ctx->cipher->do_cipher(ctx,out,in,inl))
+                       {
+                       *outl=inl;
+                       return 1;
+                       }
+               else
+                       {
+                       *outl=0;
+                       return 0;
+                       }
+               }
+       i=ctx->buf_len;
+       bl=ctx->cipher->block_size;
+       OPENSSL_assert(bl <= sizeof ctx->buf);
+       if (i != 0)
+               {
+               if (i+inl < bl)
+                       {
+                       memcpy(&(ctx->buf[i]),in,inl);
+                       ctx->buf_len+=inl;
+                       *outl=0;
+                       return 1;
+                       }
+               else
+                       {
+                       j=bl-i;
+                       memcpy(&(ctx->buf[i]),in,j);
+                       if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,bl)) return 0;
+                       inl-=j;
+                       in+=j;
+                       out+=bl;
+                       *outl=bl;
+                       }
+               }
+       else
+               *outl = 0;
+       i=inl&(bl-1);
+       inl-=i;
+       if (inl > 0)
+               {
+               if(!ctx->cipher->do_cipher(ctx,out,in,inl)) return 0;
+               *outl+=inl;
+               }
+
+       if (i != 0)
+               memcpy(ctx->buf,&(in[inl]),i);
+       ctx->buf_len=i;
+       return 1;
+       }
+
+int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+       {
+       int ret;
+       ret = EVP_EncryptFinal_ex(ctx, out, outl);
+       return ret;
+       }
+
+int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+       {
+       int i,n,b,bl,ret;
+
+       b=ctx->cipher->block_size;
+       OPENSSL_assert(b <= sizeof ctx->buf);
+       if (b == 1)
+               {
+               *outl=0;
+               return 1;
+               }
+       bl=ctx->buf_len;
+       if (ctx->flags & EVP_CIPH_NO_PADDING)
+               {
+               if(bl)
+                       {
+                       EVPerr(EVP_F_EVP_ENCRYPTFINAL,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
+                       return 0;
+                       }
+               *outl = 0;
+               return 1;
+               }
+
+       n=b-bl;
+       for (i=bl; i<b; i++)
+               ctx->buf[i]=n;
+       ret=ctx->cipher->do_cipher(ctx,out,ctx->buf,b);
+
+
+       if(ret)
+               *outl=b;
+
+       return ret;
+       }
+
+int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+            const unsigned char *in, int inl)
+       {
+       int b, fix_len;
+
+       if (inl == 0)
+               {
+               *outl=0;
+               return 1;
+               }
+
+       if (ctx->flags & EVP_CIPH_NO_PADDING)
+               return EVP_EncryptUpdate(ctx, out, outl, in, inl);
+
+       b=ctx->cipher->block_size;
+       OPENSSL_assert(b <= sizeof ctx->final);
+
+       if(ctx->final_used)
+               {
+               memcpy(out,ctx->final,b);
+               out+=b;
+               fix_len = 1;
+               }
+       else
+               fix_len = 0;
+
+
+       if(!EVP_EncryptUpdate(ctx,out,outl,in,inl))
+               return 0;
+
+       /* if we have 'decrypted' a multiple of block size, make sure
+        * we have a copy of this last block */
+       if (b > 1 && !ctx->buf_len)
+               {
+               *outl-=b;
+               ctx->final_used=1;
+               memcpy(ctx->final,&out[*outl],b);
+               }
+       else
+               ctx->final_used = 0;
+
+       if (fix_len)
+               *outl += b;
+               
+       return 1;
+       }
+
+int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+       {
+       int ret;
+       ret = EVP_DecryptFinal_ex(ctx, out, outl);
+       return ret;
+       }
+
+int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+       {
+       int i,b;
+       int n;
+
+       *outl=0;
+       b=ctx->cipher->block_size;
+       if (ctx->flags & EVP_CIPH_NO_PADDING)
+               {
+               if(ctx->buf_len)
+                       {
+                       EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
+                       return 0;
+                       }
+               *outl = 0;
+               return 1;
+               }
+       if (b > 1)
+               {
+               if (ctx->buf_len || !ctx->final_used)
+                       {
+                       // EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_WRONG_FINAL_BLOCK_LENGTH);
+                       // GrP fixme fix up error reporting!
+                       return(0);
+                       }
+               OPENSSL_assert(b <= sizeof ctx->final);
+               n=ctx->final[b-1];
+               if (n > b)
+                       {
+                       // EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_WRONG_FINAL_BLOCK_LENGTH);
+                       // GrP fixme fix up error reporting!
+                       return(0);
+                       }
+               for (i=0; i<n; i++)
+                       {
+                       if (ctx->final[--b] != n)
+                               {
+                               // EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_WRONG_FINAL_BLOCK_LENGTH);
+                               // GrP fixme fix up error reporting!
+                               return(0);
+                               }
+                       }
+               n=ctx->cipher->block_size-n;
+               for (i=0; i<n; i++)
+                       out[i]=ctx->final[i];
+               *outl=n;
+               }
+       else
+               *outl=0;
+       return(1);
+       }
+
+int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
+       {
+       if (c->cipher != NULL)
+               {
+               if(c->cipher->cleanup && !c->cipher->cleanup(c))
+                       return 0;
+               /* Cleanse cipher context data */
+               if (c->cipher_data)
+                       OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
+               }
+       if (c->cipher_data)
+               OPENSSL_free(c->cipher_data);
+#ifndef OPENSSL_NO_ENGINE
+       if (c->engine)
+               /* The EVP_CIPHER we used belongs to an ENGINE, release the
+                * functional reference we held for this reason. */
+               ENGINE_finish(c->engine);
+#endif
+       memset(c,0,sizeof(EVP_CIPHER_CTX));
+       return 1;
+       }
+
+int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
+       {
+       if(c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) 
+               return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL);
+       if(c->key_len == keylen) return 1;
+       if((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH))
+               {
+               c->key_len = keylen;
+               return 1;
+               }
+       EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH,EVP_R_INVALID_KEY_LENGTH);
+       return 0;
+       }
+
+int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
+       {
+       if (pad) ctx->flags &= ~EVP_CIPH_NO_PADDING;
+       else ctx->flags |= EVP_CIPH_NO_PADDING;
+       return 1;
+       }
+
+int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+{
+       int ret;
+       if(!ctx->cipher) {
+               EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
+               return 0;
+       }
+
+       if(!ctx->cipher->ctrl) {
+               EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
+               return 0;
+       }
+
+       ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
+       if(ret == -1) {
+               EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
+               return 0;
+       }
+       return ret;
+}
diff --git a/crypto/openssl/evp/evp_locl.h b/crypto/openssl/evp/evp_locl.h
new file mode 100644 (file)
index 0000000..bfef816
--- /dev/null
@@ -0,0 +1,260 @@
+/* evp_locl.h */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * 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).
+ *
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed BLOCK_CIPHER_func_* defines to emit a prototype that places 
+//     the function in EVP_SEGMENT
+// changed BLOCK_CIPHER_DEF1 to use hardcoded NID rather than nid 
+//     to fix macro expansion problems (fixme still necessary?)
+
+/* Macros to code block cipher wrappers */
+
+/* Wrapper functions for each cipher mode */
+
+#define BLOCK_CIPHER_ecb_loop() \
+       unsigned int i, bl; \
+       bl = ctx->cipher->block_size;\
+       if(inl < bl) return 1;\
+       inl -= bl; \
+       for(i=0; i <= inl; i+=bl) \
+
+#define BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \
+extern int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) EVP_SEGMENT; \
+static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \
+{\
+       BLOCK_CIPHER_ecb_loop() \
+               cprefix##_ecb_encrypt(in + i, out + i, &((kstruct *)ctx->cipher_data)->ksched, ctx->encrypt);\
+       return 1;\
+}
+
+#define BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched) \
+extern int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) EVP_SEGMENT; \
+static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \
+{\
+       cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\
+       return 1;\
+}
+
+#define BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \
+static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) EVP_SEGMENT; \
+static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \
+{\
+       cprefix##_cbc_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\
+       return 1;\
+}
+
+#define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \
+extern int cname##_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) EVP_SEGMENT; \
+static int cname##_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \
+{\
+       cprefix##_cfb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\
+       return 1;\
+}
+
+#define BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \
+       BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \
+       BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \
+       BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \
+       BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched)
+
+#define BLOCK_CIPHER_def1(cname, nmode, mode, MODE, kstruct, nid, block_size, \
+                         key_len, iv_len, flags, init_key, cleanup, \
+                         set_asn1, get_asn1, ctrl) \
+static const EVP_CIPHER cname##_##mode = { \
+       NID_##cname##_##nmode, block_size, key_len, iv_len, \
+       flags | EVP_CIPH_##MODE##_MODE, \
+       init_key, \
+       cname##_##mode##_cipher, \
+       cleanup, \
+       sizeof(kstruct), \
+       set_asn1, get_asn1,\
+       ctrl, \
+       NULL \
+}; \
+const EVP_CIPHER *EVP_##cname##_##mode(void) { return &cname##_##mode; }
+
+#define BLOCK_CIPHER_def_cbc(cname, kstruct, nid, block_size, key_len, \
+                            iv_len, flags, init_key, cleanup, set_asn1, \
+                            get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, cbc, cbc, CBC, kstruct, nid, block_size, key_len, \
+                 iv_len, flags, init_key, cleanup, set_asn1, get_asn1, ctrl)
+
+#define BLOCK_CIPHER_def_cfb(cname, kstruct, nid, key_len, \
+                            iv_len, cbits, flags, init_key, cleanup, \
+                            set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, cfb##cbits, cfb, CFB, kstruct, nid, 1, \
+                 key_len, iv_len, flags, init_key, cleanup, set_asn1, \
+                 get_asn1, ctrl)
+
+#define BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, \
+                            iv_len, cbits, flags, init_key, cleanup, \
+                            set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, ofb##cbits, ofb, OFB, kstruct, nid, 1, \
+                 key_len, iv_len, flags, init_key, cleanup, set_asn1, \
+                 get_asn1, ctrl)
+
+#define BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, \
+                            iv_len, flags, init_key, cleanup, set_asn1, \
+                            get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, ecb, ecb, ECB, kstruct, nid, block_size, key_len, \
+                 iv_len, flags, init_key, cleanup, set_asn1, get_asn1, ctrl)
+
+#define BLOCK_CIPHER_defs(cname, kstruct, \
+                         nid, block_size, key_len, iv_len, cbits, flags, \
+                         init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_cbc(cname, kstruct, nid, block_size, key_len, iv_len, flags, \
+                    init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_cfb(cname, kstruct, nid, key_len, iv_len, cbits, \
+                    flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, iv_len, cbits, \
+                    flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, iv_len, flags, \
+                    init_key, cleanup, set_asn1, get_asn1, ctrl)
+
+
+/*
+#define BLOCK_CIPHER_defs(cname, kstruct, \
+                               nid, block_size, key_len, iv_len, flags,\
+                                init_key, cleanup, set_asn1, get_asn1, ctrl)\
+static const EVP_CIPHER cname##_cbc = {\
+       nid##_cbc, block_size, key_len, iv_len, \
+       flags | EVP_CIPH_CBC_MODE,\
+       init_key,\
+       cname##_cbc_cipher,\
+       cleanup,\
+       sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+               sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+       set_asn1, get_asn1,\
+       ctrl, \
+       NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_cbc(void) { return &cname##_cbc; }\
+static const EVP_CIPHER cname##_cfb = {\
+       nid##_cfb64, 1, key_len, iv_len, \
+       flags | EVP_CIPH_CFB_MODE,\
+       init_key,\
+       cname##_cfb_cipher,\
+       cleanup,\
+       sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+               sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+       set_asn1, get_asn1,\
+       ctrl,\
+       NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_cfb(void) { return &cname##_cfb; }\
+static const EVP_CIPHER cname##_ofb = {\
+       nid##_ofb64, 1, key_len, iv_len, \
+       flags | EVP_CIPH_OFB_MODE,\
+       init_key,\
+       cname##_ofb_cipher,\
+       cleanup,\
+       sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+               sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+       set_asn1, get_asn1,\
+       ctrl,\
+       NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_ofb(void) { return &cname##_ofb; }\
+static const EVP_CIPHER cname##_ecb = {\
+       nid##_ecb, block_size, key_len, iv_len, \
+       flags | EVP_CIPH_ECB_MODE,\
+       init_key,\
+       cname##_ecb_cipher,\
+       cleanup,\
+       sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+               sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+       set_asn1, get_asn1,\
+       ctrl,\
+       NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; }
+*/
+
+#define IMPLEMENT_BLOCK_CIPHER(cname, ksched, cprefix, kstruct, nid, \
+                              block_size, key_len, iv_len, cbits, \
+                              flags, init_key, \
+                              cleanup, set_asn1, get_asn1, ctrl) \
+       BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \
+       BLOCK_CIPHER_defs(cname, kstruct, nid, block_size, key_len, iv_len, \
+                         cbits, flags, init_key, cleanup, set_asn1, \
+                         get_asn1, ctrl)
+
+#define EVP_C_DATA(kstruct, ctx)       ((kstruct *)(ctx)->cipher_data)
diff --git a/crypto/openssl/evp/m_md5.c b/crypto/openssl/evp/m_md5.c
new file mode 100644 (file)
index 0000000..cf19aeb
--- /dev/null
@@ -0,0 +1,120 @@
+/* crypto/evp/m_md5.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.]
+ */
+/**********
+ * Portions Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// trimmed public-key fields from md5_md initializer
+
+#ifndef OPENSSL_NO_MD5
+#include "cryptlib.h"
+#include "evp.h"
+#include "md5/md5.h"
+
+static int init(EVP_MD_CTX *ctx)
+       { return MD5_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,unsigned long count)
+       { return MD5_Update(ctx->md_data,data,count); }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+       { return MD5_Final(md,ctx->md_data); }
+
+static const EVP_MD md5_md=
+       {
+       NID_md5,
+       // NID_md5WithRSAEncryption,
+       MD5_DIGEST_LENGTH,
+       0,
+       init,
+       update,
+       final,
+       NULL,
+       NULL,
+       // EVP_PKEY_RSA_method,
+       MD5_CBLOCK,
+       sizeof(EVP_MD *)+sizeof(MD5_CTX),
+       };
+
+const EVP_MD *EVP_md5(void)
+       {
+       return(&md5_md);
+       }
+#endif
diff --git a/crypto/openssl/evp/m_sha1.c b/crypto/openssl/evp/m_sha1.c
new file mode 100644 (file)
index 0000000..830fc90
--- /dev/null
@@ -0,0 +1,120 @@
+/* crypto/evp/m_sha1.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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// changed EVP_MD sha1_md initializer to omit public-key fields
+
+#ifndef OPENSSL_NO_SHA
+#include "cryptlib.h"
+#include "evp.h"
+#include "objects/objects.h"
+
+static int init(EVP_MD_CTX *ctx)
+       { return SHA1_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,unsigned long count)
+       { return SHA1_Update(ctx->md_data,data,count); }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+       { return SHA1_Final(md,ctx->md_data); }
+
+static const EVP_MD sha1_md=
+       {
+       NID_sha1,
+       // NID_sha1WithRSAEncryption,
+       SHA_DIGEST_LENGTH,
+       0,
+       init,
+       update,
+       final,
+       NULL,
+       NULL,
+       // EVP_PKEY_RSA_method,
+       SHA_CBLOCK,
+       sizeof(EVP_MD *)+sizeof(SHA_CTX),
+       };
+
+const EVP_MD *EVP_sha1(void)
+       {
+       return(&sha1_md);
+       }
+#endif
diff --git a/crypto/openssl/hmac/hmac.c b/crypto/openssl/hmac/hmac.c
new file mode 100644 (file)
index 0000000..0bef0e9
--- /dev/null
@@ -0,0 +1,197 @@
+/* crypto/hmac/hmac.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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh: 
+// changed includes
+
+#include "hmac.h"
+#include "cryptlib.h"
+
+void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
+                 const EVP_MD *md, ENGINE *impl)
+       {
+       int i,j,reset=0;
+       unsigned char pad[HMAC_MAX_MD_CBLOCK];
+
+       if (md != NULL)
+               {
+               reset=1;
+               ctx->md=md;
+               }
+       else
+               md=ctx->md;
+
+       if (key != NULL)
+               {
+               reset=1;
+               j=EVP_MD_block_size(md);
+               OPENSSL_assert(j <= sizeof ctx->key);
+               if (j < len)
+                       {
+                       EVP_DigestInit_ex(&ctx->md_ctx,md, impl);
+                       EVP_DigestUpdate(&ctx->md_ctx,key,len);
+                       EVP_DigestFinal_ex(&(ctx->md_ctx),ctx->key,
+                               &ctx->key_length);
+                       }
+               else
+                       {
+                       OPENSSL_assert(len <= sizeof ctx->key);
+                       memcpy(ctx->key,key,len);
+                       ctx->key_length=len;
+                       }
+               if(ctx->key_length != HMAC_MAX_MD_CBLOCK)
+                       memset(&ctx->key[ctx->key_length], 0,
+                               HMAC_MAX_MD_CBLOCK - ctx->key_length);
+               }
+
+       if (reset)      
+               {
+               for (i=0; i<HMAC_MAX_MD_CBLOCK; i++)
+                       pad[i]=0x36^ctx->key[i];
+               EVP_DigestInit_ex(&ctx->i_ctx,md, impl);
+               EVP_DigestUpdate(&ctx->i_ctx,pad,EVP_MD_block_size(md));
+
+               for (i=0; i<HMAC_MAX_MD_CBLOCK; i++)
+                       pad[i]=0x5c^ctx->key[i];
+               EVP_DigestInit_ex(&ctx->o_ctx,md, impl);
+               EVP_DigestUpdate(&ctx->o_ctx,pad,EVP_MD_block_size(md));
+               }
+       EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->i_ctx);
+       }
+
+void HMAC_Init(HMAC_CTX *ctx, const void *key, int len,
+              const EVP_MD *md)
+       {
+       if(key && md)
+           HMAC_CTX_init(ctx);
+       HMAC_Init_ex(ctx,key,len,md, NULL);
+       }
+
+void HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, int len)
+       {
+       EVP_DigestUpdate(&ctx->md_ctx,data,len);
+       }
+
+void HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
+       {
+       int j;
+       unsigned int i;
+       unsigned char buf[EVP_MAX_MD_SIZE];
+
+       j=EVP_MD_block_size(ctx->md);
+
+       EVP_DigestFinal_ex(&ctx->md_ctx,buf,&i);
+       EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->o_ctx);
+       EVP_DigestUpdate(&ctx->md_ctx,buf,i);
+       EVP_DigestFinal_ex(&ctx->md_ctx,md,len);
+       }
+
+void HMAC_CTX_init(HMAC_CTX *ctx)
+       {
+       EVP_MD_CTX_init(&ctx->i_ctx);
+       EVP_MD_CTX_init(&ctx->o_ctx);
+       EVP_MD_CTX_init(&ctx->md_ctx);
+       }
+
+void HMAC_CTX_cleanup(HMAC_CTX *ctx)
+       {
+       EVP_MD_CTX_cleanup(&ctx->i_ctx);
+       EVP_MD_CTX_cleanup(&ctx->o_ctx);
+       EVP_MD_CTX_cleanup(&ctx->md_ctx);
+       memset(ctx,0,sizeof *ctx);
+       }
+
+unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
+                   const unsigned char *d, int n, unsigned char *md,
+                   unsigned int *md_len)
+       {
+       HMAC_CTX c;
+       static unsigned char m[EVP_MAX_MD_SIZE];
+
+       if (md == NULL) md=m;
+       HMAC_CTX_init(&c);
+       HMAC_Init(&c,key,key_len,evp_md);
+       HMAC_Update(&c,d,n);
+       HMAC_Final(&c,md,md_len);
+       HMAC_CTX_cleanup(&c);
+       return(md);
+       }
+
diff --git a/crypto/openssl/hmac/hmac.h b/crypto/openssl/hmac/hmac.h
new file mode 100644 (file)
index 0000000..7f966c2
--- /dev/null
@@ -0,0 +1,134 @@
+/* crypto/hmac/hmac.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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// added HMAC_SEGMENT everywhere
+
+#ifndef HEADER_HMAC_H
+#define HEADER_HMAC_H
+
+#ifdef OPENSSL_NO_HMAC
+#error HMAC is disabled.
+#endif
+
+#include "openssl/evp/evp.h"
+
+#define HMAC_MAX_MD_CBLOCK     64
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct hmac_ctx_st
+       {
+       const EVP_MD *md;
+       EVP_MD_CTX md_ctx;
+       EVP_MD_CTX i_ctx;
+       EVP_MD_CTX o_ctx;
+       unsigned int key_length;
+       unsigned char key[HMAC_MAX_MD_CBLOCK];
+       } HMAC_CTX;
+
+#define HMAC_size(e)   (EVP_MD_size((e)->md))
+
+
+void HMAC_CTX_init(HMAC_CTX *ctx) HMAC_SEGMENT;
+void HMAC_CTX_cleanup(HMAC_CTX *ctx) HMAC_SEGMENT;
+
+#define HMAC_cleanup(ctx) HMAC_CTX_cleanup(ctx) /* deprecated */
+
+void HMAC_Init(HMAC_CTX *ctx, const void *key, int len,
+              const EVP_MD *md) HMAC_SEGMENT; /* deprecated */
+void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
+                 const EVP_MD *md, ENGINE *impl) HMAC_SEGMENT;
+void HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, int len) HMAC_SEGMENT;
+void HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) HMAC_SEGMENT;
+unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
+                   const unsigned char *d, int n, unsigned char *md,
+                   unsigned int *md_len) HMAC_SEGMENT;
+
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/crypto/openssl/md32_common.h b/crypto/openssl/md32_common.h
new file mode 100644 (file)
index 0000000..5762597
--- /dev/null
@@ -0,0 +1,664 @@
+/* crypto/md32_common.h */
+/* ====================================================================
+ * Copyright (c) 1999-2002 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).
+ *
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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 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").
+ * HASH_MAKE_STRING
+ *     macro convering context variables to an ASCII hash string.
+ *
+ * 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>
+ */
+
+// GrP pssh:
+// changed static unsigned char end[4] to non-static 
+//     to avoid initialization problems
+
+#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 0 /* defined(_MSC_VER) */
+#  define ROTATE(a,n)  _lrotl(a,n)
+# elif defined(__MWERKS__)
+#  if defined(__POWERPC__)
+#   define ROTATE(a,n) __rlwinm(a,n,0,31)
+#  elif defined(__MC68K__)
+    /* Motorola specific tweak. <appro@fy.chalmers.se> */
+#   define ROTATE(a,n) ( n<24 ? __rol(a,n) : __ror(a,32-n) )
+#  else
+#   define ROTATE(a,n) __rol(a,n)
+#  endif
+# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+  /*
+   * 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) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
+#   define ROTATE(a,n) ({ register unsigned int ret;   \
+                               asm (                   \
+                               "roll %1,%0"            \
+                               : "=r"(ret)             \
+                               : "I"(n), "0"(a)        \
+                               : "cc");                \
+                          ret;                         \
+                       })
+#  elif defined(__powerpc) || defined(__ppc)
+#   define ROTATE(a,n) ({ register unsigned int ret;   \
+                               asm (                   \
+                               "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 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+  /* some GNU C inline assembler templates by <appro@fy.chalmers.se> */
+#  if (defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)) && !defined(I386_ONLY)
+#   define BE_FETCH32(a)       ({ register unsigned int l=(a);\
+                               asm (                   \
+                               "bswapl %0"             \
+                               : "=r"(l) : "0"(l));    \
+                         l;                            \
+                       })
+#  elif defined(__powerpc)
+#   define LE_FETCH32(a)       ({ register unsigned int l;     \
+                               asm (                   \
+                               "lwbrx %0,0,%1"         \
+                               : "=r"(l)               \
+                               : "r"(a));              \
+                          l;                           \
+                       })
+
+#  elif defined(__sparc) && defined(OPENSSL_SYS_ULTRASPARC)
+#  define LE_FETCH32(a)        ({ register unsigned int l;             \
+                               asm (                           \
+                               "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)
+#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:-)
+ */
+
+int HASH_UPDATE (HASH_CTX *c, const void *data_, unsigned long len)
+       {
+       const unsigned char *data=data_;
+       register HASH_LONG * p;
+       register unsigned long l;
+       int sw,sc,ew,ec;
+
+       if (len==0) return 1;
+
+       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);
+                               if (sc)
+                                       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 1;
+                       }
+               }
+
+       sw=len/HASH_CBLOCK;
+       if (sw > 0)
+               {
+#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
+               /*
+                * 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;
+               }
+       return 1;
+       }
+
+
+void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data)
+       {
+#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
+       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
+       }
+
+
+int HASH_FINAL (unsigned char *md, HASH_CTX *c)
+       {
+       register HASH_LONG *p;
+       register unsigned long l;
+       register int i,j;
+       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);
+
+#ifndef HASH_MAKE_STRING
+#error "HASH_MAKE_STRING must be defined!"
+#else
+       HASH_MAKE_STRING(c,md);
+#endif
+
+       c->num=0;
+       /* clear stuff, HASH_BLOCK may be leaving some stuff on the stack
+        * but I'm not worried :-)
+       OPENSSL_cleanse((void *)c,sizeof(HASH_CTX));
+        */
+       return 1;
+       }
+
+#ifndef MD32_REG_T
+#define MD32_REG_T long
+/*
+ * This comment was originaly written for MD5, which is why it
+ * discusses A-D. But it basically applies to all 32-bit digests,
+ * which is why it was moved to common header file.
+ *
+ * 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>
+ * Apparently there're LP64 compilers that generate better
+ * code if A-D are declared int. Most notably GCC-x86_64
+ * generates better code.
+ *                             <appro@fy.chalmers.se>
+ */
+#endif
diff --git a/crypto/openssl/md5/md5.h b/crypto/openssl/md5/md5.h
new file mode 100644 (file)
index 0000000..4e89dd5
--- /dev/null
@@ -0,0 +1,130 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// defined MD5_LONG properly
+
+#ifndef HEADER_MD5_H
+#define HEADER_MD5_H
+
+#include "crypto/openssl/cryptlib.h"
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_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.                       !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+#define MD5_LONG uint32_t
+
+#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;
+
+int MD5_Init(MD5_CTX *c) MD5_SEGMENT;
+int MD5_Update(MD5_CTX *c, const void *data, unsigned long len) MD5_SEGMENT;
+int MD5_Final(unsigned char *md, MD5_CTX *c) MD5_SEGMENT;
+unsigned char *MD5(const unsigned char *d, unsigned long n, unsigned char *md) MD5_SEGMENT;
+void MD5_Transform(MD5_CTX *c, const unsigned char *b) MD5_SEGMENT;
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/crypto/openssl/md5/md5_dgst.c b/crypto/openssl/md5/md5_dgst.c
new file mode 100644 (file)
index 0000000..8d99731
--- /dev/null
@@ -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.]
+ */
+/**********
+ * Portions Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+
+#include "cryptlib.h"
+#include "md5_locl.h"
+
+const 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
+
+int 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;
+       return 1;
+       }
+
+#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 MD32_REG_T A,B,C,D;
+
+       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
+#ifdef X
+#undef X
+#endif
+void md5_block_data_order (MD5_CTX *c, const void *data_, int num)
+       {
+       const unsigned char *data=data_;
+       register unsigned MD32_REG_T A,B,C,D,l;
+#ifndef MD32_XARRAY
+       /* See comment in crypto/sha/sha_locl.h for details. */
+       unsigned MD32_REG_T     XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
+                               XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
+# define X(i)  XX##i
+#else
+       MD5_LONG XX[MD5_LBLOCK];
+# define X(i)  XX[i]
+#endif
+
+       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/crypto/openssl/md5/md5_locl.h b/crypto/openssl/md5/md5_locl.h
new file mode 100644 (file)
index 0000000..b95fb2f
--- /dev/null
@@ -0,0 +1,150 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// strip asm
+
+#include "cryptlib.h"
+#include "md5.h"
+
+#ifndef MD5_LONG_LOG2
+#define MD5_LONG_LOG2 2 /* default to 32 bits */
+#endif
+
+void md5_block_host_order (MD5_CTX *c, const void *p,int num) MD5_SEGMENT;
+void md5_block_data_order (MD5_CTX *c, const void *p,int num) MD5_SEGMENT;
+
+#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_MAKE_STRING(c,s)   do {    \
+       unsigned long ll;               \
+       ll=(c)->A; HOST_l2c(ll,(s));    \
+       ll=(c)->B; HOST_l2c(ll,(s));    \
+       ll=(c)->C; HOST_l2c(ll,(s));    \
+       ll=(c)->D; HOST_l2c(ll,(s));    \
+       } while (0)
+#define HASH_BLOCK_HOST_ORDER  md5_block_host_order
+#define        HASH_BLOCK_DATA_ORDER   md5_block_data_order
+
+#include "md32_common.h"
+
+/*
+#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 optimizations
+ * 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/crypto/openssl/md5/md5_one.c b/crypto/openssl/md5/md5_one.c
new file mode 100644 (file)
index 0000000..4be8744
--- /dev/null
@@ -0,0 +1,101 @@
+/* crypto/md5/md5_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.]
+ */
+/**********
+ * Portions Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// stripped EBCDIC code
+
+#include "cryptlib.h"
+#include "md5.h"
+
+unsigned char *MD5(const unsigned char *d, unsigned long n, unsigned char *md)
+       {
+       MD5_CTX c;
+       static unsigned char m[MD5_DIGEST_LENGTH];
+
+       if (md == NULL) md=m;
+       MD5_Init(&c);
+       MD5_Update(&c,d,n);
+       MD5_Final(md,&c);
+       OPENSSL_cleanse(&c,sizeof(c)); /* security consideration */
+       return(md);
+       }
+
diff --git a/crypto/openssl/md5/md5test.c b/crypto/openssl/md5/md5test.c
new file mode 100644 (file)
index 0000000..bfd6262
--- /dev/null
@@ -0,0 +1,136 @@
+/* crypto/md5/md5test.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 <stdlib.h>
+
+#include "../e_os.h"
+
+#ifdef OPENSSL_NO_MD5
+int main(int argc, char *argv[])
+{
+    printf("No MD5 support\n");
+    return(0);
+}
+#else
+#include <openssl/evp.h>
+#include <openssl/md5.h>
+
+static char *test[]={
+       "",
+       "a",
+       "abc",
+       "message digest",
+       "abcdefghijklmnopqrstuvwxyz",
+       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+       "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
+       NULL,
+       };
+
+static char *ret[]={
+       "d41d8cd98f00b204e9800998ecf8427e",
+       "0cc175b9c0f1b6a831c399e269772661",
+       "900150983cd24fb0d6963f7d28e17f72",
+       "f96b697d7cb7938d525a2f31aaf161d0",
+       "c3fcd3d76192e4007dfb496cca67e13b",
+       "d174ab98d277d9f5a5611c2c9f419d9f",
+       "57edf4a22be3c955ac49da2e2107b67a",
+       };
+
+static char *pt(unsigned char *md);
+int main(int argc, char *argv[])
+       {
+       int i,err=0;
+       unsigned char **P,**R;
+       char *p;
+       unsigned char md[MD5_DIGEST_LENGTH];
+
+       P=(unsigned char **)test;
+       R=(unsigned char **)ret;
+       i=1;
+       while (*P != NULL)
+               {
+               EVP_Digest(&(P[0][0]),(unsigned long)strlen((char *)*P),md,NULL,EVP_md5(), NULL);
+               p=pt(md);
+               if (strcmp(p,(char *)*R) != 0)
+                       {
+                       printf("error calculating MD5 on '%s'\n",*P);
+                       printf("got %s instead of %s\n",p,*R);
+                       err++;
+                       }
+               else
+                       printf("test %d ok\n",i);
+               i++;
+               R++;
+               P++;
+               }
+       EXIT(err);
+       return(0);
+       }
+
+static char *pt(unsigned char *md)
+       {
+       int i;
+       static char buf[80];
+
+       for (i=0; i<MD5_DIGEST_LENGTH; i++)
+               sprintf(&(buf[i*2]),"%02x",md[i]);
+       return(buf);
+       }
+#endif
diff --git a/crypto/openssl/mem_clr.c b/crypto/openssl/mem_clr.c
new file mode 100644 (file)
index 0000000..06383c8
--- /dev/null
@@ -0,0 +1,101 @@
+/* crypto/mem_clr.c -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 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).
+ *
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// changed int cast to uintptr_t
+
+#include "includes.h"
+
+unsigned char cleanse_ctr = 0;
+
+void OPENSSL_cleanse(void *ptr, size_t len)
+       {
+       unsigned char *p = ptr;
+       size_t loop = len;
+       while(loop--)
+               {
+               *(p++) = cleanse_ctr;
+               cleanse_ctr += (17 + (unsigned char)((uintptr_t)p & 0xF));
+               }
+       if(memchr(ptr, cleanse_ctr, len))
+               cleanse_ctr += 63;
+       }
diff --git a/crypto/openssl/objects/obj_mac.h b/crypto/openssl/objects/obj_mac.h
new file mode 100644 (file)
index 0000000..7645012
--- /dev/null
@@ -0,0 +1,2868 @@
+/* crypto/objects/obj_mac.h */
+
+/* THIS FILE IS GENERATED FROM objects.txt by objects.pl via the
+ * following command:
+ * perl objects.pl objects.txt obj_mac.num obj_mac.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.]
+ */
+
+#define SN_undef                       "UNDEF"
+#define LN_undef                       "undefined"
+#define NID_undef                      0
+#define OBJ_undef                      0L
+
+#define SN_ccitt               "CCITT"
+#define LN_ccitt               "ccitt"
+#define NID_ccitt              404
+#define OBJ_ccitt              0L
+
+#define SN_iso         "ISO"
+#define LN_iso         "iso"
+#define NID_iso                181
+#define OBJ_iso                1L
+
+#define SN_joint_iso_ccitt             "JOINT-ISO-CCITT"
+#define LN_joint_iso_ccitt             "joint-iso-ccitt"
+#define NID_joint_iso_ccitt            393
+#define OBJ_joint_iso_ccitt            2L
+
+#define SN_member_body         "member-body"
+#define LN_member_body         "ISO Member Body"
+#define NID_member_body                182
+#define OBJ_member_body                OBJ_iso,2L
+
+#define SN_selected_attribute_types            "selected-attribute-types"
+#define LN_selected_attribute_types            "Selected Attribute Types"
+#define NID_selected_attribute_types           394
+#define OBJ_selected_attribute_types           OBJ_joint_iso_ccitt,5L,1L,5L
+
+#define SN_clearance           "clearance"
+#define NID_clearance          395
+#define OBJ_clearance          OBJ_selected_attribute_types,55L
+
+#define SN_ISO_US              "ISO-US"
+#define LN_ISO_US              "ISO US Member Body"
+#define NID_ISO_US             183
+#define OBJ_ISO_US             OBJ_member_body,840L
+
+#define SN_X9_57               "X9-57"
+#define LN_X9_57               "X9.57"
+#define NID_X9_57              184
+#define OBJ_X9_57              OBJ_ISO_US,10040L
+
+#define SN_X9cm                "X9cm"
+#define LN_X9cm                "X9.57 CM ?"
+#define NID_X9cm               185
+#define OBJ_X9cm               OBJ_X9_57,4L
+
+#define SN_dsa         "DSA"
+#define LN_dsa         "dsaEncryption"
+#define NID_dsa                116
+#define OBJ_dsa                OBJ_X9cm,1L
+
+#define SN_dsaWithSHA1         "DSA-SHA1"
+#define LN_dsaWithSHA1         "dsaWithSHA1"
+#define NID_dsaWithSHA1                113
+#define OBJ_dsaWithSHA1                OBJ_X9cm,3L
+
+#define SN_ansi_X9_62          "ansi-X9-62"
+#define LN_ansi_X9_62          "ANSI X9.62"
+#define NID_ansi_X9_62         405
+#define OBJ_ansi_X9_62         OBJ_ISO_US,10045L
+
+#define OBJ_X9_62_id_fieldType         OBJ_ansi_X9_62,1L
+
+#define SN_X9_62_prime_field           "prime-field"
+#define NID_X9_62_prime_field          406
+#define OBJ_X9_62_prime_field          OBJ_X9_62_id_fieldType,1L
+
+#define SN_X9_62_characteristic_two_field              "characteristic-two-field"
+#define NID_X9_62_characteristic_two_field             407
+#define OBJ_X9_62_characteristic_two_field             OBJ_X9_62_id_fieldType,2L
+
+#define OBJ_X9_62_id_publicKeyType             OBJ_ansi_X9_62,2L
+
+#define SN_X9_62_id_ecPublicKey                "id-ecPublicKey"
+#define NID_X9_62_id_ecPublicKey               408
+#define OBJ_X9_62_id_ecPublicKey               OBJ_X9_62_id_publicKeyType,1L
+
+#define OBJ_X9_62_ellipticCurve                OBJ_ansi_X9_62,3L
+
+#define OBJ_X9_62_c_TwoCurve           OBJ_X9_62_ellipticCurve,0L
+
+#define OBJ_X9_62_primeCurve           OBJ_X9_62_ellipticCurve,1L
+
+#define SN_X9_62_prime192v1            "prime192v1"
+#define NID_X9_62_prime192v1           409
+#define OBJ_X9_62_prime192v1           OBJ_X9_62_primeCurve,1L
+
+#define SN_X9_62_prime192v2            "prime192v2"
+#define NID_X9_62_prime192v2           410
+#define OBJ_X9_62_prime192v2           OBJ_X9_62_primeCurve,2L
+
+#define SN_X9_62_prime192v3            "prime192v3"
+#define NID_X9_62_prime192v3           411
+#define OBJ_X9_62_prime192v3           OBJ_X9_62_primeCurve,3L
+
+#define SN_X9_62_prime239v1            "prime239v1"
+#define NID_X9_62_prime239v1           412
+#define OBJ_X9_62_prime239v1           OBJ_X9_62_primeCurve,4L
+
+#define SN_X9_62_prime239v2            "prime239v2"
+#define NID_X9_62_prime239v2           413
+#define OBJ_X9_62_prime239v2           OBJ_X9_62_primeCurve,5L
+
+#define SN_X9_62_prime239v3            "prime239v3"
+#define NID_X9_62_prime239v3           414
+#define OBJ_X9_62_prime239v3           OBJ_X9_62_primeCurve,6L
+
+#define SN_X9_62_prime256v1            "prime256v1"
+#define NID_X9_62_prime256v1           415
+#define OBJ_X9_62_prime256v1           OBJ_X9_62_primeCurve,7L
+
+#define OBJ_X9_62_id_ecSigType         OBJ_ansi_X9_62,4L
+
+#define SN_ecdsa_with_SHA1             "ecdsa-with-SHA1"
+#define NID_ecdsa_with_SHA1            416
+#define OBJ_ecdsa_with_SHA1            OBJ_X9_62_id_ecSigType,1L
+
+#define SN_cast5_cbc           "CAST5-CBC"
+#define LN_cast5_cbc           "cast5-cbc"
+#define NID_cast5_cbc          108
+#define OBJ_cast5_cbc          OBJ_ISO_US,113533L,7L,66L,10L
+
+#define SN_cast5_ecb           "CAST5-ECB"
+#define LN_cast5_ecb           "cast5-ecb"
+#define NID_cast5_ecb          109
+
+#define SN_cast5_cfb64         "CAST5-CFB"
+#define LN_cast5_cfb64         "cast5-cfb"
+#define NID_cast5_cfb64                110
+
+#define SN_cast5_ofb64         "CAST5-OFB"
+#define LN_cast5_ofb64         "cast5-ofb"
+#define NID_cast5_ofb64                111
+
+#define LN_pbeWithMD5AndCast5_CBC              "pbeWithMD5AndCast5CBC"
+#define NID_pbeWithMD5AndCast5_CBC             112
+#define OBJ_pbeWithMD5AndCast5_CBC             OBJ_ISO_US,113533L,7L,66L,12L
+
+#define SN_rsadsi              "rsadsi"
+#define LN_rsadsi              "RSA Data Security, Inc."
+#define NID_rsadsi             1
+#define OBJ_rsadsi             OBJ_ISO_US,113549L
+
+#define SN_pkcs                "pkcs"
+#define LN_pkcs                "RSA Data Security, Inc. PKCS"
+#define NID_pkcs               2
+#define OBJ_pkcs               OBJ_rsadsi,1L
+
+#define SN_pkcs1               "pkcs1"
+#define NID_pkcs1              186
+#define OBJ_pkcs1              OBJ_pkcs,1L
+
+#define LN_rsaEncryption               "rsaEncryption"
+#define NID_rsaEncryption              6
+#define OBJ_rsaEncryption              OBJ_pkcs1,1L
+
+#define SN_md2WithRSAEncryption                "RSA-MD2"
+#define LN_md2WithRSAEncryption                "md2WithRSAEncryption"
+#define NID_md2WithRSAEncryption               7
+#define OBJ_md2WithRSAEncryption               OBJ_pkcs1,2L
+
+#define SN_md4WithRSAEncryption                "RSA-MD4"
+#define LN_md4WithRSAEncryption                "md4WithRSAEncryption"
+#define NID_md4WithRSAEncryption               396
+#define OBJ_md4WithRSAEncryption               OBJ_pkcs1,3L
+
+#define SN_md5WithRSAEncryption                "RSA-MD5"
+#define LN_md5WithRSAEncryption                "md5WithRSAEncryption"
+#define NID_md5WithRSAEncryption               8
+#define OBJ_md5WithRSAEncryption               OBJ_pkcs1,4L
+
+#define SN_sha1WithRSAEncryption               "RSA-SHA1"
+#define LN_sha1WithRSAEncryption               "sha1WithRSAEncryption"
+#define NID_sha1WithRSAEncryption              65
+#define OBJ_sha1WithRSAEncryption              OBJ_pkcs1,5L
+
+#define SN_pkcs3               "pkcs3"
+#define NID_pkcs3              27
+#define OBJ_pkcs3              OBJ_pkcs,3L
+
+#define LN_dhKeyAgreement              "dhKeyAgreement"
+#define NID_dhKeyAgreement             28
+#define OBJ_dhKeyAgreement             OBJ_pkcs3,1L
+
+#define SN_pkcs5               "pkcs5"
+#define NID_pkcs5              187
+#define OBJ_pkcs5              OBJ_pkcs,5L
+
+#define SN_pbeWithMD2AndDES_CBC                "PBE-MD2-DES"
+#define LN_pbeWithMD2AndDES_CBC                "pbeWithMD2AndDES-CBC"
+#define NID_pbeWithMD2AndDES_CBC               9
+#define OBJ_pbeWithMD2AndDES_CBC               OBJ_pkcs5,1L
+
+#define SN_pbeWithMD5AndDES_CBC                "PBE-MD5-DES"
+#define LN_pbeWithMD5AndDES_CBC                "pbeWithMD5AndDES-CBC"
+#define NID_pbeWithMD5AndDES_CBC               10
+#define OBJ_pbeWithMD5AndDES_CBC               OBJ_pkcs5,3L
+
+#define SN_pbeWithMD2AndRC2_CBC                "PBE-MD2-RC2-64"
+#define LN_pbeWithMD2AndRC2_CBC                "pbeWithMD2AndRC2-CBC"
+#define NID_pbeWithMD2AndRC2_CBC               168
+#define OBJ_pbeWithMD2AndRC2_CBC               OBJ_pkcs5,4L
+
+#define SN_pbeWithMD5AndRC2_CBC                "PBE-MD5-RC2-64"
+#define LN_pbeWithMD5AndRC2_CBC                "pbeWithMD5AndRC2-CBC"
+#define NID_pbeWithMD5AndRC2_CBC               169
+#define OBJ_pbeWithMD5AndRC2_CBC               OBJ_pkcs5,6L
+
+#define SN_pbeWithSHA1AndDES_CBC               "PBE-SHA1-DES"
+#define LN_pbeWithSHA1AndDES_CBC               "pbeWithSHA1AndDES-CBC"
+#define NID_pbeWithSHA1AndDES_CBC              170
+#define OBJ_pbeWithSHA1AndDES_CBC              OBJ_pkcs5,10L
+
+#define SN_pbeWithSHA1AndRC2_CBC               "PBE-SHA1-RC2-64"
+#define LN_pbeWithSHA1AndRC2_CBC               "pbeWithSHA1AndRC2-CBC"
+#define NID_pbeWithSHA1AndRC2_CBC              68
+#define OBJ_pbeWithSHA1AndRC2_CBC              OBJ_pkcs5,11L
+
+#define LN_id_pbkdf2           "PBKDF2"
+#define NID_id_pbkdf2          69
+#define OBJ_id_pbkdf2          OBJ_pkcs5,12L
+
+#define LN_pbes2               "PBES2"
+#define NID_pbes2              161
+#define OBJ_pbes2              OBJ_pkcs5,13L
+
+#define LN_pbmac1              "PBMAC1"
+#define NID_pbmac1             162
+#define OBJ_pbmac1             OBJ_pkcs5,14L
+
+#define SN_pkcs7               "pkcs7"
+#define NID_pkcs7              20
+#define OBJ_pkcs7              OBJ_pkcs,7L
+
+#define LN_pkcs7_data          "pkcs7-data"
+#define NID_pkcs7_data         21
+#define OBJ_pkcs7_data         OBJ_pkcs7,1L
+
+#define LN_pkcs7_signed                "pkcs7-signedData"
+#define NID_pkcs7_signed               22
+#define OBJ_pkcs7_signed               OBJ_pkcs7,2L
+
+#define LN_pkcs7_enveloped             "pkcs7-envelopedData"
+#define NID_pkcs7_enveloped            23
+#define OBJ_pkcs7_enveloped            OBJ_pkcs7,3L
+
+#define LN_pkcs7_signedAndEnveloped            "pkcs7-signedAndEnvelopedData"
+#define NID_pkcs7_signedAndEnveloped           24
+#define OBJ_pkcs7_signedAndEnveloped           OBJ_pkcs7,4L
+
+#define LN_pkcs7_digest                "pkcs7-digestData"
+#define NID_pkcs7_digest               25
+#define OBJ_pkcs7_digest               OBJ_pkcs7,5L
+
+#define LN_pkcs7_encrypted             "pkcs7-encryptedData"
+#define NID_pkcs7_encrypted            26
+#define OBJ_pkcs7_encrypted            OBJ_pkcs7,6L
+
+#define SN_pkcs9               "pkcs9"
+#define NID_pkcs9              47
+#define OBJ_pkcs9              OBJ_pkcs,9L
+
+#define LN_pkcs9_emailAddress          "emailAddress"
+#define NID_pkcs9_emailAddress         48
+#define OBJ_pkcs9_emailAddress         OBJ_pkcs9,1L
+
+#define LN_pkcs9_unstructuredName              "unstructuredName"
+#define NID_pkcs9_unstructuredName             49
+#define OBJ_pkcs9_unstructuredName             OBJ_pkcs9,2L
+
+#define LN_pkcs9_contentType           "contentType"
+#define NID_pkcs9_contentType          50
+#define OBJ_pkcs9_contentType          OBJ_pkcs9,3L
+
+#define LN_pkcs9_messageDigest         "messageDigest"
+#define NID_pkcs9_messageDigest                51
+#define OBJ_pkcs9_messageDigest                OBJ_pkcs9,4L
+
+#define LN_pkcs9_signingTime           "signingTime"
+#define NID_pkcs9_signingTime          52
+#define OBJ_pkcs9_signingTime          OBJ_pkcs9,5L
+
+#define LN_pkcs9_countersignature              "countersignature"
+#define NID_pkcs9_countersignature             53
+#define OBJ_pkcs9_countersignature             OBJ_pkcs9,6L
+
+#define LN_pkcs9_challengePassword             "challengePassword"
+#define NID_pkcs9_challengePassword            54
+#define OBJ_pkcs9_challengePassword            OBJ_pkcs9,7L
+
+#define LN_pkcs9_unstructuredAddress           "unstructuredAddress"
+#define NID_pkcs9_unstructuredAddress          55
+#define OBJ_pkcs9_unstructuredAddress          OBJ_pkcs9,8L
+
+#define LN_pkcs9_extCertAttributes             "extendedCertificateAttributes"
+#define NID_pkcs9_extCertAttributes            56
+#define OBJ_pkcs9_extCertAttributes            OBJ_pkcs9,9L
+
+#define SN_ext_req             "extReq"
+#define LN_ext_req             "Extension Request"
+#define NID_ext_req            172
+#define OBJ_ext_req            OBJ_pkcs9,14L
+
+#define SN_SMIMECapabilities           "SMIME-CAPS"
+#define LN_SMIMECapabilities           "S/MIME Capabilities"
+#define NID_SMIMECapabilities          167
+#define OBJ_SMIMECapabilities          OBJ_pkcs9,15L
+
+#define SN_SMIME               "SMIME"
+#define LN_SMIME               "S/MIME"
+#define NID_SMIME              188
+#define OBJ_SMIME              OBJ_pkcs9,16L
+
+#define SN_id_smime_mod                "id-smime-mod"
+#define NID_id_smime_mod               189
+#define OBJ_id_smime_mod               OBJ_SMIME,0L
+
+#define SN_id_smime_ct         "id-smime-ct"
+#define NID_id_smime_ct                190
+#define OBJ_id_smime_ct                OBJ_SMIME,1L
+
+#define SN_id_smime_aa         "id-smime-aa"
+#define NID_id_smime_aa                191
+#define OBJ_id_smime_aa                OBJ_SMIME,2L
+
+#define SN_id_smime_alg                "id-smime-alg"
+#define NID_id_smime_alg               192
+#define OBJ_id_smime_alg               OBJ_SMIME,3L
+
+#define SN_id_smime_cd         "id-smime-cd"
+#define NID_id_smime_cd                193
+#define OBJ_id_smime_cd                OBJ_SMIME,4L
+
+#define SN_id_smime_spq                "id-smime-spq"
+#define NID_id_smime_spq               194
+#define OBJ_id_smime_spq               OBJ_SMIME,5L
+
+#define SN_id_smime_cti                "id-smime-cti"
+#define NID_id_smime_cti               195
+#define OBJ_id_smime_cti               OBJ_SMIME,6L
+
+#define SN_id_smime_mod_cms            "id-smime-mod-cms"
+#define NID_id_smime_mod_cms           196
+#define OBJ_id_smime_mod_cms           OBJ_id_smime_mod,1L
+
+#define SN_id_smime_mod_ess            "id-smime-mod-ess"
+#define NID_id_smime_mod_ess           197
+#define OBJ_id_smime_mod_ess           OBJ_id_smime_mod,2L
+
+#define SN_id_smime_mod_oid            "id-smime-mod-oid"
+#define NID_id_smime_mod_oid           198
+#define OBJ_id_smime_mod_oid           OBJ_id_smime_mod,3L
+
+#define SN_id_smime_mod_msg_v3         "id-smime-mod-msg-v3"
+#define NID_id_smime_mod_msg_v3                199
+#define OBJ_id_smime_mod_msg_v3                OBJ_id_smime_mod,4L
+
+#define SN_id_smime_mod_ets_eSignature_88              "id-smime-mod-ets-eSignature-88"
+#define NID_id_smime_mod_ets_eSignature_88             200
+#define OBJ_id_smime_mod_ets_eSignature_88             OBJ_id_smime_mod,5L
+
+#define SN_id_smime_mod_ets_eSignature_97              "id-smime-mod-ets-eSignature-97"
+#define NID_id_smime_mod_ets_eSignature_97             201
+#define OBJ_id_smime_mod_ets_eSignature_97             OBJ_id_smime_mod,6L
+
+#define SN_id_smime_mod_ets_eSigPolicy_88              "id-smime-mod-ets-eSigPolicy-88"
+#define NID_id_smime_mod_ets_eSigPolicy_88             202
+#define OBJ_id_smime_mod_ets_eSigPolicy_88             OBJ_id_smime_mod,7L
+
+#define SN_id_smime_mod_ets_eSigPolicy_97              "id-smime-mod-ets-eSigPolicy-97"
+#define NID_id_smime_mod_ets_eSigPolicy_97             203
+#define OBJ_id_smime_mod_ets_eSigPolicy_97             OBJ_id_smime_mod,8L
+
+#define SN_id_smime_ct_receipt         "id-smime-ct-receipt"
+#define NID_id_smime_ct_receipt                204
+#define OBJ_id_smime_ct_receipt                OBJ_id_smime_ct,1L
+
+#define SN_id_smime_ct_authData                "id-smime-ct-authData"
+#define NID_id_smime_ct_authData               205
+#define OBJ_id_smime_ct_authData               OBJ_id_smime_ct,2L
+
+#define SN_id_smime_ct_publishCert             "id-smime-ct-publishCert"
+#define NID_id_smime_ct_publishCert            206
+#define OBJ_id_smime_ct_publishCert            OBJ_id_smime_ct,3L
+
+#define SN_id_smime_ct_TSTInfo         "id-smime-ct-TSTInfo"
+#define NID_id_smime_ct_TSTInfo                207
+#define OBJ_id_smime_ct_TSTInfo                OBJ_id_smime_ct,4L
+
+#define SN_id_smime_ct_TDTInfo         "id-smime-ct-TDTInfo"
+#define NID_id_smime_ct_TDTInfo                208
+#define OBJ_id_smime_ct_TDTInfo                OBJ_id_smime_ct,5L
+
+#define SN_id_smime_ct_contentInfo             "id-smime-ct-contentInfo"
+#define NID_id_smime_ct_contentInfo            209
+#define OBJ_id_smime_ct_contentInfo            OBJ_id_smime_ct,6L
+
+#define SN_id_smime_ct_DVCSRequestData         "id-smime-ct-DVCSRequestData"
+#define NID_id_smime_ct_DVCSRequestData                210
+#define OBJ_id_smime_ct_DVCSRequestData                OBJ_id_smime_ct,7L
+
+#define SN_id_smime_ct_DVCSResponseData                "id-smime-ct-DVCSResponseData"
+#define NID_id_smime_ct_DVCSResponseData               211
+#define OBJ_id_smime_ct_DVCSResponseData               OBJ_id_smime_ct,8L
+
+#define SN_id_smime_aa_receiptRequest          "id-smime-aa-receiptRequest"
+#define NID_id_smime_aa_receiptRequest         212
+#define OBJ_id_smime_aa_receiptRequest         OBJ_id_smime_aa,1L
+
+#define SN_id_smime_aa_securityLabel           "id-smime-aa-securityLabel"
+#define NID_id_smime_aa_securityLabel          213
+#define OBJ_id_smime_aa_securityLabel          OBJ_id_smime_aa,2L
+
+#define SN_id_smime_aa_mlExpandHistory         "id-smime-aa-mlExpandHistory"
+#define NID_id_smime_aa_mlExpandHistory                214
+#define OBJ_id_smime_aa_mlExpandHistory                OBJ_id_smime_aa,3L
+
+#define SN_id_smime_aa_contentHint             "id-smime-aa-contentHint"
+#define NID_id_smime_aa_contentHint            215
+#define OBJ_id_smime_aa_contentHint            OBJ_id_smime_aa,4L
+
+#define SN_id_smime_aa_msgSigDigest            "id-smime-aa-msgSigDigest"
+#define NID_id_smime_aa_msgSigDigest           216
+#define OBJ_id_smime_aa_msgSigDigest           OBJ_id_smime_aa,5L
+
+#define SN_id_smime_aa_encapContentType                "id-smime-aa-encapContentType"
+#define NID_id_smime_aa_encapContentType               217
+#define OBJ_id_smime_aa_encapContentType               OBJ_id_smime_aa,6L
+
+#define SN_id_smime_aa_contentIdentifier               "id-smime-aa-contentIdentifier"
+#define NID_id_smime_aa_contentIdentifier              218
+#define OBJ_id_smime_aa_contentIdentifier              OBJ_id_smime_aa,7L
+
+#define SN_id_smime_aa_macValue                "id-smime-aa-macValue"
+#define NID_id_smime_aa_macValue               219
+#define OBJ_id_smime_aa_macValue               OBJ_id_smime_aa,8L
+
+#define SN_id_smime_aa_equivalentLabels                "id-smime-aa-equivalentLabels"
+#define NID_id_smime_aa_equivalentLabels               220
+#define OBJ_id_smime_aa_equivalentLabels               OBJ_id_smime_aa,9L
+
+#define SN_id_smime_aa_contentReference                "id-smime-aa-contentReference"
+#define NID_id_smime_aa_contentReference               221
+#define OBJ_id_smime_aa_contentReference               OBJ_id_smime_aa,10L
+
+#define SN_id_smime_aa_encrypKeyPref           "id-smime-aa-encrypKeyPref"
+#define NID_id_smime_aa_encrypKeyPref          222
+#define OBJ_id_smime_aa_encrypKeyPref          OBJ_id_smime_aa,11L
+
+#define SN_id_smime_aa_signingCertificate              "id-smime-aa-signingCertificate"
+#define NID_id_smime_aa_signingCertificate             223
+#define OBJ_id_smime_aa_signingCertificate             OBJ_id_smime_aa,12L
+
+#define SN_id_smime_aa_smimeEncryptCerts               "id-smime-aa-smimeEncryptCerts"
+#define NID_id_smime_aa_smimeEncryptCerts              224
+#define OBJ_id_smime_aa_smimeEncryptCerts              OBJ_id_smime_aa,13L
+
+#define SN_id_smime_aa_timeStampToken          "id-smime-aa-timeStampToken"
+#define NID_id_smime_aa_timeStampToken         225
+#define OBJ_id_smime_aa_timeStampToken         OBJ_id_smime_aa,14L
+
+#define SN_id_smime_aa_ets_sigPolicyId         "id-smime-aa-ets-sigPolicyId"
+#define NID_id_smime_aa_ets_sigPolicyId                226
+#define OBJ_id_smime_aa_ets_sigPolicyId                OBJ_id_smime_aa,15L
+
+#define SN_id_smime_aa_ets_commitmentType              "id-smime-aa-ets-commitmentType"
+#define NID_id_smime_aa_ets_commitmentType             227
+#define OBJ_id_smime_aa_ets_commitmentType             OBJ_id_smime_aa,16L
+
+#define SN_id_smime_aa_ets_signerLocation              "id-smime-aa-ets-signerLocation"
+#define NID_id_smime_aa_ets_signerLocation             228
+#define OBJ_id_smime_aa_ets_signerLocation             OBJ_id_smime_aa,17L
+
+#define SN_id_smime_aa_ets_signerAttr          "id-smime-aa-ets-signerAttr"
+#define NID_id_smime_aa_ets_signerAttr         229
+#define OBJ_id_smime_aa_ets_signerAttr         OBJ_id_smime_aa,18L
+
+#define SN_id_smime_aa_ets_otherSigCert                "id-smime-aa-ets-otherSigCert"
+#define NID_id_smime_aa_ets_otherSigCert               230
+#define OBJ_id_smime_aa_ets_otherSigCert               OBJ_id_smime_aa,19L
+
+#define SN_id_smime_aa_ets_contentTimestamp            "id-smime-aa-ets-contentTimestamp"
+#define NID_id_smime_aa_ets_contentTimestamp           231
+#define OBJ_id_smime_aa_ets_contentTimestamp           OBJ_id_smime_aa,20L
+
+#define SN_id_smime_aa_ets_CertificateRefs             "id-smime-aa-ets-CertificateRefs"
+#define NID_id_smime_aa_ets_CertificateRefs            232
+#define OBJ_id_smime_aa_ets_CertificateRefs            OBJ_id_smime_aa,21L
+
+#define SN_id_smime_aa_ets_RevocationRefs              "id-smime-aa-ets-RevocationRefs"
+#define NID_id_smime_aa_ets_RevocationRefs             233
+#define OBJ_id_smime_aa_ets_RevocationRefs             OBJ_id_smime_aa,22L
+
+#define SN_id_smime_aa_ets_certValues          "id-smime-aa-ets-certValues"
+#define NID_id_smime_aa_ets_certValues         234
+#define OBJ_id_smime_aa_ets_certValues         OBJ_id_smime_aa,23L
+
+#define SN_id_smime_aa_ets_revocationValues            "id-smime-aa-ets-revocationValues"
+#define NID_id_smime_aa_ets_revocationValues           235
+#define OBJ_id_smime_aa_ets_revocationValues           OBJ_id_smime_aa,24L
+
+#define SN_id_smime_aa_ets_escTimeStamp                "id-smime-aa-ets-escTimeStamp"
+#define NID_id_smime_aa_ets_escTimeStamp               236
+#define OBJ_id_smime_aa_ets_escTimeStamp               OBJ_id_smime_aa,25L
+
+#define SN_id_smime_aa_ets_certCRLTimestamp            "id-smime-aa-ets-certCRLTimestamp"
+#define NID_id_smime_aa_ets_certCRLTimestamp           237
+#define OBJ_id_smime_aa_ets_certCRLTimestamp           OBJ_id_smime_aa,26L
+
+#define SN_id_smime_aa_ets_archiveTimeStamp            "id-smime-aa-ets-archiveTimeStamp"
+#define NID_id_smime_aa_ets_archiveTimeStamp           238
+#define OBJ_id_smime_aa_ets_archiveTimeStamp           OBJ_id_smime_aa,27L
+
+#define SN_id_smime_aa_signatureType           "id-smime-aa-signatureType"
+#define NID_id_smime_aa_signatureType          239
+#define OBJ_id_smime_aa_signatureType          OBJ_id_smime_aa,28L
+
+#define SN_id_smime_aa_dvcs_dvc                "id-smime-aa-dvcs-dvc"
+#define NID_id_smime_aa_dvcs_dvc               240
+#define OBJ_id_smime_aa_dvcs_dvc               OBJ_id_smime_aa,29L
+
+#define SN_id_smime_alg_ESDHwith3DES           "id-smime-alg-ESDHwith3DES"
+#define NID_id_smime_alg_ESDHwith3DES          241
+#define OBJ_id_smime_alg_ESDHwith3DES          OBJ_id_smime_alg,1L
+
+#define SN_id_smime_alg_ESDHwithRC2            "id-smime-alg-ESDHwithRC2"
+#define NID_id_smime_alg_ESDHwithRC2           242
+#define OBJ_id_smime_alg_ESDHwithRC2           OBJ_id_smime_alg,2L
+
+#define SN_id_smime_alg_3DESwrap               "id-smime-alg-3DESwrap"
+#define NID_id_smime_alg_3DESwrap              243
+#define OBJ_id_smime_alg_3DESwrap              OBJ_id_smime_alg,3L
+
+#define SN_id_smime_alg_RC2wrap                "id-smime-alg-RC2wrap"
+#define NID_id_smime_alg_RC2wrap               244
+#define OBJ_id_smime_alg_RC2wrap               OBJ_id_smime_alg,4L
+
+#define SN_id_smime_alg_ESDH           "id-smime-alg-ESDH"
+#define NID_id_smime_alg_ESDH          245
+#define OBJ_id_smime_alg_ESDH          OBJ_id_smime_alg,5L
+
+#define SN_id_smime_alg_CMS3DESwrap            "id-smime-alg-CMS3DESwrap"
+#define NID_id_smime_alg_CMS3DESwrap           246
+#define OBJ_id_smime_alg_CMS3DESwrap           OBJ_id_smime_alg,6L
+
+#define SN_id_smime_alg_CMSRC2wrap             "id-smime-alg-CMSRC2wrap"
+#define NID_id_smime_alg_CMSRC2wrap            247
+#define OBJ_id_smime_alg_CMSRC2wrap            OBJ_id_smime_alg,7L
+
+#define SN_id_smime_cd_ldap            "id-smime-cd-ldap"
+#define NID_id_smime_cd_ldap           248
+#define OBJ_id_smime_cd_ldap           OBJ_id_smime_cd,1L
+
+#define SN_id_smime_spq_ets_sqt_uri            "id-smime-spq-ets-sqt-uri"
+#define NID_id_smime_spq_ets_sqt_uri           249
+#define OBJ_id_smime_spq_ets_sqt_uri           OBJ_id_smime_spq,1L
+
+#define SN_id_smime_spq_ets_sqt_unotice                "id-smime-spq-ets-sqt-unotice"
+#define NID_id_smime_spq_ets_sqt_unotice               250
+#define OBJ_id_smime_spq_ets_sqt_unotice               OBJ_id_smime_spq,2L
+
+#define SN_id_smime_cti_ets_proofOfOrigin              "id-smime-cti-ets-proofOfOrigin"
+#define NID_id_smime_cti_ets_proofOfOrigin             251
+#define OBJ_id_smime_cti_ets_proofOfOrigin             OBJ_id_smime_cti,1L
+
+#define SN_id_smime_cti_ets_proofOfReceipt             "id-smime-cti-ets-proofOfReceipt"
+#define NID_id_smime_cti_ets_proofOfReceipt            252
+#define OBJ_id_smime_cti_ets_proofOfReceipt            OBJ_id_smime_cti,2L
+
+#define SN_id_smime_cti_ets_proofOfDelivery            "id-smime-cti-ets-proofOfDelivery"
+#define NID_id_smime_cti_ets_proofOfDelivery           253
+#define OBJ_id_smime_cti_ets_proofOfDelivery           OBJ_id_smime_cti,3L
+
+#define SN_id_smime_cti_ets_proofOfSender              "id-smime-cti-ets-proofOfSender"
+#define NID_id_smime_cti_ets_proofOfSender             254
+#define OBJ_id_smime_cti_ets_proofOfSender             OBJ_id_smime_cti,4L
+
+#define SN_id_smime_cti_ets_proofOfApproval            "id-smime-cti-ets-proofOfApproval"
+#define NID_id_smime_cti_ets_proofOfApproval           255
+#define OBJ_id_smime_cti_ets_proofOfApproval           OBJ_id_smime_cti,5L
+
+#define SN_id_smime_cti_ets_proofOfCreation            "id-smime-cti-ets-proofOfCreation"
+#define NID_id_smime_cti_ets_proofOfCreation           256
+#define OBJ_id_smime_cti_ets_proofOfCreation           OBJ_id_smime_cti,6L
+
+#define LN_friendlyName                "friendlyName"
+#define NID_friendlyName               156
+#define OBJ_friendlyName               OBJ_pkcs9,20L
+
+#define LN_localKeyID          "localKeyID"
+#define NID_localKeyID         157
+#define OBJ_localKeyID         OBJ_pkcs9,21L
+
+#define SN_ms_csp_name         "CSPName"
+#define LN_ms_csp_name         "Microsoft CSP Name"
+#define NID_ms_csp_name                417
+#define OBJ_ms_csp_name                1L,3L,6L,1L,4L,1L,311L,17L,1L
+
+#define OBJ_certTypes          OBJ_pkcs9,22L
+
+#define LN_x509Certificate             "x509Certificate"
+#define NID_x509Certificate            158
+#define OBJ_x509Certificate            OBJ_certTypes,1L
+
+#define LN_sdsiCertificate             "sdsiCertificate"
+#define NID_sdsiCertificate            159
+#define OBJ_sdsiCertificate            OBJ_certTypes,2L
+
+#define OBJ_crlTypes           OBJ_pkcs9,23L
+
+#define LN_x509Crl             "x509Crl"
+#define NID_x509Crl            160
+#define OBJ_x509Crl            OBJ_crlTypes,1L
+
+#define OBJ_pkcs12             OBJ_pkcs,12L
+
+#define OBJ_pkcs12_pbeids              OBJ_pkcs12,1L
+
+#define SN_pbe_WithSHA1And128BitRC4            "PBE-SHA1-RC4-128"
+#define LN_pbe_WithSHA1And128BitRC4            "pbeWithSHA1And128BitRC4"
+#define NID_pbe_WithSHA1And128BitRC4           144
+#define OBJ_pbe_WithSHA1And128BitRC4           OBJ_pkcs12_pbeids,1L
+
+#define SN_pbe_WithSHA1And40BitRC4             "PBE-SHA1-RC4-40"
+#define LN_pbe_WithSHA1And40BitRC4             "pbeWithSHA1And40BitRC4"
+#define NID_pbe_WithSHA1And40BitRC4            145
+#define OBJ_pbe_WithSHA1And40BitRC4            OBJ_pkcs12_pbeids,2L
+
+#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC          "PBE-SHA1-3DES"
+#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC          "pbeWithSHA1And3-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC         146
+#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC         OBJ_pkcs12_pbeids,3L
+
+#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC          "PBE-SHA1-2DES"
+#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC          "pbeWithSHA1And2-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC         147
+#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC         OBJ_pkcs12_pbeids,4L
+
+#define SN_pbe_WithSHA1And128BitRC2_CBC                "PBE-SHA1-RC2-128"
+#define LN_pbe_WithSHA1And128BitRC2_CBC                "pbeWithSHA1And128BitRC2-CBC"
+#define NID_pbe_WithSHA1And128BitRC2_CBC               148
+#define OBJ_pbe_WithSHA1And128BitRC2_CBC               OBJ_pkcs12_pbeids,5L
+
+#define SN_pbe_WithSHA1And40BitRC2_CBC         "PBE-SHA1-RC2-40"
+#define LN_pbe_WithSHA1And40BitRC2_CBC         "pbeWithSHA1And40BitRC2-CBC"
+#define NID_pbe_WithSHA1And40BitRC2_CBC                149
+#define OBJ_pbe_WithSHA1And40BitRC2_CBC                OBJ_pkcs12_pbeids,6L
+
+#define OBJ_pkcs12_Version1            OBJ_pkcs12,10L
+
+#define OBJ_pkcs12_BagIds              OBJ_pkcs12_Version1,1L
+
+#define LN_keyBag              "keyBag"
+#define NID_keyBag             150
+#define OBJ_keyBag             OBJ_pkcs12_BagIds,1L
+
+#define LN_pkcs8ShroudedKeyBag         "pkcs8ShroudedKeyBag"
+#define NID_pkcs8ShroudedKeyBag                151
+#define OBJ_pkcs8ShroudedKeyBag                OBJ_pkcs12_BagIds,2L
+
+#define LN_certBag             "certBag"
+#define NID_certBag            152
+#define OBJ_certBag            OBJ_pkcs12_BagIds,3L
+
+#define LN_crlBag              "crlBag"
+#define NID_crlBag             153
+#define OBJ_crlBag             OBJ_pkcs12_BagIds,4L
+
+#define LN_secretBag           "secretBag"
+#define NID_secretBag          154
+#define OBJ_secretBag          OBJ_pkcs12_BagIds,5L
+
+#define LN_safeContentsBag             "safeContentsBag"
+#define NID_safeContentsBag            155
+#define OBJ_safeContentsBag            OBJ_pkcs12_BagIds,6L
+
+#define SN_md2         "MD2"
+#define LN_md2         "md2"
+#define NID_md2                3
+#define OBJ_md2                OBJ_rsadsi,2L,2L
+
+#define SN_md4         "MD4"
+#define LN_md4         "md4"
+#define NID_md4                257
+#define OBJ_md4                OBJ_rsadsi,2L,4L
+
+#define SN_md5         "MD5"
+#define LN_md5         "md5"
+#define NID_md5                4
+#define OBJ_md5                OBJ_rsadsi,2L,5L
+
+#define SN_md5_sha1            "MD5-SHA1"
+#define LN_md5_sha1            "md5-sha1"
+#define NID_md5_sha1           114
+
+#define LN_hmacWithSHA1                "hmacWithSHA1"
+#define NID_hmacWithSHA1               163
+#define OBJ_hmacWithSHA1               OBJ_rsadsi,2L,7L
+
+#define SN_rc2_cbc             "RC2-CBC"
+#define LN_rc2_cbc             "rc2-cbc"
+#define NID_rc2_cbc            37
+#define OBJ_rc2_cbc            OBJ_rsadsi,3L,2L
+
+#define SN_rc2_ecb             "RC2-ECB"
+#define LN_rc2_ecb             "rc2-ecb"
+#define NID_rc2_ecb            38
+
+#define SN_rc2_cfb64           "RC2-CFB"
+#define LN_rc2_cfb64           "rc2-cfb"
+#define NID_rc2_cfb64          39
+
+#define SN_rc2_ofb64           "RC2-OFB"
+#define LN_rc2_ofb64           "rc2-ofb"
+#define NID_rc2_ofb64          40
+
+#define SN_rc2_40_cbc          "RC2-40-CBC"
+#define LN_rc2_40_cbc          "rc2-40-cbc"
+#define NID_rc2_40_cbc         98
+
+#define SN_rc2_64_cbc          "RC2-64-CBC"
+#define LN_rc2_64_cbc          "rc2-64-cbc"
+#define NID_rc2_64_cbc         166
+
+#define SN_rc4         "RC4"
+#define LN_rc4         "rc4"
+#define NID_rc4                5
+#define OBJ_rc4                OBJ_rsadsi,3L,4L
+
+#define SN_rc4_40              "RC4-40"
+#define LN_rc4_40              "rc4-40"
+#define NID_rc4_40             97
+
+#define SN_des_ede3_cbc                "DES-EDE3-CBC"
+#define LN_des_ede3_cbc                "des-ede3-cbc"
+#define NID_des_ede3_cbc               44
+#define OBJ_des_ede3_cbc               OBJ_rsadsi,3L,7L
+
+#define SN_rc5_cbc             "RC5-CBC"
+#define LN_rc5_cbc             "rc5-cbc"
+#define NID_rc5_cbc            120
+#define OBJ_rc5_cbc            OBJ_rsadsi,3L,8L
+
+#define SN_rc5_ecb             "RC5-ECB"
+#define LN_rc5_ecb             "rc5-ecb"
+#define NID_rc5_ecb            121
+
+#define SN_rc5_cfb64           "RC5-CFB"
+#define LN_rc5_cfb64           "rc5-cfb"
+#define NID_rc5_cfb64          122
+
+#define SN_rc5_ofb64           "RC5-OFB"
+#define LN_rc5_ofb64           "rc5-ofb"
+#define NID_rc5_ofb64          123
+
+#define SN_ms_ext_req          "msExtReq"
+#define LN_ms_ext_req          "Microsoft Extension Request"
+#define NID_ms_ext_req         171
+#define OBJ_ms_ext_req         1L,3L,6L,1L,4L,1L,311L,2L,1L,14L
+
+#define SN_ms_code_ind         "msCodeInd"
+#define LN_ms_code_ind         "Microsoft Individual Code Signing"
+#define NID_ms_code_ind                134
+#define OBJ_ms_code_ind                1L,3L,6L,1L,4L,1L,311L,2L,1L,21L
+
+#define SN_ms_code_com         "msCodeCom"
+#define LN_ms_code_com         "Microsoft Commercial Code Signing"
+#define NID_ms_code_com                135
+#define OBJ_ms_code_com                1L,3L,6L,1L,4L,1L,311L,2L,1L,22L
+
+#define SN_ms_ctl_sign         "msCTLSign"
+#define LN_ms_ctl_sign         "Microsoft Trust List Signing"
+#define NID_ms_ctl_sign                136
+#define OBJ_ms_ctl_sign                1L,3L,6L,1L,4L,1L,311L,10L,3L,1L
+
+#define SN_ms_sgc              "msSGC"
+#define LN_ms_sgc              "Microsoft Server Gated Crypto"
+#define NID_ms_sgc             137
+#define OBJ_ms_sgc             1L,3L,6L,1L,4L,1L,311L,10L,3L,3L
+
+#define SN_ms_efs              "msEFS"
+#define LN_ms_efs              "Microsoft Encrypted File System"
+#define NID_ms_efs             138
+#define OBJ_ms_efs             1L,3L,6L,1L,4L,1L,311L,10L,3L,4L
+
+#define SN_ms_smartcard_login          "msSmartcardLogin"
+#define LN_ms_smartcard_login          "Microsoft Smartcardlogin"
+#define NID_ms_smartcard_login         648
+#define OBJ_ms_smartcard_login         1L,3L,6L,1L,4L,1L,311L,20L,2L,2L
+
+#define SN_ms_upn              "msUPN"
+#define LN_ms_upn              "Microsoft Universal Principal Name"
+#define NID_ms_upn             649
+#define OBJ_ms_upn             1L,3L,6L,1L,4L,1L,311L,20L,2L,3L
+
+#define SN_idea_cbc            "IDEA-CBC"
+#define LN_idea_cbc            "idea-cbc"
+#define NID_idea_cbc           34
+#define OBJ_idea_cbc           1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L
+
+#define SN_idea_ecb            "IDEA-ECB"
+#define LN_idea_ecb            "idea-ecb"
+#define NID_idea_ecb           36
+
+#define SN_idea_cfb64          "IDEA-CFB"
+#define LN_idea_cfb64          "idea-cfb"
+#define NID_idea_cfb64         35
+
+#define SN_idea_ofb64          "IDEA-OFB"
+#define LN_idea_ofb64          "idea-ofb"
+#define NID_idea_ofb64         46
+
+#define SN_bf_cbc              "BF-CBC"
+#define LN_bf_cbc              "bf-cbc"
+#define NID_bf_cbc             91
+#define OBJ_bf_cbc             1L,3L,6L,1L,4L,1L,3029L,1L,2L
+
+#define SN_bf_ecb              "BF-ECB"
+#define LN_bf_ecb              "bf-ecb"
+#define NID_bf_ecb             92
+
+#define SN_bf_cfb64            "BF-CFB"
+#define LN_bf_cfb64            "bf-cfb"
+#define NID_bf_cfb64           93
+
+#define SN_bf_ofb64            "BF-OFB"
+#define LN_bf_ofb64            "bf-ofb"
+#define NID_bf_ofb64           94
+
+#define SN_id_pkix             "PKIX"
+#define NID_id_pkix            127
+#define OBJ_id_pkix            1L,3L,6L,1L,5L,5L,7L
+
+#define SN_id_pkix_mod         "id-pkix-mod"
+#define NID_id_pkix_mod                258
+#define OBJ_id_pkix_mod                OBJ_id_pkix,0L
+
+#define SN_id_pe               "id-pe"
+#define NID_id_pe              175
+#define OBJ_id_pe              OBJ_id_pkix,1L
+
+#define SN_id_qt               "id-qt"
+#define NID_id_qt              259
+#define OBJ_id_qt              OBJ_id_pkix,2L
+
+#define SN_id_kp               "id-kp"
+#define NID_id_kp              128
+#define OBJ_id_kp              OBJ_id_pkix,3L
+
+#define SN_id_it               "id-it"
+#define NID_id_it              260
+#define OBJ_id_it              OBJ_id_pkix,4L
+
+#define SN_id_pkip             "id-pkip"
+#define NID_id_pkip            261
+#define OBJ_id_pkip            OBJ_id_pkix,5L
+
+#define SN_id_alg              "id-alg"
+#define NID_id_alg             262
+#define OBJ_id_alg             OBJ_id_pkix,6L
+
+#define SN_id_cmc              "id-cmc"
+#define NID_id_cmc             263
+#define OBJ_id_cmc             OBJ_id_pkix,7L
+
+#define SN_id_on               "id-on"
+#define NID_id_on              264
+#define OBJ_id_on              OBJ_id_pkix,8L
+
+#define SN_id_pda              "id-pda"
+#define NID_id_pda             265
+#define OBJ_id_pda             OBJ_id_pkix,9L
+
+#define SN_id_aca              "id-aca"
+#define NID_id_aca             266
+#define OBJ_id_aca             OBJ_id_pkix,10L
+
+#define SN_id_qcs              "id-qcs"
+#define NID_id_qcs             267
+#define OBJ_id_qcs             OBJ_id_pkix,11L
+
+#define SN_id_cct              "id-cct"
+#define NID_id_cct             268
+#define OBJ_id_cct             OBJ_id_pkix,12L
+
+#define SN_id_ad               "id-ad"
+#define NID_id_ad              176
+#define OBJ_id_ad              OBJ_id_pkix,48L
+
+#define SN_id_pkix1_explicit_88                "id-pkix1-explicit-88"
+#define NID_id_pkix1_explicit_88               269
+#define OBJ_id_pkix1_explicit_88               OBJ_id_pkix_mod,1L
+
+#define SN_id_pkix1_implicit_88                "id-pkix1-implicit-88"
+#define NID_id_pkix1_implicit_88               270
+#define OBJ_id_pkix1_implicit_88               OBJ_id_pkix_mod,2L
+
+#define SN_id_pkix1_explicit_93                "id-pkix1-explicit-93"
+#define NID_id_pkix1_explicit_93               271
+#define OBJ_id_pkix1_explicit_93               OBJ_id_pkix_mod,3L
+
+#define SN_id_pkix1_implicit_93                "id-pkix1-implicit-93"
+#define NID_id_pkix1_implicit_93               272
+#define OBJ_id_pkix1_implicit_93               OBJ_id_pkix_mod,4L
+
+#define SN_id_mod_crmf         "id-mod-crmf"
+#define NID_id_mod_crmf                273
+#define OBJ_id_mod_crmf                OBJ_id_pkix_mod,5L
+
+#define SN_id_mod_cmc          "id-mod-cmc"
+#define NID_id_mod_cmc         274
+#define OBJ_id_mod_cmc         OBJ_id_pkix_mod,6L
+
+#define SN_id_mod_kea_profile_88               "id-mod-kea-profile-88"
+#define NID_id_mod_kea_profile_88              275
+#define OBJ_id_mod_kea_profile_88              OBJ_id_pkix_mod,7L
+
+#define SN_id_mod_kea_profile_93               "id-mod-kea-profile-93"
+#define NID_id_mod_kea_profile_93              276
+#define OBJ_id_mod_kea_profile_93              OBJ_id_pkix_mod,8L
+
+#define SN_id_mod_cmp          "id-mod-cmp"
+#define NID_id_mod_cmp         277
+#define OBJ_id_mod_cmp         OBJ_id_pkix_mod,9L
+
+#define SN_id_mod_qualified_cert_88            "id-mod-qualified-cert-88"
+#define NID_id_mod_qualified_cert_88           278
+#define OBJ_id_mod_qualified_cert_88           OBJ_id_pkix_mod,10L
+
+#define SN_id_mod_qualified_cert_93            "id-mod-qualified-cert-93"
+#define NID_id_mod_qualified_cert_93           279
+#define OBJ_id_mod_qualified_cert_93           OBJ_id_pkix_mod,11L
+
+#define SN_id_mod_attribute_cert               "id-mod-attribute-cert"
+#define NID_id_mod_attribute_cert              280
+#define OBJ_id_mod_attribute_cert              OBJ_id_pkix_mod,12L
+
+#define SN_id_mod_timestamp_protocol           "id-mod-timestamp-protocol"
+#define NID_id_mod_timestamp_protocol          281
+#define OBJ_id_mod_timestamp_protocol          OBJ_id_pkix_mod,13L
+
+#define SN_id_mod_ocsp         "id-mod-ocsp"
+#define NID_id_mod_ocsp                282
+#define OBJ_id_mod_ocsp                OBJ_id_pkix_mod,14L
+
+#define SN_id_mod_dvcs         "id-mod-dvcs"
+#define NID_id_mod_dvcs                283
+#define OBJ_id_mod_dvcs                OBJ_id_pkix_mod,15L
+
+#define SN_id_mod_cmp2000              "id-mod-cmp2000"
+#define NID_id_mod_cmp2000             284
+#define OBJ_id_mod_cmp2000             OBJ_id_pkix_mod,16L
+
+#define SN_info_access         "authorityInfoAccess"
+#define LN_info_access         "Authority Information Access"
+#define NID_info_access                177
+#define OBJ_info_access                OBJ_id_pe,1L
+
+#define SN_biometricInfo               "biometricInfo"
+#define LN_biometricInfo               "Biometric Info"
+#define NID_biometricInfo              285
+#define OBJ_biometricInfo              OBJ_id_pe,2L
+
+#define SN_qcStatements                "qcStatements"
+#define NID_qcStatements               286
+#define OBJ_qcStatements               OBJ_id_pe,3L
+
+#define SN_ac_auditEntity              "ac-auditEntity"
+#define NID_ac_auditEntity             287
+#define OBJ_ac_auditEntity             OBJ_id_pe,4L
+
+#define SN_ac_targeting                "ac-targeting"
+#define NID_ac_targeting               288
+#define OBJ_ac_targeting               OBJ_id_pe,5L
+
+#define SN_aaControls          "aaControls"
+#define NID_aaControls         289
+#define OBJ_aaControls         OBJ_id_pe,6L
+
+#define SN_sbqp_ipAddrBlock            "sbqp-ipAddrBlock"
+#define NID_sbqp_ipAddrBlock           290
+#define OBJ_sbqp_ipAddrBlock           OBJ_id_pe,7L
+
+#define SN_sbqp_autonomousSysNum               "sbqp-autonomousSysNum"
+#define NID_sbqp_autonomousSysNum              291
+#define OBJ_sbqp_autonomousSysNum              OBJ_id_pe,8L
+
+#define SN_sbqp_routerIdentifier               "sbqp-routerIdentifier"
+#define NID_sbqp_routerIdentifier              292
+#define OBJ_sbqp_routerIdentifier              OBJ_id_pe,9L
+
+#define SN_ac_proxying         "ac-proxying"
+#define NID_ac_proxying                397
+#define OBJ_ac_proxying                OBJ_id_pe,10L
+
+#define SN_sinfo_access                "subjectInfoAccess"
+#define LN_sinfo_access                "Subject Information Access"
+#define NID_sinfo_access               398
+#define OBJ_sinfo_access               OBJ_id_pe,11L
+
+#define SN_id_qt_cps           "id-qt-cps"
+#define LN_id_qt_cps           "Policy Qualifier CPS"
+#define NID_id_qt_cps          164
+#define OBJ_id_qt_cps          OBJ_id_qt,1L
+
+#define SN_id_qt_unotice               "id-qt-unotice"
+#define LN_id_qt_unotice               "Policy Qualifier User Notice"
+#define NID_id_qt_unotice              165
+#define OBJ_id_qt_unotice              OBJ_id_qt,2L
+
+#define SN_textNotice          "textNotice"
+#define NID_textNotice         293
+#define OBJ_textNotice         OBJ_id_qt,3L
+
+#define SN_server_auth         "serverAuth"
+#define LN_server_auth         "TLS Web Server Authentication"
+#define NID_server_auth                129
+#define OBJ_server_auth                OBJ_id_kp,1L
+
+#define SN_client_auth         "clientAuth"
+#define LN_client_auth         "TLS Web Client Authentication"
+#define NID_client_auth                130
+#define OBJ_client_auth                OBJ_id_kp,2L
+
+#define SN_code_sign           "codeSigning"
+#define LN_code_sign           "Code Signing"
+#define NID_code_sign          131
+#define OBJ_code_sign          OBJ_id_kp,3L
+
+#define SN_email_protect               "emailProtection"
+#define LN_email_protect               "E-mail Protection"
+#define NID_email_protect              132
+#define OBJ_email_protect              OBJ_id_kp,4L
+
+#define SN_ipsecEndSystem              "ipsecEndSystem"
+#define LN_ipsecEndSystem              "IPSec End System"
+#define NID_ipsecEndSystem             294
+#define OBJ_ipsecEndSystem             OBJ_id_kp,5L
+
+#define SN_ipsecTunnel         "ipsecTunnel"
+#define LN_ipsecTunnel         "IPSec Tunnel"
+#define NID_ipsecTunnel                295
+#define OBJ_ipsecTunnel                OBJ_id_kp,6L
+
+#define SN_ipsecUser           "ipsecUser"
+#define LN_ipsecUser           "IPSec User"
+#define NID_ipsecUser          296
+#define OBJ_ipsecUser          OBJ_id_kp,7L
+
+#define SN_time_stamp          "timeStamping"
+#define LN_time_stamp          "Time Stamping"
+#define NID_time_stamp         133
+#define OBJ_time_stamp         OBJ_id_kp,8L
+
+#define SN_OCSP_sign           "OCSPSigning"
+#define LN_OCSP_sign           "OCSP Signing"
+#define NID_OCSP_sign          180
+#define OBJ_OCSP_sign          OBJ_id_kp,9L
+
+#define SN_dvcs                "DVCS"
+#define LN_dvcs                "dvcs"
+#define NID_dvcs               297
+#define OBJ_dvcs               OBJ_id_kp,10L
+
+#define SN_id_it_caProtEncCert         "id-it-caProtEncCert"
+#define NID_id_it_caProtEncCert                298
+#define OBJ_id_it_caProtEncCert                OBJ_id_it,1L
+
+#define SN_id_it_signKeyPairTypes              "id-it-signKeyPairTypes"
+#define NID_id_it_signKeyPairTypes             299
+#define OBJ_id_it_signKeyPairTypes             OBJ_id_it,2L
+
+#define SN_id_it_encKeyPairTypes               "id-it-encKeyPairTypes"
+#define NID_id_it_encKeyPairTypes              300
+#define OBJ_id_it_encKeyPairTypes              OBJ_id_it,3L
+
+#define SN_id_it_preferredSymmAlg              "id-it-preferredSymmAlg"
+#define NID_id_it_preferredSymmAlg             301
+#define OBJ_id_it_preferredSymmAlg             OBJ_id_it,4L
+
+#define SN_id_it_caKeyUpdateInfo               "id-it-caKeyUpdateInfo"
+#define NID_id_it_caKeyUpdateInfo              302
+#define OBJ_id_it_caKeyUpdateInfo              OBJ_id_it,5L
+
+#define SN_id_it_currentCRL            "id-it-currentCRL"
+#define NID_id_it_currentCRL           303
+#define OBJ_id_it_currentCRL           OBJ_id_it,6L
+
+#define SN_id_it_unsupportedOIDs               "id-it-unsupportedOIDs"
+#define NID_id_it_unsupportedOIDs              304
+#define OBJ_id_it_unsupportedOIDs              OBJ_id_it,7L
+
+#define SN_id_it_subscriptionRequest           "id-it-subscriptionRequest"
+#define NID_id_it_subscriptionRequest          305
+#define OBJ_id_it_subscriptionRequest          OBJ_id_it,8L
+
+#define SN_id_it_subscriptionResponse          "id-it-subscriptionResponse"
+#define NID_id_it_subscriptionResponse         306
+#define OBJ_id_it_subscriptionResponse         OBJ_id_it,9L
+
+#define SN_id_it_keyPairParamReq               "id-it-keyPairParamReq"
+#define NID_id_it_keyPairParamReq              307
+#define OBJ_id_it_keyPairParamReq              OBJ_id_it,10L
+
+#define SN_id_it_keyPairParamRep               "id-it-keyPairParamRep"
+#define NID_id_it_keyPairParamRep              308
+#define OBJ_id_it_keyPairParamRep              OBJ_id_it,11L
+
+#define SN_id_it_revPassphrase         "id-it-revPassphrase"
+#define NID_id_it_revPassphrase                309
+#define OBJ_id_it_revPassphrase                OBJ_id_it,12L
+
+#define SN_id_it_implicitConfirm               "id-it-implicitConfirm"
+#define NID_id_it_implicitConfirm              310
+#define OBJ_id_it_implicitConfirm              OBJ_id_it,13L
+
+#define SN_id_it_confirmWaitTime               "id-it-confirmWaitTime"
+#define NID_id_it_confirmWaitTime              311
+#define OBJ_id_it_confirmWaitTime              OBJ_id_it,14L
+
+#define SN_id_it_origPKIMessage                "id-it-origPKIMessage"
+#define NID_id_it_origPKIMessage               312
+#define OBJ_id_it_origPKIMessage               OBJ_id_it,15L
+
+#define SN_id_regCtrl          "id-regCtrl"
+#define NID_id_regCtrl         313
+#define OBJ_id_regCtrl         OBJ_id_pkip,1L
+
+#define SN_id_regInfo          "id-regInfo"
+#define NID_id_regInfo         314
+#define OBJ_id_regInfo         OBJ_id_pkip,2L
+
+#define SN_id_regCtrl_regToken         "id-regCtrl-regToken"
+#define NID_id_regCtrl_regToken                315
+#define OBJ_id_regCtrl_regToken                OBJ_id_regCtrl,1L
+
+#define SN_id_regCtrl_authenticator            "id-regCtrl-authenticator"
+#define NID_id_regCtrl_authenticator           316
+#define OBJ_id_regCtrl_authenticator           OBJ_id_regCtrl,2L
+
+#define SN_id_regCtrl_pkiPublicationInfo               "id-regCtrl-pkiPublicationInfo"
+#define NID_id_regCtrl_pkiPublicationInfo              317
+#define OBJ_id_regCtrl_pkiPublicationInfo              OBJ_id_regCtrl,3L
+
+#define SN_id_regCtrl_pkiArchiveOptions                "id-regCtrl-pkiArchiveOptions"
+#define NID_id_regCtrl_pkiArchiveOptions               318
+#define OBJ_id_regCtrl_pkiArchiveOptions               OBJ_id_regCtrl,4L
+
+#define SN_id_regCtrl_oldCertID                "id-regCtrl-oldCertID"
+#define NID_id_regCtrl_oldCertID               319
+#define OBJ_id_regCtrl_oldCertID               OBJ_id_regCtrl,5L
+
+#define SN_id_regCtrl_protocolEncrKey          "id-regCtrl-protocolEncrKey"
+#define NID_id_regCtrl_protocolEncrKey         320
+#define OBJ_id_regCtrl_protocolEncrKey         OBJ_id_regCtrl,6L
+
+#define SN_id_regInfo_utf8Pairs                "id-regInfo-utf8Pairs"
+#define NID_id_regInfo_utf8Pairs               321
+#define OBJ_id_regInfo_utf8Pairs               OBJ_id_regInfo,1L
+
+#define SN_id_regInfo_certReq          "id-regInfo-certReq"
+#define NID_id_regInfo_certReq         322
+#define OBJ_id_regInfo_certReq         OBJ_id_regInfo,2L
+
+#define SN_id_alg_des40                "id-alg-des40"
+#define NID_id_alg_des40               323
+#define OBJ_id_alg_des40               OBJ_id_alg,1L
+
+#define SN_id_alg_noSignature          "id-alg-noSignature"
+#define NID_id_alg_noSignature         324
+#define OBJ_id_alg_noSignature         OBJ_id_alg,2L
+
+#define SN_id_alg_dh_sig_hmac_sha1             "id-alg-dh-sig-hmac-sha1"
+#define NID_id_alg_dh_sig_hmac_sha1            325
+#define OBJ_id_alg_dh_sig_hmac_sha1            OBJ_id_alg,3L
+
+#define SN_id_alg_dh_pop               "id-alg-dh-pop"
+#define NID_id_alg_dh_pop              326
+#define OBJ_id_alg_dh_pop              OBJ_id_alg,4L
+
+#define SN_id_cmc_statusInfo           "id-cmc-statusInfo"
+#define NID_id_cmc_statusInfo          327
+#define OBJ_id_cmc_statusInfo          OBJ_id_cmc,1L
+
+#define SN_id_cmc_identification               "id-cmc-identification"
+#define NID_id_cmc_identification              328
+#define OBJ_id_cmc_identification              OBJ_id_cmc,2L
+
+#define SN_id_cmc_identityProof                "id-cmc-identityProof"
+#define NID_id_cmc_identityProof               329
+#define OBJ_id_cmc_identityProof               OBJ_id_cmc,3L
+
+#define SN_id_cmc_dataReturn           "id-cmc-dataReturn"
+#define NID_id_cmc_dataReturn          330
+#define OBJ_id_cmc_dataReturn          OBJ_id_cmc,4L
+
+#define SN_id_cmc_transactionId                "id-cmc-transactionId"
+#define NID_id_cmc_transactionId               331
+#define OBJ_id_cmc_transactionId               OBJ_id_cmc,5L
+
+#define SN_id_cmc_senderNonce          "id-cmc-senderNonce"
+#define NID_id_cmc_senderNonce         332
+#define OBJ_id_cmc_senderNonce         OBJ_id_cmc,6L
+
+#define SN_id_cmc_recipientNonce               "id-cmc-recipientNonce"
+#define NID_id_cmc_recipientNonce              333
+#define OBJ_id_cmc_recipientNonce              OBJ_id_cmc,7L
+
+#define SN_id_cmc_addExtensions                "id-cmc-addExtensions"
+#define NID_id_cmc_addExtensions               334
+#define OBJ_id_cmc_addExtensions               OBJ_id_cmc,8L
+
+#define SN_id_cmc_encryptedPOP         "id-cmc-encryptedPOP"
+#define NID_id_cmc_encryptedPOP                335
+#define OBJ_id_cmc_encryptedPOP                OBJ_id_cmc,9L
+
+#define SN_id_cmc_decryptedPOP         "id-cmc-decryptedPOP"
+#define NID_id_cmc_decryptedPOP                336
+#define OBJ_id_cmc_decryptedPOP                OBJ_id_cmc,10L
+
+#define SN_id_cmc_lraPOPWitness                "id-cmc-lraPOPWitness"
+#define NID_id_cmc_lraPOPWitness               337
+#define OBJ_id_cmc_lraPOPWitness               OBJ_id_cmc,11L
+
+#define SN_id_cmc_getCert              "id-cmc-getCert"
+#define NID_id_cmc_getCert             338
+#define OBJ_id_cmc_getCert             OBJ_id_cmc,15L
+
+#define SN_id_cmc_getCRL               "id-cmc-getCRL"
+#define NID_id_cmc_getCRL              339
+#define OBJ_id_cmc_getCRL              OBJ_id_cmc,16L
+
+#define SN_id_cmc_revokeRequest                "id-cmc-revokeRequest"
+#define NID_id_cmc_revokeRequest               340
+#define OBJ_id_cmc_revokeRequest               OBJ_id_cmc,17L
+
+#define SN_id_cmc_regInfo              "id-cmc-regInfo"
+#define NID_id_cmc_regInfo             341
+#define OBJ_id_cmc_regInfo             OBJ_id_cmc,18L
+
+#define SN_id_cmc_responseInfo         "id-cmc-responseInfo"
+#define NID_id_cmc_responseInfo                342
+#define OBJ_id_cmc_responseInfo                OBJ_id_cmc,19L
+
+#define SN_id_cmc_queryPending         "id-cmc-queryPending"
+#define NID_id_cmc_queryPending                343
+#define OBJ_id_cmc_queryPending                OBJ_id_cmc,21L
+
+#define SN_id_cmc_popLinkRandom                "id-cmc-popLinkRandom"
+#define NID_id_cmc_popLinkRandom               344
+#define OBJ_id_cmc_popLinkRandom               OBJ_id_cmc,22L
+
+#define SN_id_cmc_popLinkWitness               "id-cmc-popLinkWitness"
+#define NID_id_cmc_popLinkWitness              345
+#define OBJ_id_cmc_popLinkWitness              OBJ_id_cmc,23L
+
+#define SN_id_cmc_confirmCertAcceptance                "id-cmc-confirmCertAcceptance"
+#define NID_id_cmc_confirmCertAcceptance               346
+#define OBJ_id_cmc_confirmCertAcceptance               OBJ_id_cmc,24L
+
+#define SN_id_on_personalData          "id-on-personalData"
+#define NID_id_on_personalData         347
+#define OBJ_id_on_personalData         OBJ_id_on,1L
+
+#define SN_id_pda_dateOfBirth          "id-pda-dateOfBirth"
+#define NID_id_pda_dateOfBirth         348
+#define OBJ_id_pda_dateOfBirth         OBJ_id_pda,1L
+
+#define SN_id_pda_placeOfBirth         "id-pda-placeOfBirth"
+#define NID_id_pda_placeOfBirth                349
+#define OBJ_id_pda_placeOfBirth                OBJ_id_pda,2L
+
+#define SN_id_pda_gender               "id-pda-gender"
+#define NID_id_pda_gender              351
+#define OBJ_id_pda_gender              OBJ_id_pda,3L
+
+#define SN_id_pda_countryOfCitizenship         "id-pda-countryOfCitizenship"
+#define NID_id_pda_countryOfCitizenship                352
+#define OBJ_id_pda_countryOfCitizenship                OBJ_id_pda,4L
+
+#define SN_id_pda_countryOfResidence           "id-pda-countryOfResidence"
+#define NID_id_pda_countryOfResidence          353
+#define OBJ_id_pda_countryOfResidence          OBJ_id_pda,5L
+
+#define SN_id_aca_authenticationInfo           "id-aca-authenticationInfo"
+#define NID_id_aca_authenticationInfo          354
+#define OBJ_id_aca_authenticationInfo          OBJ_id_aca,1L
+
+#define SN_id_aca_accessIdentity               "id-aca-accessIdentity"
+#define NID_id_aca_accessIdentity              355
+#define OBJ_id_aca_accessIdentity              OBJ_id_aca,2L
+
+#define SN_id_aca_chargingIdentity             "id-aca-chargingIdentity"
+#define NID_id_aca_chargingIdentity            356
+#define OBJ_id_aca_chargingIdentity            OBJ_id_aca,3L
+
+#define SN_id_aca_group                "id-aca-group"
+#define NID_id_aca_group               357
+#define OBJ_id_aca_group               OBJ_id_aca,4L
+
+#define SN_id_aca_role         "id-aca-role"
+#define NID_id_aca_role                358
+#define OBJ_id_aca_role                OBJ_id_aca,5L
+
+#define SN_id_aca_encAttrs             "id-aca-encAttrs"
+#define NID_id_aca_encAttrs            399
+#define OBJ_id_aca_encAttrs            OBJ_id_aca,6L
+
+#define SN_id_qcs_pkixQCSyntax_v1              "id-qcs-pkixQCSyntax-v1"
+#define NID_id_qcs_pkixQCSyntax_v1             359
+#define OBJ_id_qcs_pkixQCSyntax_v1             OBJ_id_qcs,1L
+
+#define SN_id_cct_crs          "id-cct-crs"
+#define NID_id_cct_crs         360
+#define OBJ_id_cct_crs         OBJ_id_cct,1L
+
+#define SN_id_cct_PKIData              "id-cct-PKIData"
+#define NID_id_cct_PKIData             361
+#define OBJ_id_cct_PKIData             OBJ_id_cct,2L
+
+#define SN_id_cct_PKIResponse          "id-cct-PKIResponse"
+#define NID_id_cct_PKIResponse         362
+#define OBJ_id_cct_PKIResponse         OBJ_id_cct,3L
+
+#define SN_ad_OCSP             "OCSP"
+#define LN_ad_OCSP             "OCSP"
+#define NID_ad_OCSP            178
+#define OBJ_ad_OCSP            OBJ_id_ad,1L
+
+#define SN_ad_ca_issuers               "caIssuers"
+#define LN_ad_ca_issuers               "CA Issuers"
+#define NID_ad_ca_issuers              179
+#define OBJ_ad_ca_issuers              OBJ_id_ad,2L
+
+#define SN_ad_timeStamping             "ad_timestamping"
+#define LN_ad_timeStamping             "AD Time Stamping"
+#define NID_ad_timeStamping            363
+#define OBJ_ad_timeStamping            OBJ_id_ad,3L
+
+#define SN_ad_dvcs             "AD_DVCS"
+#define LN_ad_dvcs             "ad dvcs"
+#define NID_ad_dvcs            364
+#define OBJ_ad_dvcs            OBJ_id_ad,4L
+
+#define OBJ_id_pkix_OCSP               OBJ_ad_OCSP
+
+#define SN_id_pkix_OCSP_basic          "basicOCSPResponse"
+#define LN_id_pkix_OCSP_basic          "Basic OCSP Response"
+#define NID_id_pkix_OCSP_basic         365
+#define OBJ_id_pkix_OCSP_basic         OBJ_id_pkix_OCSP,1L
+
+#define SN_id_pkix_OCSP_Nonce          "Nonce"
+#define LN_id_pkix_OCSP_Nonce          "OCSP Nonce"
+#define NID_id_pkix_OCSP_Nonce         366
+#define OBJ_id_pkix_OCSP_Nonce         OBJ_id_pkix_OCSP,2L
+
+#define SN_id_pkix_OCSP_CrlID          "CrlID"
+#define LN_id_pkix_OCSP_CrlID          "OCSP CRL ID"
+#define NID_id_pkix_OCSP_CrlID         367
+#define OBJ_id_pkix_OCSP_CrlID         OBJ_id_pkix_OCSP,3L
+
+#define SN_id_pkix_OCSP_acceptableResponses            "acceptableResponses"
+#define LN_id_pkix_OCSP_acceptableResponses            "Acceptable OCSP Responses"
+#define NID_id_pkix_OCSP_acceptableResponses           368
+#define OBJ_id_pkix_OCSP_acceptableResponses           OBJ_id_pkix_OCSP,4L
+
+#define SN_id_pkix_OCSP_noCheck                "noCheck"
+#define LN_id_pkix_OCSP_noCheck                "OCSP No Check"
+#define NID_id_pkix_OCSP_noCheck               369
+#define OBJ_id_pkix_OCSP_noCheck               OBJ_id_pkix_OCSP,5L
+
+#define SN_id_pkix_OCSP_archiveCutoff          "archiveCutoff"
+#define LN_id_pkix_OCSP_archiveCutoff          "OCSP Archive Cutoff"
+#define NID_id_pkix_OCSP_archiveCutoff         370
+#define OBJ_id_pkix_OCSP_archiveCutoff         OBJ_id_pkix_OCSP,6L
+
+#define SN_id_pkix_OCSP_serviceLocator         "serviceLocator"
+#define LN_id_pkix_OCSP_serviceLocator         "OCSP Service Locator"
+#define NID_id_pkix_OCSP_serviceLocator                371
+#define OBJ_id_pkix_OCSP_serviceLocator                OBJ_id_pkix_OCSP,7L
+
+#define SN_id_pkix_OCSP_extendedStatus         "extendedStatus"
+#define LN_id_pkix_OCSP_extendedStatus         "Extended OCSP Status"
+#define NID_id_pkix_OCSP_extendedStatus                372
+#define OBJ_id_pkix_OCSP_extendedStatus                OBJ_id_pkix_OCSP,8L
+
+#define SN_id_pkix_OCSP_valid          "valid"
+#define NID_id_pkix_OCSP_valid         373
+#define OBJ_id_pkix_OCSP_valid         OBJ_id_pkix_OCSP,9L
+
+#define SN_id_pkix_OCSP_path           "path"
+#define NID_id_pkix_OCSP_path          374
+#define OBJ_id_pkix_OCSP_path          OBJ_id_pkix_OCSP,10L
+
+#define SN_id_pkix_OCSP_trustRoot              "trustRoot"
+#define LN_id_pkix_OCSP_trustRoot              "Trust Root"
+#define NID_id_pkix_OCSP_trustRoot             375
+#define OBJ_id_pkix_OCSP_trustRoot             OBJ_id_pkix_OCSP,11L
+
+#define SN_algorithm           "algorithm"
+#define LN_algorithm           "algorithm"
+#define NID_algorithm          376
+#define OBJ_algorithm          1L,3L,14L,3L,2L
+
+#define SN_md5WithRSA          "RSA-NP-MD5"
+#define LN_md5WithRSA          "md5WithRSA"
+#define NID_md5WithRSA         104
+#define OBJ_md5WithRSA         OBJ_algorithm,3L
+
+#define SN_des_ecb             "DES-ECB"
+#define LN_des_ecb             "des-ecb"
+#define NID_des_ecb            29
+#define OBJ_des_ecb            OBJ_algorithm,6L
+
+#define SN_des_cbc             "DES-CBC"
+#define LN_des_cbc             "des-cbc"
+#define NID_des_cbc            31
+#define OBJ_des_cbc            OBJ_algorithm,7L
+
+#define SN_des_ofb64           "DES-OFB"
+#define LN_des_ofb64           "des-ofb"
+#define NID_des_ofb64          45
+#define OBJ_des_ofb64          OBJ_algorithm,8L
+
+#define SN_des_cfb64           "DES-CFB"
+#define LN_des_cfb64           "des-cfb"
+#define NID_des_cfb64          30
+#define OBJ_des_cfb64          OBJ_algorithm,9L
+
+#define SN_rsaSignature                "rsaSignature"
+#define NID_rsaSignature               377
+#define OBJ_rsaSignature               OBJ_algorithm,11L
+
+#define SN_dsa_2               "DSA-old"
+#define LN_dsa_2               "dsaEncryption-old"
+#define NID_dsa_2              67
+#define OBJ_dsa_2              OBJ_algorithm,12L
+
+#define SN_dsaWithSHA          "DSA-SHA"
+#define LN_dsaWithSHA          "dsaWithSHA"
+#define NID_dsaWithSHA         66
+#define OBJ_dsaWithSHA         OBJ_algorithm,13L
+
+#define SN_shaWithRSAEncryption                "RSA-SHA"
+#define LN_shaWithRSAEncryption                "shaWithRSAEncryption"
+#define NID_shaWithRSAEncryption               42
+#define OBJ_shaWithRSAEncryption               OBJ_algorithm,15L
+
+#define SN_des_ede_ecb         "DES-EDE"
+#define LN_des_ede_ecb         "des-ede"
+#define NID_des_ede_ecb                32
+#define OBJ_des_ede_ecb                OBJ_algorithm,17L
+
+#define SN_des_ede3_ecb                "DES-EDE3"
+#define LN_des_ede3_ecb                "des-ede3"
+#define NID_des_ede3_ecb               33
+
+#define SN_des_ede_cbc         "DES-EDE-CBC"
+#define LN_des_ede_cbc         "des-ede-cbc"
+#define NID_des_ede_cbc                43
+
+#define SN_des_ede_cfb64               "DES-EDE-CFB"
+#define LN_des_ede_cfb64               "des-ede-cfb"
+#define NID_des_ede_cfb64              60
+
+#define SN_des_ede3_cfb64              "DES-EDE3-CFB"
+#define LN_des_ede3_cfb64              "des-ede3-cfb"
+#define NID_des_ede3_cfb64             61
+
+#define SN_des_ede_ofb64               "DES-EDE-OFB"
+#define LN_des_ede_ofb64               "des-ede-ofb"
+#define NID_des_ede_ofb64              62
+
+#define SN_des_ede3_ofb64              "DES-EDE3-OFB"
+#define LN_des_ede3_ofb64              "des-ede3-ofb"
+#define NID_des_ede3_ofb64             63
+
+#define SN_desx_cbc            "DESX-CBC"
+#define LN_desx_cbc            "desx-cbc"
+#define NID_desx_cbc           80
+
+#define SN_sha         "SHA"
+#define LN_sha         "sha"
+#define NID_sha                41
+#define OBJ_sha                OBJ_algorithm,18L
+
+#define SN_sha1                "SHA1"
+#define LN_sha1                "sha1"
+#define NID_sha1               64
+#define OBJ_sha1               OBJ_algorithm,26L
+
+#define SN_dsaWithSHA1_2               "DSA-SHA1-old"
+#define LN_dsaWithSHA1_2               "dsaWithSHA1-old"
+#define NID_dsaWithSHA1_2              70
+#define OBJ_dsaWithSHA1_2              OBJ_algorithm,27L
+
+#define SN_sha1WithRSA         "RSA-SHA1-2"
+#define LN_sha1WithRSA         "sha1WithRSA"
+#define NID_sha1WithRSA                115
+#define OBJ_sha1WithRSA                OBJ_algorithm,29L
+
+#define SN_ripemd160           "RIPEMD160"
+#define LN_ripemd160           "ripemd160"
+#define NID_ripemd160          117
+#define OBJ_ripemd160          1L,3L,36L,3L,2L,1L
+
+#define SN_ripemd160WithRSA            "RSA-RIPEMD160"
+#define LN_ripemd160WithRSA            "ripemd160WithRSA"
+#define NID_ripemd160WithRSA           119
+#define OBJ_ripemd160WithRSA           1L,3L,36L,3L,3L,1L,2L
+
+#define SN_sxnet               "SXNetID"
+#define LN_sxnet               "Strong Extranet ID"
+#define NID_sxnet              143
+#define OBJ_sxnet              1L,3L,101L,1L,4L,1L
+
+#define SN_X500                "X500"
+#define LN_X500                "directory services (X.500)"
+#define NID_X500               11
+#define OBJ_X500               2L,5L
+
+#define SN_X509                "X509"
+#define NID_X509               12
+#define OBJ_X509               OBJ_X500,4L
+
+#define SN_commonName          "CN"
+#define LN_commonName          "commonName"
+#define NID_commonName         13
+#define OBJ_commonName         OBJ_X509,3L
+
+#define SN_surname             "SN"
+#define LN_surname             "surname"
+#define NID_surname            100
+#define OBJ_surname            OBJ_X509,4L
+
+#define LN_serialNumber                "serialNumber"
+#define NID_serialNumber               105
+#define OBJ_serialNumber               OBJ_X509,5L
+
+#define SN_countryName         "C"
+#define LN_countryName         "countryName"
+#define NID_countryName                14
+#define OBJ_countryName                OBJ_X509,6L
+
+#define SN_localityName                "L"
+#define LN_localityName                "localityName"
+#define NID_localityName               15
+#define OBJ_localityName               OBJ_X509,7L
+
+#define SN_stateOrProvinceName         "ST"
+#define LN_stateOrProvinceName         "stateOrProvinceName"
+#define NID_stateOrProvinceName                16
+#define OBJ_stateOrProvinceName                OBJ_X509,8L
+
+#define SN_organizationName            "O"
+#define LN_organizationName            "organizationName"
+#define NID_organizationName           17
+#define OBJ_organizationName           OBJ_X509,10L
+
+#define SN_organizationalUnitName              "OU"
+#define LN_organizationalUnitName              "organizationalUnitName"
+#define NID_organizationalUnitName             18
+#define OBJ_organizationalUnitName             OBJ_X509,11L
+
+#define LN_title               "title"
+#define NID_title              106
+#define OBJ_title              OBJ_X509,12L
+
+#define LN_description         "description"
+#define NID_description                107
+#define OBJ_description                OBJ_X509,13L
+
+#define SN_name                "name"
+#define LN_name                "name"
+#define NID_name               173
+#define OBJ_name               OBJ_X509,41L
+
+#define SN_givenName           "GN"
+#define LN_givenName           "givenName"
+#define NID_givenName          99
+#define OBJ_givenName          OBJ_X509,42L
+
+#define LN_initials            "initials"
+#define NID_initials           101
+#define OBJ_initials           OBJ_X509,43L
+
+#define LN_generationQualifier         "generationQualifier"
+#define NID_generationQualifier                509
+#define OBJ_generationQualifier                OBJ_X509,44L
+
+#define LN_x500UniqueIdentifier                "x500UniqueIdentifier"
+#define NID_x500UniqueIdentifier               503
+#define OBJ_x500UniqueIdentifier               OBJ_X509,45L
+
+#define SN_dnQualifier         "dnQualifier"
+#define LN_dnQualifier         "dnQualifier"
+#define NID_dnQualifier                174
+#define OBJ_dnQualifier                OBJ_X509,46L
+
+#define LN_pseudonym           "pseudonym"
+#define NID_pseudonym          510
+#define OBJ_pseudonym          OBJ_X509,65L
+
+#define SN_role                "role"
+#define LN_role                "role"
+#define NID_role               400
+#define OBJ_role               OBJ_X509,72L
+
+#define SN_X500algorithms              "X500algorithms"
+#define LN_X500algorithms              "directory services - algorithms"
+#define NID_X500algorithms             378
+#define OBJ_X500algorithms             OBJ_X500,8L
+
+#define SN_rsa         "RSA"
+#define LN_rsa         "rsa"
+#define NID_rsa                19
+#define OBJ_rsa                OBJ_X500algorithms,1L,1L
+
+#define SN_mdc2WithRSA         "RSA-MDC2"
+#define LN_mdc2WithRSA         "mdc2WithRSA"
+#define NID_mdc2WithRSA                96
+#define OBJ_mdc2WithRSA                OBJ_X500algorithms,3L,100L
+
+#define SN_mdc2                "MDC2"
+#define LN_mdc2                "mdc2"
+#define NID_mdc2               95
+#define OBJ_mdc2               OBJ_X500algorithms,3L,101L
+
+#define SN_id_ce               "id-ce"
+#define NID_id_ce              81
+#define OBJ_id_ce              OBJ_X500,29L
+
+#define SN_subject_key_identifier              "subjectKeyIdentifier"
+#define LN_subject_key_identifier              "X509v3 Subject Key Identifier"
+#define NID_subject_key_identifier             82
+#define OBJ_subject_key_identifier             OBJ_id_ce,14L
+
+#define SN_key_usage           "keyUsage"
+#define LN_key_usage           "X509v3 Key Usage"
+#define NID_key_usage          83
+#define OBJ_key_usage          OBJ_id_ce,15L
+
+#define SN_private_key_usage_period            "privateKeyUsagePeriod"
+#define LN_private_key_usage_period            "X509v3 Private Key Usage Period"
+#define NID_private_key_usage_period           84
+#define OBJ_private_key_usage_period           OBJ_id_ce,16L
+
+#define SN_subject_alt_name            "subjectAltName"
+#define LN_subject_alt_name            "X509v3 Subject Alternative Name"
+#define NID_subject_alt_name           85
+#define OBJ_subject_alt_name           OBJ_id_ce,17L
+
+#define SN_issuer_alt_name             "issuerAltName"
+#define LN_issuer_alt_name             "X509v3 Issuer Alternative Name"
+#define NID_issuer_alt_name            86
+#define OBJ_issuer_alt_name            OBJ_id_ce,18L
+
+#define SN_basic_constraints           "basicConstraints"
+#define LN_basic_constraints           "X509v3 Basic Constraints"
+#define NID_basic_constraints          87
+#define OBJ_basic_constraints          OBJ_id_ce,19L
+
+#define SN_crl_number          "crlNumber"
+#define LN_crl_number          "X509v3 CRL Number"
+#define NID_crl_number         88
+#define OBJ_crl_number         OBJ_id_ce,20L
+
+#define SN_crl_reason          "CRLReason"
+#define LN_crl_reason          "X509v3 CRL Reason Code"
+#define NID_crl_reason         141
+#define OBJ_crl_reason         OBJ_id_ce,21L
+
+#define SN_invalidity_date             "invalidityDate"
+#define LN_invalidity_date             "Invalidity Date"
+#define NID_invalidity_date            142
+#define OBJ_invalidity_date            OBJ_id_ce,24L
+
+#define SN_delta_crl           "deltaCRL"
+#define LN_delta_crl           "X509v3 Delta CRL Indicator"
+#define NID_delta_crl          140
+#define OBJ_delta_crl          OBJ_id_ce,27L
+
+#define SN_crl_distribution_points             "crlDistributionPoints"
+#define LN_crl_distribution_points             "X509v3 CRL Distribution Points"
+#define NID_crl_distribution_points            103
+#define OBJ_crl_distribution_points            OBJ_id_ce,31L
+
+#define SN_certificate_policies                "certificatePolicies"
+#define LN_certificate_policies                "X509v3 Certificate Policies"
+#define NID_certificate_policies               89
+#define OBJ_certificate_policies               OBJ_id_ce,32L
+
+#define SN_authority_key_identifier            "authorityKeyIdentifier"
+#define LN_authority_key_identifier            "X509v3 Authority Key Identifier"
+#define NID_authority_key_identifier           90
+#define OBJ_authority_key_identifier           OBJ_id_ce,35L
+
+#define SN_policy_constraints          "policyConstraints"
+#define LN_policy_constraints          "X509v3 Policy Constraints"
+#define NID_policy_constraints         401
+#define OBJ_policy_constraints         OBJ_id_ce,36L
+
+#define SN_ext_key_usage               "extendedKeyUsage"
+#define LN_ext_key_usage               "X509v3 Extended Key Usage"
+#define NID_ext_key_usage              126
+#define OBJ_ext_key_usage              OBJ_id_ce,37L
+
+#define SN_target_information          "targetInformation"
+#define LN_target_information          "X509v3 AC Targeting"
+#define NID_target_information         402
+#define OBJ_target_information         OBJ_id_ce,55L
+
+#define SN_no_rev_avail                "noRevAvail"
+#define LN_no_rev_avail                "X509v3 No Revocation Available"
+#define NID_no_rev_avail               403
+#define OBJ_no_rev_avail               OBJ_id_ce,56L
+
+#define SN_netscape            "Netscape"
+#define LN_netscape            "Netscape Communications Corp."
+#define NID_netscape           57
+#define OBJ_netscape           2L,16L,840L,1L,113730L
+
+#define SN_netscape_cert_extension             "nsCertExt"
+#define LN_netscape_cert_extension             "Netscape Certificate Extension"
+#define NID_netscape_cert_extension            58
+#define OBJ_netscape_cert_extension            OBJ_netscape,1L
+
+#define SN_netscape_data_type          "nsDataType"
+#define LN_netscape_data_type          "Netscape Data Type"
+#define NID_netscape_data_type         59
+#define OBJ_netscape_data_type         OBJ_netscape,2L
+
+#define SN_netscape_cert_type          "nsCertType"
+#define LN_netscape_cert_type          "Netscape Cert Type"
+#define NID_netscape_cert_type         71
+#define OBJ_netscape_cert_type         OBJ_netscape_cert_extension,1L
+
+#define SN_netscape_base_url           "nsBaseUrl"
+#define LN_netscape_base_url           "Netscape Base Url"
+#define NID_netscape_base_url          72
+#define OBJ_netscape_base_url          OBJ_netscape_cert_extension,2L
+
+#define SN_netscape_revocation_url             "nsRevocationUrl"
+#define LN_netscape_revocation_url             "Netscape Revocation Url"
+#define NID_netscape_revocation_url            73
+#define OBJ_netscape_revocation_url            OBJ_netscape_cert_extension,3L
+
+#define SN_netscape_ca_revocation_url          "nsCaRevocationUrl"
+#define LN_netscape_ca_revocation_url          "Netscape CA Revocation Url"
+#define NID_netscape_ca_revocation_url         74
+#define OBJ_netscape_ca_revocation_url         OBJ_netscape_cert_extension,4L
+
+#define SN_netscape_renewal_url                "nsRenewalUrl"
+#define LN_netscape_renewal_url                "Netscape Renewal Url"
+#define NID_netscape_renewal_url               75
+#define OBJ_netscape_renewal_url               OBJ_netscape_cert_extension,7L
+
+#define SN_netscape_ca_policy_url              "nsCaPolicyUrl"
+#define LN_netscape_ca_policy_url              "Netscape CA Policy Url"
+#define NID_netscape_ca_policy_url             76
+#define OBJ_netscape_ca_policy_url             OBJ_netscape_cert_extension,8L
+
+#define SN_netscape_ssl_server_name            "nsSslServerName"
+#define LN_netscape_ssl_server_name            "Netscape SSL Server Name"
+#define NID_netscape_ssl_server_name           77
+#define OBJ_netscape_ssl_server_name           OBJ_netscape_cert_extension,12L
+
+#define SN_netscape_comment            "nsComment"
+#define LN_netscape_comment            "Netscape Comment"
+#define NID_netscape_comment           78
+#define OBJ_netscape_comment           OBJ_netscape_cert_extension,13L
+
+#define SN_netscape_cert_sequence              "nsCertSequence"
+#define LN_netscape_cert_sequence              "Netscape Certificate Sequence"
+#define NID_netscape_cert_sequence             79
+#define OBJ_netscape_cert_sequence             OBJ_netscape_data_type,5L
+
+#define SN_ns_sgc              "nsSGC"
+#define LN_ns_sgc              "Netscape Server Gated Crypto"
+#define NID_ns_sgc             139
+#define OBJ_ns_sgc             OBJ_netscape,4L,1L
+
+#define SN_org         "ORG"
+#define LN_org         "org"
+#define NID_org                379
+#define OBJ_org                OBJ_iso,3L
+
+#define SN_dod         "DOD"
+#define LN_dod         "dod"
+#define NID_dod                380
+#define OBJ_dod                OBJ_org,6L
+
+#define SN_iana                "IANA"
+#define LN_iana                "iana"
+#define NID_iana               381
+#define OBJ_iana               OBJ_dod,1L
+
+#define OBJ_internet           OBJ_iana
+
+#define SN_Directory           "directory"
+#define LN_Directory           "Directory"
+#define NID_Directory          382
+#define OBJ_Directory          OBJ_internet,1L
+
+#define SN_Management          "mgmt"
+#define LN_Management          "Management"
+#define NID_Management         383
+#define OBJ_Management         OBJ_internet,2L
+
+#define SN_Experimental                "experimental"
+#define LN_Experimental                "Experimental"
+#define NID_Experimental               384
+#define OBJ_Experimental               OBJ_internet,3L
+
+#define SN_Private             "private"
+#define LN_Private             "Private"
+#define NID_Private            385
+#define OBJ_Private            OBJ_internet,4L
+
+#define SN_Security            "security"
+#define LN_Security            "Security"
+#define NID_Security           386
+#define OBJ_Security           OBJ_internet,5L
+
+#define SN_SNMPv2              "snmpv2"
+#define LN_SNMPv2              "SNMPv2"
+#define NID_SNMPv2             387
+#define OBJ_SNMPv2             OBJ_internet,6L
+
+#define LN_Mail                "Mail"
+#define NID_Mail               388
+#define OBJ_Mail               OBJ_internet,7L
+
+#define SN_Enterprises         "enterprises"
+#define LN_Enterprises         "Enterprises"
+#define NID_Enterprises                389
+#define OBJ_Enterprises                OBJ_Private,1L
+
+#define SN_dcObject            "dcobject"
+#define LN_dcObject            "dcObject"
+#define NID_dcObject           390
+#define OBJ_dcObject           OBJ_Enterprises,1466L,344L
+
+#define SN_mime_mhs            "mime-mhs"
+#define LN_mime_mhs            "MIME MHS"
+#define NID_mime_mhs           504
+#define OBJ_mime_mhs           OBJ_Mail,1L
+
+#define SN_mime_mhs_headings           "mime-mhs-headings"
+#define LN_mime_mhs_headings           "mime-mhs-headings"
+#define NID_mime_mhs_headings          505
+#define OBJ_mime_mhs_headings          OBJ_mime_mhs,1L
+
+#define SN_mime_mhs_bodies             "mime-mhs-bodies"
+#define LN_mime_mhs_bodies             "mime-mhs-bodies"
+#define NID_mime_mhs_bodies            506
+#define OBJ_mime_mhs_bodies            OBJ_mime_mhs,2L
+
+#define SN_id_hex_partial_message              "id-hex-partial-message"
+#define LN_id_hex_partial_message              "id-hex-partial-message"
+#define NID_id_hex_partial_message             507
+#define OBJ_id_hex_partial_message             OBJ_mime_mhs_headings,1L
+
+#define SN_id_hex_multipart_message            "id-hex-multipart-message"
+#define LN_id_hex_multipart_message            "id-hex-multipart-message"
+#define NID_id_hex_multipart_message           508
+#define OBJ_id_hex_multipart_message           OBJ_mime_mhs_headings,2L
+
+#define SN_rle_compression             "RLE"
+#define LN_rle_compression             "run length compression"
+#define NID_rle_compression            124
+#define OBJ_rle_compression            1L,1L,1L,1L,666L,1L
+
+#define SN_zlib_compression            "ZLIB"
+#define LN_zlib_compression            "zlib compression"
+#define NID_zlib_compression           125
+#define OBJ_zlib_compression           1L,1L,1L,1L,666L,2L
+
+#define OBJ_csor               2L,16L,840L,1L,101L,3L
+
+#define OBJ_nistAlgorithms             OBJ_csor,4L
+
+#define OBJ_aes                OBJ_nistAlgorithms,1L
+
+#define SN_aes_128_ecb         "AES-128-ECB"
+#define LN_aes_128_ecb         "aes-128-ecb"
+#define NID_aes_128_ecb                418
+#define OBJ_aes_128_ecb                OBJ_aes,1L
+
+#define SN_aes_128_cbc         "AES-128-CBC"
+#define LN_aes_128_cbc         "aes-128-cbc"
+#define NID_aes_128_cbc                419
+#define OBJ_aes_128_cbc                OBJ_aes,2L
+
+#define SN_aes_128_ofb128              "AES-128-OFB"
+#define LN_aes_128_ofb128              "aes-128-ofb"
+#define NID_aes_128_ofb128             420
+#define OBJ_aes_128_ofb128             OBJ_aes,3L
+
+#define SN_aes_128_cfb128              "AES-128-CFB"
+#define LN_aes_128_cfb128              "aes-128-cfb"
+#define NID_aes_128_cfb128             421
+#define OBJ_aes_128_cfb128             OBJ_aes,4L
+
+#define SN_aes_192_ecb         "AES-192-ECB"
+#define LN_aes_192_ecb         "aes-192-ecb"
+#define NID_aes_192_ecb                422
+#define OBJ_aes_192_ecb                OBJ_aes,21L
+
+#define SN_aes_192_cbc         "AES-192-CBC"
+#define LN_aes_192_cbc         "aes-192-cbc"
+#define NID_aes_192_cbc                423
+#define OBJ_aes_192_cbc                OBJ_aes,22L
+
+#define SN_aes_192_ofb128              "AES-192-OFB"
+#define LN_aes_192_ofb128              "aes-192-ofb"
+#define NID_aes_192_ofb128             424
+#define OBJ_aes_192_ofb128             OBJ_aes,23L
+
+#define SN_aes_192_cfb128              "AES-192-CFB"
+#define LN_aes_192_cfb128              "aes-192-cfb"
+#define NID_aes_192_cfb128             425
+#define OBJ_aes_192_cfb128             OBJ_aes,24L
+
+#define SN_aes_256_ecb         "AES-256-ECB"
+#define LN_aes_256_ecb         "aes-256-ecb"
+#define NID_aes_256_ecb                426
+#define OBJ_aes_256_ecb                OBJ_aes,41L
+
+#define SN_aes_256_cbc         "AES-256-CBC"
+#define LN_aes_256_cbc         "aes-256-cbc"
+#define NID_aes_256_cbc                427
+#define OBJ_aes_256_cbc                OBJ_aes,42L
+
+#define SN_aes_256_ofb128              "AES-256-OFB"
+#define LN_aes_256_ofb128              "aes-256-ofb"
+#define NID_aes_256_ofb128             428
+#define OBJ_aes_256_ofb128             OBJ_aes,43L
+
+#define SN_aes_256_cfb128              "AES-256-CFB"
+#define LN_aes_256_cfb128              "aes-256-cfb"
+#define NID_aes_256_cfb128             429
+#define OBJ_aes_256_cfb128             OBJ_aes,44L
+
+#define SN_hold_instruction_code               "holdInstructionCode"
+#define LN_hold_instruction_code               "Hold Instruction Code"
+#define NID_hold_instruction_code              430
+#define OBJ_hold_instruction_code              OBJ_id_ce,23L
+
+#define OBJ_holdInstruction            OBJ_X9_57,2L
+
+#define SN_hold_instruction_none               "holdInstructionNone"
+#define LN_hold_instruction_none               "Hold Instruction None"
+#define NID_hold_instruction_none              431
+#define OBJ_hold_instruction_none              OBJ_holdInstruction,1L
+
+#define SN_hold_instruction_call_issuer                "holdInstructionCallIssuer"
+#define LN_hold_instruction_call_issuer                "Hold Instruction Call Issuer"
+#define NID_hold_instruction_call_issuer               432
+#define OBJ_hold_instruction_call_issuer               OBJ_holdInstruction,2L
+
+#define SN_hold_instruction_reject             "holdInstructionReject"
+#define LN_hold_instruction_reject             "Hold Instruction Reject"
+#define NID_hold_instruction_reject            433
+#define OBJ_hold_instruction_reject            OBJ_holdInstruction,3L
+
+#define SN_data                "data"
+#define NID_data               434
+#define OBJ_data               OBJ_ccitt,9L
+
+#define SN_pss         "pss"
+#define NID_pss                435
+#define OBJ_pss                OBJ_data,2342L
+
+#define SN_ucl         "ucl"
+#define NID_ucl                436
+#define OBJ_ucl                OBJ_pss,19200300L
+
+#define SN_pilot               "pilot"
+#define NID_pilot              437
+#define OBJ_pilot              OBJ_ucl,100L
+
+#define LN_pilotAttributeType          "pilotAttributeType"
+#define NID_pilotAttributeType         438
+#define OBJ_pilotAttributeType         OBJ_pilot,1L
+
+#define LN_pilotAttributeSyntax                "pilotAttributeSyntax"
+#define NID_pilotAttributeSyntax               439
+#define OBJ_pilotAttributeSyntax               OBJ_pilot,3L
+
+#define LN_pilotObjectClass            "pilotObjectClass"
+#define NID_pilotObjectClass           440
+#define OBJ_pilotObjectClass           OBJ_pilot,4L
+
+#define LN_pilotGroups         "pilotGroups"
+#define NID_pilotGroups                441
+#define OBJ_pilotGroups                OBJ_pilot,10L
+
+#define LN_iA5StringSyntax             "iA5StringSyntax"
+#define NID_iA5StringSyntax            442
+#define OBJ_iA5StringSyntax            OBJ_pilotAttributeSyntax,4L
+
+#define LN_caseIgnoreIA5StringSyntax           "caseIgnoreIA5StringSyntax"
+#define NID_caseIgnoreIA5StringSyntax          443
+#define OBJ_caseIgnoreIA5StringSyntax          OBJ_pilotAttributeSyntax,5L
+
+#define LN_pilotObject         "pilotObject"
+#define NID_pilotObject                444
+#define OBJ_pilotObject                OBJ_pilotObjectClass,3L
+
+#define LN_pilotPerson         "pilotPerson"
+#define NID_pilotPerson                445
+#define OBJ_pilotPerson                OBJ_pilotObjectClass,4L
+
+#define SN_account             "account"
+#define NID_account            446
+#define OBJ_account            OBJ_pilotObjectClass,5L
+
+#define SN_document            "document"
+#define NID_document           447
+#define OBJ_document           OBJ_pilotObjectClass,6L
+
+#define SN_room                "room"
+#define NID_room               448
+#define OBJ_room               OBJ_pilotObjectClass,7L
+
+#define LN_documentSeries              "documentSeries"
+#define NID_documentSeries             449
+#define OBJ_documentSeries             OBJ_pilotObjectClass,9L
+
+#define SN_Domain              "domain"
+#define LN_Domain              "Domain"
+#define NID_Domain             392
+#define OBJ_Domain             OBJ_pilotObjectClass,13L
+
+#define LN_rFC822localPart             "rFC822localPart"
+#define NID_rFC822localPart            450
+#define OBJ_rFC822localPart            OBJ_pilotObjectClass,14L
+
+#define LN_dNSDomain           "dNSDomain"
+#define NID_dNSDomain          451
+#define OBJ_dNSDomain          OBJ_pilotObjectClass,15L
+
+#define LN_domainRelatedObject         "domainRelatedObject"
+#define NID_domainRelatedObject                452
+#define OBJ_domainRelatedObject                OBJ_pilotObjectClass,17L
+
+#define LN_friendlyCountry             "friendlyCountry"
+#define NID_friendlyCountry            453
+#define OBJ_friendlyCountry            OBJ_pilotObjectClass,18L
+
+#define LN_simpleSecurityObject                "simpleSecurityObject"
+#define NID_simpleSecurityObject               454
+#define OBJ_simpleSecurityObject               OBJ_pilotObjectClass,19L
+
+#define LN_pilotOrganization           "pilotOrganization"
+#define NID_pilotOrganization          455
+#define OBJ_pilotOrganization          OBJ_pilotObjectClass,20L
+
+#define LN_pilotDSA            "pilotDSA"
+#define NID_pilotDSA           456
+#define OBJ_pilotDSA           OBJ_pilotObjectClass,21L
+
+#define LN_qualityLabelledData         "qualityLabelledData"
+#define NID_qualityLabelledData                457
+#define OBJ_qualityLabelledData                OBJ_pilotObjectClass,22L
+
+#define SN_userId              "UID"
+#define LN_userId              "userId"
+#define NID_userId             458
+#define OBJ_userId             OBJ_pilotAttributeType,1L
+
+#define LN_textEncodedORAddress                "textEncodedORAddress"
+#define NID_textEncodedORAddress               459
+#define OBJ_textEncodedORAddress               OBJ_pilotAttributeType,2L
+
+#define SN_rfc822Mailbox               "mail"
+#define LN_rfc822Mailbox               "rfc822Mailbox"
+#define NID_rfc822Mailbox              460
+#define OBJ_rfc822Mailbox              OBJ_pilotAttributeType,3L
+
+#define SN_info                "info"
+#define NID_info               461
+#define OBJ_info               OBJ_pilotAttributeType,4L
+
+#define LN_favouriteDrink              "favouriteDrink"
+#define NID_favouriteDrink             462
+#define OBJ_favouriteDrink             OBJ_pilotAttributeType,5L
+
+#define LN_roomNumber          "roomNumber"
+#define NID_roomNumber         463
+#define OBJ_roomNumber         OBJ_pilotAttributeType,6L
+
+#define SN_photo               "photo"
+#define NID_photo              464
+#define OBJ_photo              OBJ_pilotAttributeType,7L
+
+#define LN_userClass           "userClass"
+#define NID_userClass          465
+#define OBJ_userClass          OBJ_pilotAttributeType,8L
+
+#define SN_host                "host"
+#define NID_host               466
+#define OBJ_host               OBJ_pilotAttributeType,9L
+
+#define SN_manager             "manager"
+#define NID_manager            467
+#define OBJ_manager            OBJ_pilotAttributeType,10L
+
+#define LN_documentIdentifier          "documentIdentifier"
+#define NID_documentIdentifier         468
+#define OBJ_documentIdentifier         OBJ_pilotAttributeType,11L
+
+#define LN_documentTitle               "documentTitle"
+#define NID_documentTitle              469
+#define OBJ_documentTitle              OBJ_pilotAttributeType,12L
+
+#define LN_documentVersion             "documentVersion"
+#define NID_documentVersion            470
+#define OBJ_documentVersion            OBJ_pilotAttributeType,13L
+
+#define LN_documentAuthor              "documentAuthor"
+#define NID_documentAuthor             471
+#define OBJ_documentAuthor             OBJ_pilotAttributeType,14L
+
+#define LN_documentLocation            "documentLocation"
+#define NID_documentLocation           472
+#define OBJ_documentLocation           OBJ_pilotAttributeType,15L
+
+#define LN_homeTelephoneNumber         "homeTelephoneNumber"
+#define NID_homeTelephoneNumber                473
+#define OBJ_homeTelephoneNumber                OBJ_pilotAttributeType,20L
+
+#define SN_secretary           "secretary"
+#define NID_secretary          474
+#define OBJ_secretary          OBJ_pilotAttributeType,21L
+
+#define LN_otherMailbox                "otherMailbox"
+#define NID_otherMailbox               475
+#define OBJ_otherMailbox               OBJ_pilotAttributeType,22L
+
+#define LN_lastModifiedTime            "lastModifiedTime"
+#define NID_lastModifiedTime           476
+#define OBJ_lastModifiedTime           OBJ_pilotAttributeType,23L
+
+#define LN_lastModifiedBy              "lastModifiedBy"
+#define NID_lastModifiedBy             477
+#define OBJ_lastModifiedBy             OBJ_pilotAttributeType,24L
+
+#define SN_domainComponent             "DC"
+#define LN_domainComponent             "domainComponent"
+#define NID_domainComponent            391
+#define OBJ_domainComponent            OBJ_pilotAttributeType,25L
+
+#define LN_aRecord             "aRecord"
+#define NID_aRecord            478
+#define OBJ_aRecord            OBJ_pilotAttributeType,26L
+
+#define LN_pilotAttributeType27                "pilotAttributeType27"
+#define NID_pilotAttributeType27               479
+#define OBJ_pilotAttributeType27               OBJ_pilotAttributeType,27L
+
+#define LN_mXRecord            "mXRecord"
+#define NID_mXRecord           480
+#define OBJ_mXRecord           OBJ_pilotAttributeType,28L
+
+#define LN_nSRecord            "nSRecord"
+#define NID_nSRecord           481
+#define OBJ_nSRecord           OBJ_pilotAttributeType,29L
+
+#define LN_sOARecord           "sOARecord"
+#define NID_sOARecord          482
+#define OBJ_sOARecord          OBJ_pilotAttributeType,30L
+
+#define LN_cNAMERecord         "cNAMERecord"
+#define NID_cNAMERecord                483
+#define OBJ_cNAMERecord                OBJ_pilotAttributeType,31L
+
+#define LN_associatedDomain            "associatedDomain"
+#define NID_associatedDomain           484
+#define OBJ_associatedDomain           OBJ_pilotAttributeType,37L
+
+#define LN_associatedName              "associatedName"
+#define NID_associatedName             485
+#define OBJ_associatedName             OBJ_pilotAttributeType,38L
+
+#define LN_homePostalAddress           "homePostalAddress"
+#define NID_homePostalAddress          486
+#define OBJ_homePostalAddress          OBJ_pilotAttributeType,39L
+
+#define LN_personalTitle               "personalTitle"
+#define NID_personalTitle              487
+#define OBJ_personalTitle              OBJ_pilotAttributeType,40L
+
+#define LN_mobileTelephoneNumber               "mobileTelephoneNumber"
+#define NID_mobileTelephoneNumber              488
+#define OBJ_mobileTelephoneNumber              OBJ_pilotAttributeType,41L
+
+#define LN_pagerTelephoneNumber                "pagerTelephoneNumber"
+#define NID_pagerTelephoneNumber               489
+#define OBJ_pagerTelephoneNumber               OBJ_pilotAttributeType,42L
+
+#define LN_friendlyCountryName         "friendlyCountryName"
+#define NID_friendlyCountryName                490
+#define OBJ_friendlyCountryName                OBJ_pilotAttributeType,43L
+
+#define LN_organizationalStatus                "organizationalStatus"
+#define NID_organizationalStatus               491
+#define OBJ_organizationalStatus               OBJ_pilotAttributeType,45L
+
+#define LN_janetMailbox                "janetMailbox"
+#define NID_janetMailbox               492
+#define OBJ_janetMailbox               OBJ_pilotAttributeType,46L
+
+#define LN_mailPreferenceOption                "mailPreferenceOption"
+#define NID_mailPreferenceOption               493
+#define OBJ_mailPreferenceOption               OBJ_pilotAttributeType,47L
+
+#define LN_buildingName                "buildingName"
+#define NID_buildingName               494
+#define OBJ_buildingName               OBJ_pilotAttributeType,48L
+
+#define LN_dSAQuality          "dSAQuality"
+#define NID_dSAQuality         495
+#define OBJ_dSAQuality         OBJ_pilotAttributeType,49L
+
+#define LN_singleLevelQuality          "singleLevelQuality"
+#define NID_singleLevelQuality         496
+#define OBJ_singleLevelQuality         OBJ_pilotAttributeType,50L
+
+#define LN_subtreeMinimumQuality               "subtreeMinimumQuality"
+#define NID_subtreeMinimumQuality              497
+#define OBJ_subtreeMinimumQuality              OBJ_pilotAttributeType,51L
+
+#define LN_subtreeMaximumQuality               "subtreeMaximumQuality"
+#define NID_subtreeMaximumQuality              498
+#define OBJ_subtreeMaximumQuality              OBJ_pilotAttributeType,52L
+
+#define LN_personalSignature           "personalSignature"
+#define NID_personalSignature          499
+#define OBJ_personalSignature          OBJ_pilotAttributeType,53L
+
+#define LN_dITRedirect         "dITRedirect"
+#define NID_dITRedirect                500
+#define OBJ_dITRedirect                OBJ_pilotAttributeType,54L
+
+#define SN_audio               "audio"
+#define NID_audio              501
+#define OBJ_audio              OBJ_pilotAttributeType,55L
+
+#define LN_documentPublisher           "documentPublisher"
+#define NID_documentPublisher          502
+#define OBJ_documentPublisher          OBJ_pilotAttributeType,56L
+
+#define SN_id_set              "id-set"
+#define LN_id_set              "Secure Electronic Transactions"
+#define NID_id_set             512
+#define OBJ_id_set             2L,23L,42L
+
+#define SN_set_ctype           "set-ctype"
+#define LN_set_ctype           "content types"
+#define NID_set_ctype          513
+#define OBJ_set_ctype          OBJ_id_set,0L
+
+#define SN_set_msgExt          "set-msgExt"
+#define LN_set_msgExt          "message extensions"
+#define NID_set_msgExt         514
+#define OBJ_set_msgExt         OBJ_id_set,1L
+
+#define SN_set_attr            "set-attr"
+#define NID_set_attr           515
+#define OBJ_set_attr           OBJ_id_set,3L
+
+#define SN_set_policy          "set-policy"
+#define NID_set_policy         516
+#define OBJ_set_policy         OBJ_id_set,5L
+
+#define SN_set_certExt         "set-certExt"
+#define LN_set_certExt         "certificate extensions"
+#define NID_set_certExt                517
+#define OBJ_set_certExt                OBJ_id_set,7L
+
+#define SN_set_brand           "set-brand"
+#define NID_set_brand          518
+#define OBJ_set_brand          OBJ_id_set,8L
+
+#define SN_setct_PANData               "setct-PANData"
+#define NID_setct_PANData              519
+#define OBJ_setct_PANData              OBJ_set_ctype,0L
+
+#define SN_setct_PANToken              "setct-PANToken"
+#define NID_setct_PANToken             520
+#define OBJ_setct_PANToken             OBJ_set_ctype,1L
+
+#define SN_setct_PANOnly               "setct-PANOnly"
+#define NID_setct_PANOnly              521
+#define OBJ_setct_PANOnly              OBJ_set_ctype,2L
+
+#define SN_setct_OIData                "setct-OIData"
+#define NID_setct_OIData               522
+#define OBJ_setct_OIData               OBJ_set_ctype,3L
+
+#define SN_setct_PI            "setct-PI"
+#define NID_setct_PI           523
+#define OBJ_setct_PI           OBJ_set_ctype,4L
+
+#define SN_setct_PIData                "setct-PIData"
+#define NID_setct_PIData               524
+#define OBJ_setct_PIData               OBJ_set_ctype,5L
+
+#define SN_setct_PIDataUnsigned                "setct-PIDataUnsigned"
+#define NID_setct_PIDataUnsigned               525
+#define OBJ_setct_PIDataUnsigned               OBJ_set_ctype,6L
+
+#define SN_setct_HODInput              "setct-HODInput"
+#define NID_setct_HODInput             526
+#define OBJ_setct_HODInput             OBJ_set_ctype,7L
+
+#define SN_setct_AuthResBaggage                "setct-AuthResBaggage"
+#define NID_setct_AuthResBaggage               527
+#define OBJ_setct_AuthResBaggage               OBJ_set_ctype,8L
+
+#define SN_setct_AuthRevReqBaggage             "setct-AuthRevReqBaggage"
+#define NID_setct_AuthRevReqBaggage            528
+#define OBJ_setct_AuthRevReqBaggage            OBJ_set_ctype,9L
+
+#define SN_setct_AuthRevResBaggage             "setct-AuthRevResBaggage"
+#define NID_setct_AuthRevResBaggage            529
+#define OBJ_setct_AuthRevResBaggage            OBJ_set_ctype,10L
+
+#define SN_setct_CapTokenSeq           "setct-CapTokenSeq"
+#define NID_setct_CapTokenSeq          530
+#define OBJ_setct_CapTokenSeq          OBJ_set_ctype,11L
+
+#define SN_setct_PInitResData          "setct-PInitResData"
+#define NID_setct_PInitResData         531
+#define OBJ_setct_PInitResData         OBJ_set_ctype,12L
+
+#define SN_setct_PI_TBS                "setct-PI-TBS"
+#define NID_setct_PI_TBS               532
+#define OBJ_setct_PI_TBS               OBJ_set_ctype,13L
+
+#define SN_setct_PResData              "setct-PResData"
+#define NID_setct_PResData             533
+#define OBJ_setct_PResData             OBJ_set_ctype,14L
+
+#define SN_setct_AuthReqTBS            "setct-AuthReqTBS"
+#define NID_setct_AuthReqTBS           534
+#define OBJ_setct_AuthReqTBS           OBJ_set_ctype,16L
+
+#define SN_setct_AuthResTBS            "setct-AuthResTBS"
+#define NID_setct_AuthResTBS           535
+#define OBJ_setct_AuthResTBS           OBJ_set_ctype,17L
+
+#define SN_setct_AuthResTBSX           "setct-AuthResTBSX"
+#define NID_setct_AuthResTBSX          536
+#define OBJ_setct_AuthResTBSX          OBJ_set_ctype,18L
+
+#define SN_setct_AuthTokenTBS          "setct-AuthTokenTBS"
+#define NID_setct_AuthTokenTBS         537
+#define OBJ_setct_AuthTokenTBS         OBJ_set_ctype,19L
+
+#define SN_setct_CapTokenData          "setct-CapTokenData"
+#define NID_setct_CapTokenData         538
+#define OBJ_setct_CapTokenData         OBJ_set_ctype,20L
+
+#define SN_setct_CapTokenTBS           "setct-CapTokenTBS"
+#define NID_setct_CapTokenTBS          539
+#define OBJ_setct_CapTokenTBS          OBJ_set_ctype,21L
+
+#define SN_setct_AcqCardCodeMsg                "setct-AcqCardCodeMsg"
+#define NID_setct_AcqCardCodeMsg               540
+#define OBJ_setct_AcqCardCodeMsg               OBJ_set_ctype,22L
+
+#define SN_setct_AuthRevReqTBS         "setct-AuthRevReqTBS"
+#define NID_setct_AuthRevReqTBS                541
+#define OBJ_setct_AuthRevReqTBS                OBJ_set_ctype,23L
+
+#define SN_setct_AuthRevResData                "setct-AuthRevResData"
+#define NID_setct_AuthRevResData               542
+#define OBJ_setct_AuthRevResData               OBJ_set_ctype,24L
+
+#define SN_setct_AuthRevResTBS         "setct-AuthRevResTBS"
+#define NID_setct_AuthRevResTBS                543
+#define OBJ_setct_AuthRevResTBS                OBJ_set_ctype,25L
+
+#define SN_setct_CapReqTBS             "setct-CapReqTBS"
+#define NID_setct_CapReqTBS            544
+#define OBJ_setct_CapReqTBS            OBJ_set_ctype,26L
+
+#define SN_setct_CapReqTBSX            "setct-CapReqTBSX"
+#define NID_setct_CapReqTBSX           545
+#define OBJ_setct_CapReqTBSX           OBJ_set_ctype,27L
+
+#define SN_setct_CapResData            "setct-CapResData"
+#define NID_setct_CapResData           546
+#define OBJ_setct_CapResData           OBJ_set_ctype,28L
+
+#define SN_setct_CapRevReqTBS          "setct-CapRevReqTBS"
+#define NID_setct_CapRevReqTBS         547
+#define OBJ_setct_CapRevReqTBS         OBJ_set_ctype,29L
+
+#define SN_setct_CapRevReqTBSX         "setct-CapRevReqTBSX"
+#define NID_setct_CapRevReqTBSX                548
+#define OBJ_setct_CapRevReqTBSX                OBJ_set_ctype,30L
+
+#define SN_setct_CapRevResData         "setct-CapRevResData"
+#define NID_setct_CapRevResData                549
+#define OBJ_setct_CapRevResData                OBJ_set_ctype,31L
+
+#define SN_setct_CredReqTBS            "setct-CredReqTBS"
+#define NID_setct_CredReqTBS           550
+#define OBJ_setct_CredReqTBS           OBJ_set_ctype,32L
+
+#define SN_setct_CredReqTBSX           "setct-CredReqTBSX"
+#define NID_setct_CredReqTBSX          551
+#define OBJ_setct_CredReqTBSX          OBJ_set_ctype,33L
+
+#define SN_setct_CredResData           "setct-CredResData"
+#define NID_setct_CredResData          552
+#define OBJ_setct_CredResData          OBJ_set_ctype,34L
+
+#define SN_setct_CredRevReqTBS         "setct-CredRevReqTBS"
+#define NID_setct_CredRevReqTBS                553
+#define OBJ_setct_CredRevReqTBS                OBJ_set_ctype,35L
+
+#define SN_setct_CredRevReqTBSX                "setct-CredRevReqTBSX"
+#define NID_setct_CredRevReqTBSX               554
+#define OBJ_setct_CredRevReqTBSX               OBJ_set_ctype,36L
+
+#define SN_setct_CredRevResData                "setct-CredRevResData"
+#define NID_setct_CredRevResData               555
+#define OBJ_setct_CredRevResData               OBJ_set_ctype,37L
+
+#define SN_setct_PCertReqData          "setct-PCertReqData"
+#define NID_setct_PCertReqData         556
+#define OBJ_setct_PCertReqData         OBJ_set_ctype,38L
+
+#define SN_setct_PCertResTBS           "setct-PCertResTBS"
+#define NID_setct_PCertResTBS          557
+#define OBJ_setct_PCertResTBS          OBJ_set_ctype,39L
+
+#define SN_setct_BatchAdminReqData             "setct-BatchAdminReqData"
+#define NID_setct_BatchAdminReqData            558
+#define OBJ_setct_BatchAdminReqData            OBJ_set_ctype,40L
+
+#define SN_setct_BatchAdminResData             "setct-BatchAdminResData"
+#define NID_setct_BatchAdminResData            559
+#define OBJ_setct_BatchAdminResData            OBJ_set_ctype,41L
+
+#define SN_setct_CardCInitResTBS               "setct-CardCInitResTBS"
+#define NID_setct_CardCInitResTBS              560
+#define OBJ_setct_CardCInitResTBS              OBJ_set_ctype,42L
+
+#define SN_setct_MeAqCInitResTBS               "setct-MeAqCInitResTBS"
+#define NID_setct_MeAqCInitResTBS              561
+#define OBJ_setct_MeAqCInitResTBS              OBJ_set_ctype,43L
+
+#define SN_setct_RegFormResTBS         "setct-RegFormResTBS"
+#define NID_setct_RegFormResTBS                562
+#define OBJ_setct_RegFormResTBS                OBJ_set_ctype,44L
+
+#define SN_setct_CertReqData           "setct-CertReqData"
+#define NID_setct_CertReqData          563
+#define OBJ_setct_CertReqData          OBJ_set_ctype,45L
+
+#define SN_setct_CertReqTBS            "setct-CertReqTBS"
+#define NID_setct_CertReqTBS           564
+#define OBJ_setct_CertReqTBS           OBJ_set_ctype,46L
+
+#define SN_setct_CertResData           "setct-CertResData"
+#define NID_setct_CertResData          565
+#define OBJ_setct_CertResData          OBJ_set_ctype,47L
+
+#define SN_setct_CertInqReqTBS         "setct-CertInqReqTBS"
+#define NID_setct_CertInqReqTBS                566
+#define OBJ_setct_CertInqReqTBS                OBJ_set_ctype,48L
+
+#define SN_setct_ErrorTBS              "setct-ErrorTBS"
+#define NID_setct_ErrorTBS             567
+#define OBJ_setct_ErrorTBS             OBJ_set_ctype,49L
+
+#define SN_setct_PIDualSignedTBE               "setct-PIDualSignedTBE"
+#define NID_setct_PIDualSignedTBE              568
+#define OBJ_setct_PIDualSignedTBE              OBJ_set_ctype,50L
+
+#define SN_setct_PIUnsignedTBE         "setct-PIUnsignedTBE"
+#define NID_setct_PIUnsignedTBE                569
+#define OBJ_setct_PIUnsignedTBE                OBJ_set_ctype,51L
+
+#define SN_setct_AuthReqTBE            "setct-AuthReqTBE"
+#define NID_setct_AuthReqTBE           570
+#define OBJ_setct_AuthReqTBE           OBJ_set_ctype,52L
+
+#define SN_setct_AuthResTBE            "setct-AuthResTBE"
+#define NID_setct_AuthResTBE           571
+#define OBJ_setct_AuthResTBE           OBJ_set_ctype,53L
+
+#define SN_setct_AuthResTBEX           "setct-AuthResTBEX"
+#define NID_setct_AuthResTBEX          572
+#define OBJ_setct_AuthResTBEX          OBJ_set_ctype,54L
+
+#define SN_setct_AuthTokenTBE          "setct-AuthTokenTBE"
+#define NID_setct_AuthTokenTBE         573
+#define OBJ_setct_AuthTokenTBE         OBJ_set_ctype,55L
+
+#define SN_setct_CapTokenTBE           "setct-CapTokenTBE"
+#define NID_setct_CapTokenTBE          574
+#define OBJ_setct_CapTokenTBE          OBJ_set_ctype,56L
+
+#define SN_setct_CapTokenTBEX          "setct-CapTokenTBEX"
+#define NID_setct_CapTokenTBEX         575
+#define OBJ_setct_CapTokenTBEX         OBJ_set_ctype,57L
+
+#define SN_setct_AcqCardCodeMsgTBE             "setct-AcqCardCodeMsgTBE"
+#define NID_setct_AcqCardCodeMsgTBE            576
+#define OBJ_setct_AcqCardCodeMsgTBE            OBJ_set_ctype,58L
+
+#define SN_setct_AuthRevReqTBE         "setct-AuthRevReqTBE"
+#define NID_setct_AuthRevReqTBE                577
+#define OBJ_setct_AuthRevReqTBE                OBJ_set_ctype,59L
+
+#define SN_setct_AuthRevResTBE         "setct-AuthRevResTBE"
+#define NID_setct_AuthRevResTBE                578
+#define OBJ_setct_AuthRevResTBE                OBJ_set_ctype,60L
+
+#define SN_setct_AuthRevResTBEB                "setct-AuthRevResTBEB"
+#define NID_setct_AuthRevResTBEB               579
+#define OBJ_setct_AuthRevResTBEB               OBJ_set_ctype,61L
+
+#define SN_setct_CapReqTBE             "setct-CapReqTBE"
+#define NID_setct_CapReqTBE            580
+#define OBJ_setct_CapReqTBE            OBJ_set_ctype,62L
+
+#define SN_setct_CapReqTBEX            "setct-CapReqTBEX"
+#define NID_setct_CapReqTBEX           581
+#define OBJ_setct_CapReqTBEX           OBJ_set_ctype,63L
+
+#define SN_setct_CapResTBE             "setct-CapResTBE"
+#define NID_setct_CapResTBE            582
+#define OBJ_setct_CapResTBE            OBJ_set_ctype,64L
+
+#define SN_setct_CapRevReqTBE          "setct-CapRevReqTBE"
+#define NID_setct_CapRevReqTBE         583
+#define OBJ_setct_CapRevReqTBE         OBJ_set_ctype,65L
+
+#define SN_setct_CapRevReqTBEX         "setct-CapRevReqTBEX"
+#define NID_setct_CapRevReqTBEX                584
+#define OBJ_setct_CapRevReqTBEX                OBJ_set_ctype,66L
+
+#define SN_setct_CapRevResTBE          "setct-CapRevResTBE"
+#define NID_setct_CapRevResTBE         585
+#define OBJ_setct_CapRevResTBE         OBJ_set_ctype,67L
+
+#define SN_setct_CredReqTBE            "setct-CredReqTBE"
+#define NID_setct_CredReqTBE           586
+#define OBJ_setct_CredReqTBE           OBJ_set_ctype,68L
+
+#define SN_setct_CredReqTBEX           "setct-CredReqTBEX"
+#define NID_setct_CredReqTBEX          587
+#define OBJ_setct_CredReqTBEX          OBJ_set_ctype,69L
+
+#define SN_setct_CredResTBE            "setct-CredResTBE"
+#define NID_setct_CredResTBE           588
+#define OBJ_setct_CredResTBE           OBJ_set_ctype,70L
+
+#define SN_setct_CredRevReqTBE         "setct-CredRevReqTBE"
+#define NID_setct_CredRevReqTBE                589
+#define OBJ_setct_CredRevReqTBE                OBJ_set_ctype,71L
+
+#define SN_setct_CredRevReqTBEX                "setct-CredRevReqTBEX"
+#define NID_setct_CredRevReqTBEX               590
+#define OBJ_setct_CredRevReqTBEX               OBJ_set_ctype,72L
+
+#define SN_setct_CredRevResTBE         "setct-CredRevResTBE"
+#define NID_setct_CredRevResTBE                591
+#define OBJ_setct_CredRevResTBE                OBJ_set_ctype,73L
+
+#define SN_setct_BatchAdminReqTBE              "setct-BatchAdminReqTBE"
+#define NID_setct_BatchAdminReqTBE             592
+#define OBJ_setct_BatchAdminReqTBE             OBJ_set_ctype,74L
+
+#define SN_setct_BatchAdminResTBE              "setct-BatchAdminResTBE"
+#define NID_setct_BatchAdminResTBE             593
+#define OBJ_setct_BatchAdminResTBE             OBJ_set_ctype,75L
+
+#define SN_setct_RegFormReqTBE         "setct-RegFormReqTBE"
+#define NID_setct_RegFormReqTBE                594
+#define OBJ_setct_RegFormReqTBE                OBJ_set_ctype,76L
+
+#define SN_setct_CertReqTBE            "setct-CertReqTBE"
+#define NID_setct_CertReqTBE           595
+#define OBJ_setct_CertReqTBE           OBJ_set_ctype,77L
+
+#define SN_setct_CertReqTBEX           "setct-CertReqTBEX"
+#define NID_setct_CertReqTBEX          596
+#define OBJ_setct_CertReqTBEX          OBJ_set_ctype,78L
+
+#define SN_setct_CertResTBE            "setct-CertResTBE"
+#define NID_setct_CertResTBE           597
+#define OBJ_setct_CertResTBE           OBJ_set_ctype,79L
+
+#define SN_setct_CRLNotificationTBS            "setct-CRLNotificationTBS"
+#define NID_setct_CRLNotificationTBS           598
+#define OBJ_setct_CRLNotificationTBS           OBJ_set_ctype,80L
+
+#define SN_setct_CRLNotificationResTBS         "setct-CRLNotificationResTBS"
+#define NID_setct_CRLNotificationResTBS                599
+#define OBJ_setct_CRLNotificationResTBS                OBJ_set_ctype,81L
+
+#define SN_setct_BCIDistributionTBS            "setct-BCIDistributionTBS"
+#define NID_setct_BCIDistributionTBS           600
+#define OBJ_setct_BCIDistributionTBS           OBJ_set_ctype,82L
+
+#define SN_setext_genCrypt             "setext-genCrypt"
+#define LN_setext_genCrypt             "generic cryptogram"
+#define NID_setext_genCrypt            601
+#define OBJ_setext_genCrypt            OBJ_set_msgExt,1L
+
+#define SN_setext_miAuth               "setext-miAuth"
+#define LN_setext_miAuth               "merchant initiated auth"
+#define NID_setext_miAuth              602
+#define OBJ_setext_miAuth              OBJ_set_msgExt,3L
+
+#define SN_setext_pinSecure            "setext-pinSecure"
+#define NID_setext_pinSecure           603
+#define OBJ_setext_pinSecure           OBJ_set_msgExt,4L
+
+#define SN_setext_pinAny               "setext-pinAny"
+#define NID_setext_pinAny              604
+#define OBJ_setext_pinAny              OBJ_set_msgExt,5L
+
+#define SN_setext_track2               "setext-track2"
+#define NID_setext_track2              605
+#define OBJ_setext_track2              OBJ_set_msgExt,7L
+
+#define SN_setext_cv           "setext-cv"
+#define LN_setext_cv           "additional verification"
+#define NID_setext_cv          606
+#define OBJ_setext_cv          OBJ_set_msgExt,8L
+
+#define SN_set_policy_root             "set-policy-root"
+#define NID_set_policy_root            607
+#define OBJ_set_policy_root            OBJ_set_policy,0L
+
+#define SN_setCext_hashedRoot          "setCext-hashedRoot"
+#define NID_setCext_hashedRoot         608
+#define OBJ_setCext_hashedRoot         OBJ_set_certExt,0L
+
+#define SN_setCext_certType            "setCext-certType"
+#define NID_setCext_certType           609
+#define OBJ_setCext_certType           OBJ_set_certExt,1L
+
+#define SN_setCext_merchData           "setCext-merchData"
+#define NID_setCext_merchData          610
+#define OBJ_setCext_merchData          OBJ_set_certExt,2L
+
+#define SN_setCext_cCertRequired               "setCext-cCertRequired"
+#define NID_setCext_cCertRequired              611
+#define OBJ_setCext_cCertRequired              OBJ_set_certExt,3L
+
+#define SN_setCext_tunneling           "setCext-tunneling"
+#define NID_setCext_tunneling          612
+#define OBJ_setCext_tunneling          OBJ_set_certExt,4L
+
+#define SN_setCext_setExt              "setCext-setExt"
+#define NID_setCext_setExt             613
+#define OBJ_setCext_setExt             OBJ_set_certExt,5L
+
+#define SN_setCext_setQualf            "setCext-setQualf"
+#define NID_setCext_setQualf           614
+#define OBJ_setCext_setQualf           OBJ_set_certExt,6L
+
+#define SN_setCext_PGWYcapabilities            "setCext-PGWYcapabilities"
+#define NID_setCext_PGWYcapabilities           615
+#define OBJ_setCext_PGWYcapabilities           OBJ_set_certExt,7L
+
+#define SN_setCext_TokenIdentifier             "setCext-TokenIdentifier"
+#define NID_setCext_TokenIdentifier            616
+#define OBJ_setCext_TokenIdentifier            OBJ_set_certExt,8L
+
+#define SN_setCext_Track2Data          "setCext-Track2Data"
+#define NID_setCext_Track2Data         617
+#define OBJ_setCext_Track2Data         OBJ_set_certExt,9L
+
+#define SN_setCext_TokenType           "setCext-TokenType"
+#define NID_setCext_TokenType          618
+#define OBJ_setCext_TokenType          OBJ_set_certExt,10L
+
+#define SN_setCext_IssuerCapabilities          "setCext-IssuerCapabilities"
+#define NID_setCext_IssuerCapabilities         619
+#define OBJ_setCext_IssuerCapabilities         OBJ_set_certExt,11L
+
+#define SN_setAttr_Cert                "setAttr-Cert"
+#define NID_setAttr_Cert               620
+#define OBJ_setAttr_Cert               OBJ_set_attr,0L
+
+#define SN_setAttr_PGWYcap             "setAttr-PGWYcap"
+#define LN_setAttr_PGWYcap             "payment gateway capabilities"
+#define NID_setAttr_PGWYcap            621
+#define OBJ_setAttr_PGWYcap            OBJ_set_attr,1L
+
+#define SN_setAttr_TokenType           "setAttr-TokenType"
+#define NID_setAttr_TokenType          622
+#define OBJ_setAttr_TokenType          OBJ_set_attr,2L
+
+#define SN_setAttr_IssCap              "setAttr-IssCap"
+#define LN_setAttr_IssCap              "issuer capabilities"
+#define NID_setAttr_IssCap             623
+#define OBJ_setAttr_IssCap             OBJ_set_attr,3L
+
+#define SN_set_rootKeyThumb            "set-rootKeyThumb"
+#define NID_set_rootKeyThumb           624
+#define OBJ_set_rootKeyThumb           OBJ_setAttr_Cert,0L
+
+#define SN_set_addPolicy               "set-addPolicy"
+#define NID_set_addPolicy              625
+#define OBJ_set_addPolicy              OBJ_setAttr_Cert,1L
+
+#define SN_setAttr_Token_EMV           "setAttr-Token-EMV"
+#define NID_setAttr_Token_EMV          626
+#define OBJ_setAttr_Token_EMV          OBJ_setAttr_TokenType,1L
+
+#define SN_setAttr_Token_B0Prime               "setAttr-Token-B0Prime"
+#define NID_setAttr_Token_B0Prime              627
+#define OBJ_setAttr_Token_B0Prime              OBJ_setAttr_TokenType,2L
+
+#define SN_setAttr_IssCap_CVM          "setAttr-IssCap-CVM"
+#define NID_setAttr_IssCap_CVM         628
+#define OBJ_setAttr_IssCap_CVM         OBJ_setAttr_IssCap,3L
+
+#define SN_setAttr_IssCap_T2           "setAttr-IssCap-T2"
+#define NID_setAttr_IssCap_T2          629
+#define OBJ_setAttr_IssCap_T2          OBJ_setAttr_IssCap,4L
+
+#define SN_setAttr_IssCap_Sig          "setAttr-IssCap-Sig"
+#define NID_setAttr_IssCap_Sig         630
+#define OBJ_setAttr_IssCap_Sig         OBJ_setAttr_IssCap,5L
+
+#define SN_setAttr_GenCryptgrm         "setAttr-GenCryptgrm"
+#define LN_setAttr_GenCryptgrm         "generate cryptogram"
+#define NID_setAttr_GenCryptgrm                631
+#define OBJ_setAttr_GenCryptgrm                OBJ_setAttr_IssCap_CVM,1L
+
+#define SN_setAttr_T2Enc               "setAttr-T2Enc"
+#define LN_setAttr_T2Enc               "encrypted track 2"
+#define NID_setAttr_T2Enc              632
+#define OBJ_setAttr_T2Enc              OBJ_setAttr_IssCap_T2,1L
+
+#define SN_setAttr_T2cleartxt          "setAttr-T2cleartxt"
+#define LN_setAttr_T2cleartxt          "cleartext track 2"
+#define NID_setAttr_T2cleartxt         633
+#define OBJ_setAttr_T2cleartxt         OBJ_setAttr_IssCap_T2,2L
+
+#define SN_setAttr_TokICCsig           "setAttr-TokICCsig"
+#define LN_setAttr_TokICCsig           "ICC or token signature"
+#define NID_setAttr_TokICCsig          634
+#define OBJ_setAttr_TokICCsig          OBJ_setAttr_IssCap_Sig,1L
+
+#define SN_setAttr_SecDevSig           "setAttr-SecDevSig"
+#define LN_setAttr_SecDevSig           "secure device signature"
+#define NID_setAttr_SecDevSig          635
+#define OBJ_setAttr_SecDevSig          OBJ_setAttr_IssCap_Sig,2L
+
+#define SN_set_brand_IATA_ATA          "set-brand-IATA-ATA"
+#define NID_set_brand_IATA_ATA         636
+#define OBJ_set_brand_IATA_ATA         OBJ_set_brand,1L
+
+#define SN_set_brand_Diners            "set-brand-Diners"
+#define NID_set_brand_Diners           637
+#define OBJ_set_brand_Diners           OBJ_set_brand,30L
+
+#define SN_set_brand_AmericanExpress           "set-brand-AmericanExpress"
+#define NID_set_brand_AmericanExpress          638
+#define OBJ_set_brand_AmericanExpress          OBJ_set_brand,34L
+
+#define SN_set_brand_JCB               "set-brand-JCB"
+#define NID_set_brand_JCB              639
+#define OBJ_set_brand_JCB              OBJ_set_brand,35L
+
+#define SN_set_brand_Visa              "set-brand-Visa"
+#define NID_set_brand_Visa             640
+#define OBJ_set_brand_Visa             OBJ_set_brand,4L
+
+#define SN_set_brand_MasterCard                "set-brand-MasterCard"
+#define NID_set_brand_MasterCard               641
+#define OBJ_set_brand_MasterCard               OBJ_set_brand,5L
+
+#define SN_set_brand_Novus             "set-brand-Novus"
+#define NID_set_brand_Novus            642
+#define OBJ_set_brand_Novus            OBJ_set_brand,6011L
+
+#define SN_des_cdmf            "DES-CDMF"
+#define LN_des_cdmf            "des-cdmf"
+#define NID_des_cdmf           643
+#define OBJ_des_cdmf           OBJ_rsadsi,3L,10L
+
+#define SN_rsaOAEPEncryptionSET                "rsaOAEPEncryptionSET"
+#define NID_rsaOAEPEncryptionSET               644
+#define OBJ_rsaOAEPEncryptionSET               OBJ_rsadsi,1L,1L,6L
+
diff --git a/crypto/openssl/objects/objects.h b/crypto/openssl/objects/objects.h
new file mode 100644 (file)
index 0000000..456dc11
--- /dev/null
@@ -0,0 +1,1067 @@
+/* crypto/objects/objects.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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+
+#ifndef HEADER_OBJECTS_H
+#define HEADER_OBJECTS_H
+
+#define USE_OBJ_MAC
+
+#ifdef USE_OBJ_MAC
+#include "obj_mac.h"
+#else
+#define SN_undef                       "UNDEF"
+#define LN_undef                       "undefined"
+#define NID_undef                      0
+#define OBJ_undef                      0L
+
+#define SN_Algorithm                   "Algorithm"
+#define LN_algorithm                   "algorithm"
+#define NID_algorithm                  38
+#define OBJ_algorithm                  1L,3L,14L,3L,2L
+
+#define LN_rsadsi                      "rsadsi"
+#define NID_rsadsi                     1
+#define OBJ_rsadsi                     1L,2L,840L,113549L
+
+#define LN_pkcs                                "pkcs"
+#define NID_pkcs                       2
+#define OBJ_pkcs                       OBJ_rsadsi,1L
+
+#define SN_md2                         "MD2"
+#define LN_md2                         "md2"
+#define NID_md2                                3
+#define OBJ_md2                                OBJ_rsadsi,2L,2L
+
+#define SN_md5                         "MD5"
+#define LN_md5                         "md5"
+#define NID_md5                                4
+#define OBJ_md5                                OBJ_rsadsi,2L,5L
+
+#define SN_rc4                         "RC4"
+#define LN_rc4                         "rc4"
+#define NID_rc4                                5
+#define OBJ_rc4                                OBJ_rsadsi,3L,4L
+
+#define LN_rsaEncryption               "rsaEncryption"
+#define NID_rsaEncryption              6
+#define OBJ_rsaEncryption              OBJ_pkcs,1L,1L
+
+#define SN_md2WithRSAEncryption                "RSA-MD2"
+#define LN_md2WithRSAEncryption                "md2WithRSAEncryption"
+#define NID_md2WithRSAEncryption       7
+#define OBJ_md2WithRSAEncryption       OBJ_pkcs,1L,2L
+
+#define SN_md5WithRSAEncryption                "RSA-MD5"
+#define LN_md5WithRSAEncryption                "md5WithRSAEncryption"
+#define NID_md5WithRSAEncryption       8
+#define OBJ_md5WithRSAEncryption       OBJ_pkcs,1L,4L
+
+#define SN_pbeWithMD2AndDES_CBC                "PBE-MD2-DES"
+#define LN_pbeWithMD2AndDES_CBC                "pbeWithMD2AndDES-CBC"
+#define NID_pbeWithMD2AndDES_CBC       9
+#define OBJ_pbeWithMD2AndDES_CBC       OBJ_pkcs,5L,1L
+
+#define SN_pbeWithMD5AndDES_CBC                "PBE-MD5-DES"
+#define LN_pbeWithMD5AndDES_CBC                "pbeWithMD5AndDES-CBC"
+#define NID_pbeWithMD5AndDES_CBC       10
+#define OBJ_pbeWithMD5AndDES_CBC       OBJ_pkcs,5L,3L
+
+#define LN_X500                                "X500"
+#define NID_X500                       11
+#define OBJ_X500                       2L,5L
+
+#define LN_X509                                "X509"
+#define NID_X509                       12
+#define OBJ_X509                       OBJ_X500,4L
+
+#define SN_commonName                  "CN"
+#define LN_commonName                  "commonName"
+#define NID_commonName                 13
+#define OBJ_commonName                 OBJ_X509,3L
+
+#define SN_countryName                 "C"
+#define LN_countryName                 "countryName"
+#define NID_countryName                        14
+#define OBJ_countryName                        OBJ_X509,6L
+
+#define SN_localityName                        "L"
+#define LN_localityName                        "localityName"
+#define NID_localityName               15
+#define OBJ_localityName               OBJ_X509,7L
+
+/* Postal Address? PA */
+
+/* should be "ST" (rfc1327) but MS uses 'S' */
+#define SN_stateOrProvinceName         "ST"
+#define LN_stateOrProvinceName         "stateOrProvinceName"
+#define NID_stateOrProvinceName                16
+#define OBJ_stateOrProvinceName                OBJ_X509,8L
+
+#define SN_organizationName            "O"
+#define LN_organizationName            "organizationName"
+#define NID_organizationName           17
+#define OBJ_organizationName           OBJ_X509,10L
+
+#define SN_organizationalUnitName      "OU"
+#define LN_organizationalUnitName      "organizationalUnitName"
+#define NID_organizationalUnitName     18
+#define OBJ_organizationalUnitName     OBJ_X509,11L
+
+#define SN_rsa                         "RSA"
+#define LN_rsa                         "rsa"
+#define NID_rsa                                19
+#define OBJ_rsa                                OBJ_X500,8L,1L,1L
+
+#define LN_pkcs7                       "pkcs7"
+#define NID_pkcs7                      20
+#define OBJ_pkcs7                      OBJ_pkcs,7L
+
+#define LN_pkcs7_data                  "pkcs7-data"
+#define NID_pkcs7_data                 21
+#define OBJ_pkcs7_data                 OBJ_pkcs7,1L
+
+#define LN_pkcs7_signed                        "pkcs7-signedData"
+#define NID_pkcs7_signed               22
+#define OBJ_pkcs7_signed               OBJ_pkcs7,2L
+
+#define LN_pkcs7_enveloped             "pkcs7-envelopedData"
+#define NID_pkcs7_enveloped            23
+#define OBJ_pkcs7_enveloped            OBJ_pkcs7,3L
+
+#define LN_pkcs7_signedAndEnveloped    "pkcs7-signedAndEnvelopedData"
+#define NID_pkcs7_signedAndEnveloped   24
+#define OBJ_pkcs7_signedAndEnveloped   OBJ_pkcs7,4L
+
+#define LN_pkcs7_digest                        "pkcs7-digestData"
+#define NID_pkcs7_digest               25
+#define OBJ_pkcs7_digest               OBJ_pkcs7,5L
+
+#define LN_pkcs7_encrypted             "pkcs7-encryptedData"
+#define NID_pkcs7_encrypted            26
+#define OBJ_pkcs7_encrypted            OBJ_pkcs7,6L
+
+#define LN_pkcs3                       "pkcs3"
+#define NID_pkcs3                      27
+#define OBJ_pkcs3                      OBJ_pkcs,3L
+
+#define LN_dhKeyAgreement              "dhKeyAgreement"
+#define NID_dhKeyAgreement             28
+#define OBJ_dhKeyAgreement             OBJ_pkcs3,1L
+
+#define SN_des_ecb                     "DES-ECB"
+#define LN_des_ecb                     "des-ecb"
+#define NID_des_ecb                    29
+#define OBJ_des_ecb                    OBJ_algorithm,6L
+
+#define SN_des_cfb64                   "DES-CFB"
+#define LN_des_cfb64                   "des-cfb"
+#define NID_des_cfb64                  30
+/* IV + num */
+#define OBJ_des_cfb64                  OBJ_algorithm,9L
+
+#define SN_des_cbc                     "DES-CBC"
+#define LN_des_cbc                     "des-cbc"
+#define NID_des_cbc                    31
+/* IV */
+#define OBJ_des_cbc                    OBJ_algorithm,7L
+
+#define SN_des_ede                     "DES-EDE"
+#define LN_des_ede                     "des-ede"
+#define NID_des_ede                    32
+/* ?? */
+#define OBJ_des_ede                    OBJ_algorithm,17L
+
+#define SN_des_ede3                    "DES-EDE3"
+#define LN_des_ede3                    "des-ede3"
+#define NID_des_ede3                   33
+
+#define SN_idea_cbc                    "IDEA-CBC"
+#define LN_idea_cbc                    "idea-cbc"
+#define NID_idea_cbc                   34
+#define OBJ_idea_cbc                   1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L
+
+#define SN_idea_cfb64                  "IDEA-CFB"
+#define LN_idea_cfb64                  "idea-cfb"
+#define NID_idea_cfb64                 35
+
+#define SN_idea_ecb                    "IDEA-ECB"
+#define LN_idea_ecb                    "idea-ecb"
+#define NID_idea_ecb                   36
+
+#define SN_rc2_cbc                     "RC2-CBC"
+#define LN_rc2_cbc                     "rc2-cbc"
+#define NID_rc2_cbc                    37
+#define OBJ_rc2_cbc                    OBJ_rsadsi,3L,2L
+
+#define SN_rc2_ecb                     "RC2-ECB"
+#define LN_rc2_ecb                     "rc2-ecb"
+#define NID_rc2_ecb                    38
+
+#define SN_rc2_cfb64                   "RC2-CFB"
+#define LN_rc2_cfb64                   "rc2-cfb"
+#define NID_rc2_cfb64                  39
+
+#define SN_rc2_ofb64                   "RC2-OFB"
+#define LN_rc2_ofb64                   "rc2-ofb"
+#define NID_rc2_ofb64                  40
+
+#define SN_sha                         "SHA"
+#define LN_sha                         "sha"
+#define NID_sha                                41
+#define OBJ_sha                                OBJ_algorithm,18L
+
+#define SN_shaWithRSAEncryption                "RSA-SHA"
+#define LN_shaWithRSAEncryption                "shaWithRSAEncryption"
+#define NID_shaWithRSAEncryption       42
+#define OBJ_shaWithRSAEncryption       OBJ_algorithm,15L
+
+#define SN_des_ede_cbc                 "DES-EDE-CBC"
+#define LN_des_ede_cbc                 "des-ede-cbc"
+#define NID_des_ede_cbc                        43
+
+#define SN_des_ede3_cbc                        "DES-EDE3-CBC"
+#define LN_des_ede3_cbc                        "des-ede3-cbc"
+#define NID_des_ede3_cbc               44
+#define OBJ_des_ede3_cbc               OBJ_rsadsi,3L,7L
+
+#define SN_des_ofb64                   "DES-OFB"
+#define LN_des_ofb64                   "des-ofb"
+#define NID_des_ofb64                  45
+#define OBJ_des_ofb64                  OBJ_algorithm,8L
+
+#define SN_idea_ofb64                  "IDEA-OFB"
+#define LN_idea_ofb64                  "idea-ofb"
+#define NID_idea_ofb64                 46
+
+#define LN_pkcs9                       "pkcs9"
+#define NID_pkcs9                      47
+#define OBJ_pkcs9                      OBJ_pkcs,9L
+
+#define SN_pkcs9_emailAddress          "Email"
+#define LN_pkcs9_emailAddress          "emailAddress"
+#define NID_pkcs9_emailAddress         48
+#define OBJ_pkcs9_emailAddress         OBJ_pkcs9,1L
+
+#define LN_pkcs9_unstructuredName      "unstructuredName"
+#define NID_pkcs9_unstructuredName     49
+#define OBJ_pkcs9_unstructuredName     OBJ_pkcs9,2L
+
+#define LN_pkcs9_contentType           "contentType"
+#define NID_pkcs9_contentType          50
+#define OBJ_pkcs9_contentType          OBJ_pkcs9,3L
+
+#define LN_pkcs9_messageDigest         "messageDigest"
+#define NID_pkcs9_messageDigest                51
+#define OBJ_pkcs9_messageDigest                OBJ_pkcs9,4L
+
+#define LN_pkcs9_signingTime           "signingTime"
+#define NID_pkcs9_signingTime          52
+#define OBJ_pkcs9_signingTime          OBJ_pkcs9,5L
+
+#define LN_pkcs9_countersignature      "countersignature"
+#define NID_pkcs9_countersignature     53
+#define OBJ_pkcs9_countersignature     OBJ_pkcs9,6L
+
+#define LN_pkcs9_challengePassword     "challengePassword"
+#define NID_pkcs9_challengePassword    54
+#define OBJ_pkcs9_challengePassword    OBJ_pkcs9,7L
+
+#define LN_pkcs9_unstructuredAddress   "unstructuredAddress"
+#define NID_pkcs9_unstructuredAddress  55
+#define OBJ_pkcs9_unstructuredAddress  OBJ_pkcs9,8L
+
+#define LN_pkcs9_extCertAttributes     "extendedCertificateAttributes"
+#define NID_pkcs9_extCertAttributes    56
+#define OBJ_pkcs9_extCertAttributes    OBJ_pkcs9,9L
+
+#define SN_netscape                    "Netscape"
+#define LN_netscape                    "Netscape Communications Corp."
+#define NID_netscape                   57
+#define OBJ_netscape                   2L,16L,840L,1L,113730L
+
+#define SN_netscape_cert_extension     "nsCertExt"
+#define LN_netscape_cert_extension     "Netscape Certificate Extension"
+#define NID_netscape_cert_extension    58
+#define OBJ_netscape_cert_extension    OBJ_netscape,1L
+
+#define SN_netscape_data_type          "nsDataType"
+#define LN_netscape_data_type          "Netscape Data Type"
+#define NID_netscape_data_type         59
+#define OBJ_netscape_data_type         OBJ_netscape,2L
+
+#define SN_des_ede_cfb64               "DES-EDE-CFB"
+#define LN_des_ede_cfb64               "des-ede-cfb"
+#define NID_des_ede_cfb64              60
+
+#define SN_des_ede3_cfb64              "DES-EDE3-CFB"
+#define LN_des_ede3_cfb64              "des-ede3-cfb"
+#define NID_des_ede3_cfb64             61
+
+#define SN_des_ede_ofb64               "DES-EDE-OFB"
+#define LN_des_ede_ofb64               "des-ede-ofb"
+#define NID_des_ede_ofb64              62
+
+#define SN_des_ede3_ofb64              "DES-EDE3-OFB"
+#define LN_des_ede3_ofb64              "des-ede3-ofb"
+#define NID_des_ede3_ofb64             63
+
+/* I'm not sure about the object ID */
+#define SN_sha1                                "SHA1"
+#define LN_sha1                                "sha1"
+#define NID_sha1                       64
+#define OBJ_sha1                       OBJ_algorithm,26L
+/* 28 Jun 1996 - eay */
+/* #define OBJ_sha1                    1L,3L,14L,2L,26L,05L <- wrong */
+
+#define SN_sha1WithRSAEncryption       "RSA-SHA1"
+#define LN_sha1WithRSAEncryption       "sha1WithRSAEncryption"
+#define NID_sha1WithRSAEncryption      65
+#define OBJ_sha1WithRSAEncryption      OBJ_pkcs,1L,5L
+
+#define SN_dsaWithSHA                  "DSA-SHA"
+#define LN_dsaWithSHA                  "dsaWithSHA"
+#define NID_dsaWithSHA                 66
+#define OBJ_dsaWithSHA                 OBJ_algorithm,13L
+
+#define SN_dsa_2                       "DSA-old"
+#define LN_dsa_2                       "dsaEncryption-old"
+#define NID_dsa_2                      67
+#define OBJ_dsa_2                      OBJ_algorithm,12L
+
+/* proposed by microsoft to RSA */
+#define SN_pbeWithSHA1AndRC2_CBC       "PBE-SHA1-RC2-64"
+#define LN_pbeWithSHA1AndRC2_CBC       "pbeWithSHA1AndRC2-CBC"
+#define NID_pbeWithSHA1AndRC2_CBC      68
+#define OBJ_pbeWithSHA1AndRC2_CBC      OBJ_pkcs,5L,11L 
+
+/* proposed by microsoft to RSA as pbeWithSHA1AndRC4: it is now
+ * defined explicitly in PKCS#5 v2.0 as id-PBKDF2 which is something
+ * completely different.
+ */
+#define LN_id_pbkdf2                   "PBKDF2"
+#define NID_id_pbkdf2                  69
+#define OBJ_id_pbkdf2                  OBJ_pkcs,5L,12L 
+
+#define SN_dsaWithSHA1_2               "DSA-SHA1-old"
+#define LN_dsaWithSHA1_2               "dsaWithSHA1-old"
+#define NID_dsaWithSHA1_2              70
+/* Got this one from 'sdn706r20.pdf' which is actually an NSA document :-) */
+#define OBJ_dsaWithSHA1_2              OBJ_algorithm,27L
+
+#define SN_netscape_cert_type          "nsCertType"
+#define LN_netscape_cert_type          "Netscape Cert Type"
+#define NID_netscape_cert_type         71
+#define OBJ_netscape_cert_type         OBJ_netscape_cert_extension,1L
+
+#define SN_netscape_base_url           "nsBaseUrl"
+#define LN_netscape_base_url           "Netscape Base Url"
+#define NID_netscape_base_url          72
+#define OBJ_netscape_base_url          OBJ_netscape_cert_extension,2L
+
+#define SN_netscape_revocation_url     "nsRevocationUrl"
+#define LN_netscape_revocation_url     "Netscape Revocation Url"
+#define NID_netscape_revocation_url    73
+#define OBJ_netscape_revocation_url    OBJ_netscape_cert_extension,3L
+
+#define SN_netscape_ca_revocation_url  "nsCaRevocationUrl"
+#define LN_netscape_ca_revocation_url  "Netscape CA Revocation Url"
+#define NID_netscape_ca_revocation_url 74
+#define OBJ_netscape_ca_revocation_url OBJ_netscape_cert_extension,4L
+
+#define SN_netscape_renewal_url                "nsRenewalUrl"
+#define LN_netscape_renewal_url                "Netscape Renewal Url"
+#define NID_netscape_renewal_url       75
+#define OBJ_netscape_renewal_url       OBJ_netscape_cert_extension,7L
+
+#define SN_netscape_ca_policy_url      "nsCaPolicyUrl"
+#define LN_netscape_ca_policy_url      "Netscape CA Policy Url"
+#define NID_netscape_ca_policy_url     76
+#define OBJ_netscape_ca_policy_url     OBJ_netscape_cert_extension,8L
+
+#define SN_netscape_ssl_server_name    "nsSslServerName"
+#define LN_netscape_ssl_server_name    "Netscape SSL Server Name"
+#define NID_netscape_ssl_server_name   77
+#define OBJ_netscape_ssl_server_name   OBJ_netscape_cert_extension,12L
+
+#define SN_netscape_comment            "nsComment"
+#define LN_netscape_comment            "Netscape Comment"
+#define NID_netscape_comment           78
+#define OBJ_netscape_comment           OBJ_netscape_cert_extension,13L
+
+#define SN_netscape_cert_sequence      "nsCertSequence"
+#define LN_netscape_cert_sequence      "Netscape Certificate Sequence"
+#define NID_netscape_cert_sequence     79
+#define OBJ_netscape_cert_sequence     OBJ_netscape_data_type,5L
+
+#define SN_desx_cbc                    "DESX-CBC"
+#define LN_desx_cbc                    "desx-cbc"
+#define NID_desx_cbc                   80
+
+#define SN_id_ce                       "id-ce"
+#define NID_id_ce                      81
+#define OBJ_id_ce                      2L,5L,29L
+
+#define SN_subject_key_identifier      "subjectKeyIdentifier"
+#define LN_subject_key_identifier      "X509v3 Subject Key Identifier"
+#define NID_subject_key_identifier     82
+#define OBJ_subject_key_identifier     OBJ_id_ce,14L
+
+#define SN_key_usage                   "keyUsage"
+#define LN_key_usage                   "X509v3 Key Usage"
+#define NID_key_usage                  83
+#define OBJ_key_usage                  OBJ_id_ce,15L
+
+#define SN_private_key_usage_period    "privateKeyUsagePeriod"
+#define LN_private_key_usage_period    "X509v3 Private Key Usage Period"
+#define NID_private_key_usage_period   84
+#define OBJ_private_key_usage_period   OBJ_id_ce,16L
+
+#define SN_subject_alt_name            "subjectAltName"
+#define LN_subject_alt_name            "X509v3 Subject Alternative Name"
+#define NID_subject_alt_name           85
+#define OBJ_subject_alt_name           OBJ_id_ce,17L
+
+#define SN_issuer_alt_name             "issuerAltName"
+#define LN_issuer_alt_name             "X509v3 Issuer Alternative Name"
+#define NID_issuer_alt_name            86
+#define OBJ_issuer_alt_name            OBJ_id_ce,18L
+
+#define SN_basic_constraints           "basicConstraints"
+#define LN_basic_constraints           "X509v3 Basic Constraints"
+#define NID_basic_constraints          87
+#define OBJ_basic_constraints          OBJ_id_ce,19L
+
+#define SN_crl_number                  "crlNumber"
+#define LN_crl_number                  "X509v3 CRL Number"
+#define NID_crl_number                 88
+#define OBJ_crl_number                 OBJ_id_ce,20L
+
+#define SN_certificate_policies                "certificatePolicies"
+#define LN_certificate_policies                "X509v3 Certificate Policies"
+#define NID_certificate_policies       89
+#define OBJ_certificate_policies       OBJ_id_ce,32L
+
+#define SN_authority_key_identifier    "authorityKeyIdentifier"
+#define LN_authority_key_identifier    "X509v3 Authority Key Identifier"
+#define NID_authority_key_identifier   90
+#define OBJ_authority_key_identifier   OBJ_id_ce,35L
+
+#define SN_bf_cbc                      "BF-CBC"
+#define LN_bf_cbc                      "bf-cbc"
+#define NID_bf_cbc                     91
+#define OBJ_bf_cbc                     1L,3L,6L,1L,4L,1L,3029L,1L,2L
+
+#define SN_bf_ecb                      "BF-ECB"
+#define LN_bf_ecb                      "bf-ecb"
+#define NID_bf_ecb                     92
+
+#define SN_bf_cfb64                    "BF-CFB"
+#define LN_bf_cfb64                    "bf-cfb"
+#define NID_bf_cfb64                   93
+
+#define SN_bf_ofb64                    "BF-OFB"
+#define LN_bf_ofb64                    "bf-ofb"
+#define NID_bf_ofb64                   94
+
+#define SN_mdc2                                "MDC2"
+#define LN_mdc2                                "mdc2"
+#define NID_mdc2                       95
+#define OBJ_mdc2                       2L,5L,8L,3L,101L
+/* An alternative?                     1L,3L,14L,3L,2L,19L */
+
+#define SN_mdc2WithRSA                 "RSA-MDC2"
+#define LN_mdc2WithRSA                 "mdc2withRSA"
+#define NID_mdc2WithRSA                        96
+#define OBJ_mdc2WithRSA                        2L,5L,8L,3L,100L
+
+#define SN_rc4_40                      "RC4-40"
+#define LN_rc4_40                      "rc4-40"
+#define NID_rc4_40                     97
+
+#define SN_rc2_40_cbc                  "RC2-40-CBC"
+#define LN_rc2_40_cbc                  "rc2-40-cbc"
+#define NID_rc2_40_cbc                 98
+
+#define SN_givenName                   "G"
+#define LN_givenName                   "givenName"
+#define NID_givenName                  99
+#define OBJ_givenName                  OBJ_X509,42L
+
+#define SN_surname                     "S"
+#define LN_surname                     "surname"
+#define NID_surname                    100
+#define OBJ_surname                    OBJ_X509,4L
+
+#define SN_initials                    "I"
+#define LN_initials                    "initials"
+#define NID_initials                   101
+#define OBJ_initials                   OBJ_X509,43L
+
+#define SN_uniqueIdentifier            "UID"
+#define LN_uniqueIdentifier            "uniqueIdentifier"
+#define NID_uniqueIdentifier           102
+#define OBJ_uniqueIdentifier           OBJ_X509,45L
+
+#define SN_crl_distribution_points     "crlDistributionPoints"
+#define LN_crl_distribution_points     "X509v3 CRL Distribution Points"
+#define NID_crl_distribution_points    103
+#define OBJ_crl_distribution_points    OBJ_id_ce,31L
+
+#define SN_md5WithRSA                  "RSA-NP-MD5"
+#define LN_md5WithRSA                  "md5WithRSA"
+#define NID_md5WithRSA                 104
+#define OBJ_md5WithRSA                 OBJ_algorithm,3L
+
+#define SN_serialNumber                        "SN"
+#define LN_serialNumber                        "serialNumber"
+#define NID_serialNumber               105
+#define OBJ_serialNumber               OBJ_X509,5L
+
+#define SN_title                       "T"
+#define LN_title                       "title"
+#define NID_title                      106
+#define OBJ_title                      OBJ_X509,12L
+
+#define SN_description                 "D"
+#define LN_description                 "description"
+#define NID_description                        107
+#define OBJ_description                        OBJ_X509,13L
+
+/* CAST5 is CAST-128, I'm just sticking with the documentation */
+#define SN_cast5_cbc                   "CAST5-CBC"
+#define LN_cast5_cbc                   "cast5-cbc"
+#define NID_cast5_cbc                  108
+#define OBJ_cast5_cbc                  1L,2L,840L,113533L,7L,66L,10L
+
+#define SN_cast5_ecb                   "CAST5-ECB"
+#define LN_cast5_ecb                   "cast5-ecb"
+#define NID_cast5_ecb                  109
+
+#define SN_cast5_cfb64                 "CAST5-CFB"
+#define LN_cast5_cfb64                 "cast5-cfb"
+#define NID_cast5_cfb64                        110
+
+#define SN_cast5_ofb64                 "CAST5-OFB"
+#define LN_cast5_ofb64                 "cast5-ofb"
+#define NID_cast5_ofb64                        111
+
+#define LN_pbeWithMD5AndCast5_CBC      "pbeWithMD5AndCast5CBC"
+#define NID_pbeWithMD5AndCast5_CBC     112
+#define OBJ_pbeWithMD5AndCast5_CBC     1L,2L,840L,113533L,7L,66L,12L
+
+/* This is one sun will soon be using :-(
+ * id-dsa-with-sha1 ID  ::= {
+ *   iso(1) member-body(2) us(840) x9-57 (10040) x9cm(4) 3 }
+ */
+#define SN_dsaWithSHA1                 "DSA-SHA1"
+#define LN_dsaWithSHA1                 "dsaWithSHA1"
+#define NID_dsaWithSHA1                        113
+#define OBJ_dsaWithSHA1                        1L,2L,840L,10040L,4L,3L
+
+#define NID_md5_sha1                   114
+#define SN_md5_sha1                    "MD5-SHA1"
+#define LN_md5_sha1                    "md5-sha1"
+
+#define SN_sha1WithRSA                 "RSA-SHA1-2"
+#define LN_sha1WithRSA                 "sha1WithRSA"
+#define NID_sha1WithRSA                        115
+#define OBJ_sha1WithRSA                        OBJ_algorithm,29L
+
+#define SN_dsa                         "DSA"
+#define LN_dsa                         "dsaEncryption"
+#define NID_dsa                                116
+#define OBJ_dsa                                1L,2L,840L,10040L,4L,1L
+
+#define SN_ripemd160                   "RIPEMD160"
+#define LN_ripemd160                   "ripemd160"
+#define NID_ripemd160                  117
+#define OBJ_ripemd160                  1L,3L,36L,3L,2L,1L
+
+/* The name should actually be rsaSignatureWithripemd160, but I'm going
+ * to continue using the convention I'm using with the other ciphers */
+#define SN_ripemd160WithRSA            "RSA-RIPEMD160"
+#define LN_ripemd160WithRSA            "ripemd160WithRSA"
+#define NID_ripemd160WithRSA           119
+#define OBJ_ripemd160WithRSA           1L,3L,36L,3L,3L,1L,2L
+
+/* Taken from rfc2040
+ *  RC5_CBC_Parameters ::= SEQUENCE {
+ *     version           INTEGER (v1_0(16)),
+ *     rounds            INTEGER (8..127),
+ *     blockSizeInBits   INTEGER (64, 128),
+ *     iv                OCTET STRING OPTIONAL
+ *     }
+ */
+#define SN_rc5_cbc                     "RC5-CBC"
+#define LN_rc5_cbc                     "rc5-cbc"
+#define NID_rc5_cbc                    120
+#define OBJ_rc5_cbc                    OBJ_rsadsi,3L,8L
+
+#define SN_rc5_ecb                     "RC5-ECB"
+#define LN_rc5_ecb                     "rc5-ecb"
+#define NID_rc5_ecb                    121
+
+#define SN_rc5_cfb64                   "RC5-CFB"
+#define LN_rc5_cfb64                   "rc5-cfb"
+#define NID_rc5_cfb64                  122
+
+#define SN_rc5_ofb64                   "RC5-OFB"
+#define LN_rc5_ofb64                   "rc5-ofb"
+#define NID_rc5_ofb64                  123
+
+#define SN_rle_compression             "RLE"
+#define LN_rle_compression             "run length compression"
+#define NID_rle_compression            124
+#define OBJ_rle_compression            1L,1L,1L,1L,666L,1L
+
+#define SN_zlib_compression            "ZLIB"
+#define LN_zlib_compression            "zlib compression"
+#define NID_zlib_compression           125
+#define OBJ_zlib_compression           1L,1L,1L,1L,666L,2L
+
+#define SN_ext_key_usage               "extendedKeyUsage"
+#define LN_ext_key_usage               "X509v3 Extended Key Usage"
+#define NID_ext_key_usage              126
+#define OBJ_ext_key_usage              OBJ_id_ce,37
+
+#define SN_id_pkix                     "PKIX"
+#define NID_id_pkix                    127
+#define OBJ_id_pkix                    1L,3L,6L,1L,5L,5L,7L
+
+#define SN_id_kp                       "id-kp"
+#define NID_id_kp                      128
+#define OBJ_id_kp                      OBJ_id_pkix,3L
+
+/* PKIX extended key usage OIDs */
+
+#define SN_server_auth                 "serverAuth"
+#define LN_server_auth                 "TLS Web Server Authentication"
+#define NID_server_auth                        129
+#define OBJ_server_auth                        OBJ_id_kp,1L
+
+#define SN_client_auth                 "clientAuth"
+#define LN_client_auth                 "TLS Web Client Authentication"
+#define NID_client_auth                        130
+#define OBJ_client_auth                        OBJ_id_kp,2L
+
+#define SN_code_sign                   "codeSigning"
+#define LN_code_sign                   "Code Signing"
+#define NID_code_sign                  131
+#define OBJ_code_sign                  OBJ_id_kp,3L
+
+#define SN_email_protect               "emailProtection"
+#define LN_email_protect               "E-mail Protection"
+#define NID_email_protect              132
+#define OBJ_email_protect              OBJ_id_kp,4L
+
+#define SN_time_stamp                  "timeStamping"
+#define LN_time_stamp                  "Time Stamping"
+#define NID_time_stamp                 133
+#define OBJ_time_stamp                 OBJ_id_kp,8L
+
+/* Additional extended key usage OIDs: Microsoft */
+
+#define SN_ms_code_ind                 "msCodeInd"
+#define LN_ms_code_ind                 "Microsoft Individual Code Signing"
+#define NID_ms_code_ind                        134
+#define OBJ_ms_code_ind                        1L,3L,6L,1L,4L,1L,311L,2L,1L,21L
+
+#define SN_ms_code_com                 "msCodeCom"
+#define LN_ms_code_com                 "Microsoft Commercial Code Signing"
+#define NID_ms_code_com                        135
+#define OBJ_ms_code_com                        1L,3L,6L,1L,4L,1L,311L,2L,1L,22L
+
+#define SN_ms_ctl_sign                 "msCTLSign"
+#define LN_ms_ctl_sign                 "Microsoft Trust List Signing"
+#define NID_ms_ctl_sign                        136
+#define OBJ_ms_ctl_sign                        1L,3L,6L,1L,4L,1L,311L,10L,3L,1L
+
+#define SN_ms_sgc                      "msSGC"
+#define LN_ms_sgc                      "Microsoft Server Gated Crypto"
+#define NID_ms_sgc                     137
+#define OBJ_ms_sgc                     1L,3L,6L,1L,4L,1L,311L,10L,3L,3L
+
+#define SN_ms_efs                      "msEFS"
+#define LN_ms_efs                      "Microsoft Encrypted File System"
+#define NID_ms_efs                     138
+#define OBJ_ms_efs                     1L,3L,6L,1L,4L,1L,311L,10L,3L,4L
+
+/* Additional usage: Netscape */
+
+#define SN_ns_sgc                      "nsSGC"
+#define LN_ns_sgc                      "Netscape Server Gated Crypto"
+#define NID_ns_sgc                     139
+#define OBJ_ns_sgc                     OBJ_netscape,4L,1L
+
+#define SN_delta_crl                   "deltaCRL"
+#define LN_delta_crl                   "X509v3 Delta CRL Indicator"
+#define NID_delta_crl                  140
+#define OBJ_delta_crl                  OBJ_id_ce,27L
+
+#define SN_crl_reason                  "CRLReason"
+#define LN_crl_reason                  "CRL Reason Code"
+#define NID_crl_reason                 141
+#define OBJ_crl_reason                 OBJ_id_ce,21L
+
+#define SN_invalidity_date             "invalidityDate"
+#define LN_invalidity_date             "Invalidity Date"
+#define NID_invalidity_date            142
+#define OBJ_invalidity_date            OBJ_id_ce,24L
+
+#define SN_sxnet                       "SXNetID"
+#define LN_sxnet                       "Strong Extranet ID"
+#define NID_sxnet                      143
+#define OBJ_sxnet                      1L,3L,101L,1L,4L,1L
+
+/* PKCS12 and related OBJECT IDENTIFIERS */
+
+#define OBJ_pkcs12                     OBJ_pkcs,12L
+#define OBJ_pkcs12_pbeids              OBJ_pkcs12, 1
+
+#define SN_pbe_WithSHA1And128BitRC4    "PBE-SHA1-RC4-128"
+#define LN_pbe_WithSHA1And128BitRC4    "pbeWithSHA1And128BitRC4"
+#define NID_pbe_WithSHA1And128BitRC4   144
+#define OBJ_pbe_WithSHA1And128BitRC4   OBJ_pkcs12_pbeids, 1L
+
+#define SN_pbe_WithSHA1And40BitRC4     "PBE-SHA1-RC4-40"
+#define LN_pbe_WithSHA1And40BitRC4     "pbeWithSHA1And40BitRC4"
+#define NID_pbe_WithSHA1And40BitRC4    145
+#define OBJ_pbe_WithSHA1And40BitRC4    OBJ_pkcs12_pbeids, 2L
+
+#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC  "PBE-SHA1-3DES"
+#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC  "pbeWithSHA1And3-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146
+#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids, 3L
+
+#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC  "PBE-SHA1-2DES"
+#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC  "pbeWithSHA1And2-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147
+#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids, 4L
+
+#define SN_pbe_WithSHA1And128BitRC2_CBC                "PBE-SHA1-RC2-128"
+#define LN_pbe_WithSHA1And128BitRC2_CBC                "pbeWithSHA1And128BitRC2-CBC"
+#define NID_pbe_WithSHA1And128BitRC2_CBC       148
+#define OBJ_pbe_WithSHA1And128BitRC2_CBC       OBJ_pkcs12_pbeids, 5L
+
+#define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40"
+#define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC"
+#define NID_pbe_WithSHA1And40BitRC2_CBC        149
+#define OBJ_pbe_WithSHA1And40BitRC2_CBC        OBJ_pkcs12_pbeids, 6L
+
+#define OBJ_pkcs12_Version1    OBJ_pkcs12, 10L
+
+#define OBJ_pkcs12_BagIds      OBJ_pkcs12_Version1, 1L
+
+#define LN_keyBag              "keyBag"
+#define NID_keyBag             150
+#define OBJ_keyBag             OBJ_pkcs12_BagIds, 1L
+
+#define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag"
+#define NID_pkcs8ShroudedKeyBag        151
+#define OBJ_pkcs8ShroudedKeyBag        OBJ_pkcs12_BagIds, 2L
+
+#define LN_certBag             "certBag"
+#define NID_certBag            152
+#define OBJ_certBag            OBJ_pkcs12_BagIds, 3L
+
+#define LN_crlBag              "crlBag"
+#define NID_crlBag             153
+#define OBJ_crlBag             OBJ_pkcs12_BagIds, 4L
+
+#define LN_secretBag           "secretBag"
+#define NID_secretBag          154
+#define OBJ_secretBag          OBJ_pkcs12_BagIds, 5L
+
+#define LN_safeContentsBag     "safeContentsBag"
+#define NID_safeContentsBag    155
+#define OBJ_safeContentsBag    OBJ_pkcs12_BagIds, 6L
+
+#define LN_friendlyName                "friendlyName"
+#define        NID_friendlyName        156
+#define OBJ_friendlyName       OBJ_pkcs9, 20L
+
+#define LN_localKeyID          "localKeyID"
+#define        NID_localKeyID          157
+#define OBJ_localKeyID         OBJ_pkcs9, 21L
+
+#define OBJ_certTypes          OBJ_pkcs9, 22L
+
+#define LN_x509Certificate     "x509Certificate"
+#define        NID_x509Certificate     158
+#define OBJ_x509Certificate    OBJ_certTypes, 1L
+
+#define LN_sdsiCertificate     "sdsiCertificate"
+#define        NID_sdsiCertificate     159
+#define OBJ_sdsiCertificate    OBJ_certTypes, 2L
+
+#define OBJ_crlTypes           OBJ_pkcs9, 23L
+
+#define LN_x509Crl             "x509Crl"
+#define        NID_x509Crl             160
+#define OBJ_x509Crl            OBJ_crlTypes, 1L
+
+/* PKCS#5 v2 OIDs */
+
+#define LN_pbes2               "PBES2"
+#define NID_pbes2              161
+#define OBJ_pbes2              OBJ_pkcs,5L,13L
+
+#define LN_pbmac1              "PBMAC1"
+#define NID_pbmac1             162
+#define OBJ_pbmac1             OBJ_pkcs,5L,14L
+
+#define LN_hmacWithSHA1                "hmacWithSHA1"
+#define NID_hmacWithSHA1       163
+#define OBJ_hmacWithSHA1       OBJ_rsadsi,2L,7L
+
+/* Policy Qualifier Ids */
+
+#define LN_id_qt_cps           "Policy Qualifier CPS"
+#define SN_id_qt_cps           "id-qt-cps"
+#define NID_id_qt_cps          164
+#define OBJ_id_qt_cps          OBJ_id_pkix,2L,1L
+
+#define LN_id_qt_unotice       "Policy Qualifier User Notice"
+#define SN_id_qt_unotice       "id-qt-unotice"
+#define NID_id_qt_unotice      165
+#define OBJ_id_qt_unotice      OBJ_id_pkix,2L,2L
+
+#define SN_rc2_64_cbc                  "RC2-64-CBC"
+#define LN_rc2_64_cbc                  "rc2-64-cbc"
+#define NID_rc2_64_cbc                 166
+
+#define SN_SMIMECapabilities           "SMIME-CAPS"
+#define LN_SMIMECapabilities           "S/MIME Capabilities"
+#define NID_SMIMECapabilities          167
+#define OBJ_SMIMECapabilities          OBJ_pkcs9,15L
+
+#define SN_pbeWithMD2AndRC2_CBC                "PBE-MD2-RC2-64"
+#define LN_pbeWithMD2AndRC2_CBC                "pbeWithMD2AndRC2-CBC"
+#define NID_pbeWithMD2AndRC2_CBC       168
+#define OBJ_pbeWithMD2AndRC2_CBC       OBJ_pkcs,5L,4L
+
+#define SN_pbeWithMD5AndRC2_CBC                "PBE-MD5-RC2-64"
+#define LN_pbeWithMD5AndRC2_CBC                "pbeWithMD5AndRC2-CBC"
+#define NID_pbeWithMD5AndRC2_CBC       169
+#define OBJ_pbeWithMD5AndRC2_CBC       OBJ_pkcs,5L,6L
+
+#define SN_pbeWithSHA1AndDES_CBC       "PBE-SHA1-DES"
+#define LN_pbeWithSHA1AndDES_CBC       "pbeWithSHA1AndDES-CBC"
+#define NID_pbeWithSHA1AndDES_CBC      170
+#define OBJ_pbeWithSHA1AndDES_CBC      OBJ_pkcs,5L,10L
+
+/* Extension request OIDs */
+
+#define LN_ms_ext_req                  "Microsoft Extension Request"
+#define SN_ms_ext_req                  "msExtReq"
+#define NID_ms_ext_req                 171
+#define OBJ_ms_ext_req                 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L
+
+#define LN_ext_req                     "Extension Request"
+#define SN_ext_req                     "extReq"
+#define NID_ext_req                    172
+#define OBJ_ext_req                    OBJ_pkcs9,14L
+
+#define SN_name                                "name"
+#define LN_name                                "name"
+#define NID_name                       173
+#define OBJ_name                       OBJ_X509,41L
+
+#define SN_dnQualifier                 "dnQualifier"
+#define LN_dnQualifier                 "dnQualifier"
+#define NID_dnQualifier                        174
+#define OBJ_dnQualifier                        OBJ_X509,46L
+
+#define SN_id_pe                       "id-pe"
+#define NID_id_pe                      175
+#define OBJ_id_pe                      OBJ_id_pkix,1L
+
+#define SN_id_ad                       "id-ad"
+#define NID_id_ad                      176
+#define OBJ_id_ad                      OBJ_id_pkix,48L
+
+#define SN_info_access                 "authorityInfoAccess"
+#define LN_info_access                 "Authority Information Access"
+#define NID_info_access                        177
+#define OBJ_info_access                        OBJ_id_pe,1L
+
+#define SN_ad_OCSP                     "OCSP"
+#define LN_ad_OCSP                     "OCSP"
+#define NID_ad_OCSP                    178
+#define OBJ_ad_OCSP                    OBJ_id_ad,1L
+
+#define SN_ad_ca_issuers               "caIssuers"
+#define LN_ad_ca_issuers               "CA Issuers"
+#define NID_ad_ca_issuers              179
+#define OBJ_ad_ca_issuers              OBJ_id_ad,2L
+
+#define SN_OCSP_sign                   "OCSPSigning"
+#define LN_OCSP_sign                   "OCSP Signing"
+#define NID_OCSP_sign                  180
+#define OBJ_OCSP_sign                  OBJ_id_kp,9L
+#endif /* USE_OBJ_MAC */
+
+#define        OBJ_NAME_TYPE_UNDEF             0x00
+#define        OBJ_NAME_TYPE_MD_METH           0x01
+#define        OBJ_NAME_TYPE_CIPHER_METH       0x02
+#define        OBJ_NAME_TYPE_PKEY_METH         0x03
+#define        OBJ_NAME_TYPE_COMP_METH         0x04
+#define        OBJ_NAME_TYPE_NUM               0x05
+
+#define        OBJ_NAME_ALIAS          0x8000
+
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct obj_name_st
+       {
+       int type;
+       int alias;
+       const char *name;
+       const char *data;
+       } OBJ_NAME;
+
+#define                OBJ_create_and_add_object(a,b,c) OBJ_create(a,b,c)
+
+
+int OBJ_NAME_init(void);
+int OBJ_NAME_new_index(unsigned long (*hash_func)(const char *),
+                      int (*cmp_func)(const char *, const char *),
+                      void (*free_func)(const char *, int, const char *));
+const char *OBJ_NAME_get(const char *name,int type);
+int OBJ_NAME_add(const char *name,int type,const char *data);
+int OBJ_NAME_remove(const char *name,int type);
+void OBJ_NAME_cleanup(int type); /* -1 for everything */
+void OBJ_NAME_do_all(int type,void (*fn)(const OBJ_NAME *,void *arg),
+                    void *arg);
+void OBJ_NAME_do_all_sorted(int type,void (*fn)(const OBJ_NAME *,void *arg),
+                           void *arg);
+
+ASN1_OBJECT *  OBJ_dup(const ASN1_OBJECT *o);
+ASN1_OBJECT *  OBJ_nid2obj(int n);
+const char *   OBJ_nid2ln(int n);
+const char *   OBJ_nid2sn(int n);
+int            OBJ_obj2nid(const ASN1_OBJECT *o);
+ASN1_OBJECT *  OBJ_txt2obj(const char *s, int no_name);
+int    OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name);
+int            OBJ_txt2nid(const char *s);
+int            OBJ_ln2nid(const char *s);
+int            OBJ_sn2nid(const char *s);
+int            OBJ_cmp(const ASN1_OBJECT *a,const ASN1_OBJECT *b);
+const char *   OBJ_bsearch(const char *key,const char *base,int num,int size,
+       int (*cmp)(const void *, const void *));
+
+int            OBJ_new_nid(int num);
+int            OBJ_add_object(const ASN1_OBJECT *obj);
+int            OBJ_create(const char *oid,const char *sn,const char *ln);
+void           OBJ_cleanup(void );
+#ifndef OPENSSL_NO_BIO
+int            OBJ_create_objects(BIO *in);
+#endif
+
+/* 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.
+ */
+void ERR_load_OBJ_strings(void);
+
+/* Error codes for the OBJ functions. */
+
+/* Function codes. */
+#define OBJ_F_OBJ_CREATE                                100
+#define OBJ_F_OBJ_DUP                                   101
+#define OBJ_F_OBJ_NID2LN                                102
+#define OBJ_F_OBJ_NID2OBJ                               103
+#define OBJ_F_OBJ_NID2SN                                104
+
+/* Reason codes. */
+#define OBJ_R_MALLOC_FAILURE                            100
+#define OBJ_R_UNKNOWN_NID                               101
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/crypto/openssl/rsa/rsa.h b/crypto/openssl/rsa/rsa.h
new file mode 100644 (file)
index 0000000..7789f9e
--- /dev/null
@@ -0,0 +1,272 @@
+/* crypto/rsa/rsa.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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// stripped down to support signature verification only
+// changed includes
+
+#ifndef HEADER_RSA_H
+#define HEADER_RSA_H
+
+#include "crypto/openssl/bn/bn.h"
+
+#ifdef OPENSSL_NO_RSA
+#error RSA is disabled.
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct rsa_st RSA;
+
+typedef struct rsa_meth_st
+       {
+       const char *name;
+       int (*rsa_pub_dec)(int flen,const unsigned char *from,
+                          unsigned char *to,
+                          RSA *rsa,int padding);
+       int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                         const BIGNUM *m, BN_CTX *ctx,
+                         BN_MONT_CTX *m_ctx); /* Can be null */
+       int (*init)(RSA *rsa);          /* called at new */
+       int (*finish)(RSA *rsa);        /* called at free */
+       int flags;                      /* RSA_METHOD_FLAG_* things */
+       char *app_data;                 /* may be needed! */
+       } RSA_METHOD;
+
+struct rsa_st
+       {
+       /* The first parameter is used to pickup errors where
+        * this is passed instead of aEVP_PKEY, it is set to 0 */
+       int pad;
+       long version;
+       const RSA_METHOD *meth;
+       /* functional reference if 'meth' is ENGINE-provided */
+       BIGNUM *n;
+       BIGNUM *e;
+       BIGNUM *d;
+       BIGNUM *p;
+       BIGNUM *q;
+       BIGNUM *dmp1;
+       BIGNUM *dmq1;
+       BIGNUM *iqmp;
+
+       int flags;
+
+       /* Used to cache montgomery values */
+       BN_MONT_CTX *_method_mod_n;
+       BN_MONT_CTX *_method_mod_p;
+       BN_MONT_CTX *_method_mod_q;
+       };
+
+#define RSA_3  0x3L
+#define RSA_F4 0x10001L
+
+#define RSA_METHOD_FLAG_NO_CHECK       0x01 /* don't check pub/private match */
+
+#define RSA_FLAG_CACHE_PUBLIC          0x02
+#define RSA_FLAG_CACHE_PRIVATE         0x04
+#define RSA_FLAG_BLINDING              0x08
+#define RSA_FLAG_THREAD_SAFE           0x10
+/* This flag means the private key operations will be handled by rsa_mod_exp
+ * and that they do not depend on the private key components being present:
+ * for example a key stored in external hardware. Without this flag bn_mod_exp
+ * gets called when private key components are absent.
+ */
+#define RSA_FLAG_EXT_PKEY              0x20
+
+/* This flag in the RSA_METHOD enables the new rsa_sign, rsa_verify functions.
+ */
+#define RSA_FLAG_SIGN_VER              0x40
+
+#define RSA_FLAG_NO_BLINDING           0x80 /* new with 0.9.6j and 0.9.7b; the built-in
+                                              * RSA implementation now uses blinding by
+                                              * default (ignoring RSA_FLAG_BLINDING),
+                                              * but other engines might not need it
+                                              */
+
+#define RSA_PKCS1_PADDING      1
+#define RSA_SSLV23_PADDING     2
+#define RSA_NO_PADDING         3
+#define RSA_PKCS1_OAEP_PADDING 4
+
+#define RSA_PKCS1_PADDING_SIZE 11
+
+#define RSA_set_app_data(s,arg)         RSA_set_ex_data(s,0,arg)
+#define RSA_get_app_data(s)             RSA_get_ex_data(s,0)
+
+RSA *  RSA_new(void) RSA_SEGMENT;
+int    RSA_size(const RSA *) RSA_SEGMENT;
+RSA *  RSA_generate_key(int bits, unsigned long e,void
+               (*callback)(int,int,void *),void *cb_arg) RSA_SEGMENT;
+int    RSA_check_key(const RSA *) RSA_SEGMENT;
+       /* next 1 returns -1 on error */
+int    RSA_public_decrypt(int flen, const unsigned char *from, 
+               unsigned char *to, RSA *rsa,int padding) RSA_SEGMENT;
+void   RSA_free (RSA *r) RSA_SEGMENT;
+int    RSA_flags(const RSA *r) RSA_SEGMENT;
+
+/* these are the actual SSLeay RSA functions */
+const RSA_METHOD *RSA_PKCS1_SSLeay(void) RSA_SEGMENT;
+
+const RSA_METHOD *RSA_null_method(void) RSA_SEGMENT;
+
+int RSA_padding_check_PKCS1_type_1(unsigned char *to,int tlen,
+       const unsigned char *f,int fl,int rsa_len) RSA_SEGMENT;
+int RSA_padding_add_none(unsigned char *to,int tlen,
+       const unsigned char *f,int fl) RSA_SEGMENT;
+int RSA_padding_check_none(unsigned char *to,int tlen,
+       const unsigned char *f,int fl,int rsa_len) RSA_SEGMENT;
+
+/* 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.
+ */
+void ERR_load_RSA_strings(void);
+
+/* Error codes for the RSA functions. */
+
+/* Function codes. */
+#define RSA_F_MEMORY_LOCK                               100
+#define RSA_F_RSA_CHECK_KEY                             123
+#define RSA_F_RSA_EAY_PRIVATE_DECRYPT                   101
+#define RSA_F_RSA_EAY_PRIVATE_ENCRYPT                   102
+#define RSA_F_RSA_EAY_PUBLIC_DECRYPT                    103
+#define RSA_F_RSA_EAY_PUBLIC_ENCRYPT                    104
+#define RSA_F_RSA_GENERATE_KEY                          105
+#define RSA_F_RSA_NEW_METHOD                            106
+#define RSA_F_RSA_NULL                                  124
+#define RSA_F_RSA_PADDING_ADD_NONE                      107
+#define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP                121
+#define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1              108
+#define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2              109
+#define RSA_F_RSA_PADDING_ADD_SSLV23                    110
+#define RSA_F_RSA_PADDING_CHECK_NONE                    111
+#define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP              122
+#define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1            112
+#define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2            113
+#define RSA_F_RSA_PADDING_CHECK_SSLV23                  114
+#define RSA_F_RSA_PRINT                                         115
+#define RSA_F_RSA_PRINT_FP                              116
+#define RSA_F_RSA_SIGN                                  117
+#define RSA_F_RSA_SIGN_ASN1_OCTET_STRING                118
+#define RSA_F_RSA_VERIFY                                119
+#define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING              120
+
+/* Reason codes. */
+#define RSA_R_ALGORITHM_MISMATCH                        100
+#define RSA_R_BAD_E_VALUE                               101
+#define RSA_R_BAD_FIXED_HEADER_DECRYPT                  102
+#define RSA_R_BAD_PAD_BYTE_COUNT                        103
+#define RSA_R_BAD_SIGNATURE                             104
+#define RSA_R_BLOCK_TYPE_IS_NOT_01                      106
+#define RSA_R_BLOCK_TYPE_IS_NOT_02                      107
+#define RSA_R_DATA_GREATER_THAN_MOD_LEN                         108
+#define RSA_R_DATA_TOO_LARGE                            109
+#define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE               110
+#define RSA_R_DATA_TOO_LARGE_FOR_MODULUS                132
+#define RSA_R_DATA_TOO_SMALL                            111
+#define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE               122
+#define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY                112
+#define RSA_R_DMP1_NOT_CONGRUENT_TO_D                   124
+#define RSA_R_DMQ1_NOT_CONGRUENT_TO_D                   125
+#define RSA_R_D_E_NOT_CONGRUENT_TO_1                    123
+#define RSA_R_INVALID_MESSAGE_LENGTH                    131
+#define RSA_R_IQMP_NOT_INVERSE_OF_Q                     126
+#define RSA_R_KEY_SIZE_TOO_SMALL                        120
+#define RSA_R_NULL_BEFORE_BLOCK_MISSING                         113
+#define RSA_R_N_DOES_NOT_EQUAL_P_Q                      127
+#define RSA_R_OAEP_DECODING_ERROR                       121
+#define RSA_R_PADDING_CHECK_FAILED                      114
+#define RSA_R_P_NOT_PRIME                               128
+#define RSA_R_Q_NOT_PRIME                               129
+#define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED              130
+#define RSA_R_SSLV3_ROLLBACK_ATTACK                     115
+#define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116
+#define RSA_R_UNKNOWN_ALGORITHM_TYPE                    117
+#define RSA_R_UNKNOWN_PADDING_TYPE                      118
+#define RSA_R_WRONG_SIGNATURE_LENGTH                    119
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/crypto/openssl/rsa/rsa_eay.c b/crypto/openssl/rsa/rsa_eay.c
new file mode 100644 (file)
index 0000000..e19f48e
--- /dev/null
@@ -0,0 +1,224 @@
+/* crypto/rsa/rsa_eay.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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// stripped down to support signature verification only
+// changed includes
+
+#include "cryptlib.h"
+#include "bn/bn.h"
+#include "rsa.h"
+#include "rand.h"
+
+#ifndef RSA_NULL
+
+static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
+               unsigned char *to, RSA *rsa,int padding) RSA_SEGMENT;
+static int RSA_eay_init(RSA *rsa) RSA_SEGMENT;
+static int RSA_eay_finish(RSA *rsa) RSA_SEGMENT;
+static RSA_METHOD rsa_pkcs1_eay_meth={
+       "Eric Young's PKCS#1 RSA",
+       RSA_eay_public_decrypt, /* signature verification */
+       BN_mod_exp_mont, /* XXX probably we should not use Montgomery if  e == 3 */
+       RSA_eay_init,
+       RSA_eay_finish,
+       0, /* flags */
+       NULL,
+       };
+
+const RSA_METHOD *RSA_PKCS1_SSLeay(void)
+       {
+       return(&rsa_pkcs1_eay_meth);
+       }
+
+/* signature verification */
+static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
+            unsigned char *to, RSA *rsa, int padding)
+       {
+       BIGNUM *f,*ret;
+       int i,num=0,r= -1;
+       unsigned char *p;
+       unsigned char *buf=NULL;
+       BN_CTX *ctx=NULL;
+
+       f = BN_new();
+        ret = BN_new();
+       ctx=BN_CTX_new();
+       if (ctx == NULL) goto err;
+
+       num=BN_num_bytes(rsa->n);
+       buf=(unsigned char *)OPENSSL_malloc(num);
+       if (buf == NULL)
+               {
+               RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,ERR_R_MALLOC_FAILURE);
+               goto err;
+               }
+
+       /* This check was for equality but PGP does evil things
+        * and chops off the top '0' bytes */
+       if (flen > num)
+               {
+               RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
+               goto err;
+               }
+
+       if (BN_bin2bn(from,flen,f) == NULL) goto err;
+
+       if (BN_ucmp(f, rsa->n) >= 0)
+               {
+               RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+               goto err;
+               }
+
+       /* do the decrypt */
+       if ((rsa->_method_mod_n == NULL) && (rsa->flags & RSA_FLAG_CACHE_PUBLIC))
+               {
+               BN_MONT_CTX* bn_mont_ctx;
+               if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
+                       goto err;
+               if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->n,ctx))
+                       {
+                       BN_MONT_CTX_free(bn_mont_ctx);
+                       goto err;
+                       }
+               if (rsa->_method_mod_n == NULL) /* other thread may have finished first */
+                       {
+                       if (rsa->_method_mod_n == NULL)
+                               {
+                               rsa->_method_mod_n = bn_mont_ctx;
+                               bn_mont_ctx = NULL;
+                               }
+                       }
+               if (bn_mont_ctx)
+                       BN_MONT_CTX_free(bn_mont_ctx);
+               }
+               
+       if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx,
+               rsa->_method_mod_n)) goto err;
+
+       p=buf;
+       i=BN_bn2bin(ret,p);
+
+       switch (padding)
+               {
+       case RSA_PKCS1_PADDING:
+               r=RSA_padding_check_PKCS1_type_1(to,num,buf,i,num);
+               break;
+       case RSA_NO_PADDING:
+               r=RSA_padding_check_none(to,num,buf,i,num);
+               break;
+       default:
+               RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
+               goto err;
+               }
+       if (r < 0)
+               RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_PADDING_CHECK_FAILED);
+
+err:
+       if (ctx != NULL) BN_CTX_free(ctx);
+       BN_clear_free(f);
+       BN_clear_free(ret);
+       if (buf != NULL)
+               {
+               OPENSSL_cleanse(buf,num);
+               OPENSSL_free(buf);
+               }
+       return(r);
+       }
+
+static int RSA_eay_init(RSA *rsa)
+       {
+       rsa->flags|=RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE;
+       return(1);
+       }
+
+static int RSA_eay_finish(RSA *rsa)
+       {
+       if (rsa->_method_mod_n != NULL)
+               BN_MONT_CTX_free(rsa->_method_mod_n);
+       if (rsa->_method_mod_p != NULL)
+               BN_MONT_CTX_free(rsa->_method_mod_p);
+       if (rsa->_method_mod_q != NULL)
+               BN_MONT_CTX_free(rsa->_method_mod_q);
+       return(1);
+       }
+
+#endif
diff --git a/crypto/openssl/rsa/rsa_lib.c b/crypto/openssl/rsa/rsa_lib.c
new file mode 100644 (file)
index 0000000..3f1c6c1
--- /dev/null
@@ -0,0 +1,163 @@
+/* crypto/rsa/rsa_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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// stripped down to support signature verification only
+// changed includes
+
+#include "cryptlib.h"
+#include "bn/bn.h"
+#include "rsa/rsa.h"
+#include "rand.h"
+
+const char *RSA_version="RSA" OPENSSL_VERSION_PTEXT;
+
+RSA *RSA_new(void)
+       {
+       RSA *ret;
+
+       ret=(RSA *)OPENSSL_malloc(sizeof(RSA));
+       if (ret == NULL)
+               {
+               RSAerr(RSA_F_RSA_NEW_METHOD,ERR_R_MALLOC_FAILURE);
+               return NULL;
+               }
+
+       ret->meth = RSA_PKCS1_SSLeay();
+
+       ret->pad=0;
+       ret->version=0;
+       ret->n=NULL;
+       ret->e=NULL;
+       ret->d=NULL;
+       ret->p=NULL;
+       ret->q=NULL;
+       ret->dmp1=NULL;
+       ret->dmq1=NULL;
+       ret->iqmp=NULL;
+       ret->_method_mod_n=NULL;
+       ret->_method_mod_p=NULL;
+       ret->_method_mod_q=NULL;
+       ret->flags=ret->meth->flags;
+
+       if ((ret->meth->init != NULL) && !ret->meth->init(ret))
+               {
+               OPENSSL_free(ret);
+               ret=NULL;
+               }
+       return(ret);
+       }
+
+void RSA_free(RSA *r)
+       {
+       int i;
+
+       if (r == NULL) return;
+
+       if (r->meth->finish)
+               r->meth->finish(r);
+
+       if (r->n != NULL) BN_clear_free(r->n);
+       if (r->e != NULL) BN_clear_free(r->e);
+       if (r->d != NULL) BN_clear_free(r->d);
+       if (r->p != NULL) BN_clear_free(r->p);
+       if (r->q != NULL) BN_clear_free(r->q);
+       if (r->dmp1 != NULL) BN_clear_free(r->dmp1);
+       if (r->dmq1 != NULL) BN_clear_free(r->dmq1);
+       if (r->iqmp != NULL) BN_clear_free(r->iqmp);
+       OPENSSL_free(r);
+       }
+
+int RSA_size(const RSA *r)
+       {
+       return(BN_num_bytes(r->n));
+       }
+
+int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to,
+            RSA *rsa, int padding)
+       {
+       return(rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding));
+       }
+
+int RSA_flags(const RSA *r)
+       {
+       return((r == NULL)?0:r->meth->flags);
+       }
diff --git a/crypto/openssl/rsa/rsa_none.c b/crypto/openssl/rsa/rsa_none.c
new file mode 100644 (file)
index 0000000..a9e9e1e
--- /dev/null
@@ -0,0 +1,123 @@
+/* crypto/rsa/rsa_none.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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+
+#include "cryptlib.h"
+#include "bn/bn.h"
+#include "rsa/rsa.h"
+#include "rand.h"
+
+int RSA_padding_add_none(unsigned char *to, int tlen,
+       const unsigned char *from, int flen)
+       {
+       if (flen > tlen)
+               {
+               RSAerr(RSA_F_RSA_PADDING_ADD_NONE,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+               return(0);
+               }
+
+       if (flen < tlen)
+               {
+               RSAerr(RSA_F_RSA_PADDING_ADD_NONE,RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE);
+               return(0);
+               }
+       
+       memcpy(to,from,(unsigned int)flen);
+       return(1);
+       }
+
+int RSA_padding_check_none(unsigned char *to, int tlen,
+       const unsigned char *from, int flen, int num)
+       {
+
+       if (flen > tlen)
+               {
+               RSAerr(RSA_F_RSA_PADDING_CHECK_NONE,RSA_R_DATA_TOO_LARGE);
+               return(-1);
+               }
+
+       memset(to,0,tlen-flen);
+       memcpy(to+tlen-flen,from,flen);
+       return(tlen);
+       }
+
diff --git a/crypto/openssl/rsa/rsa_pk1.c b/crypto/openssl/rsa/rsa_pk1.c
new file mode 100644 (file)
index 0000000..8b20f53
--- /dev/null
@@ -0,0 +1,180 @@
+/* crypto/rsa/rsa_pk1.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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// stripped down to support PKCS1 verification only
+// changed includes
+
+#include "cryptlib.h"
+#include "bn/bn.h"
+#include "rsa/rsa.h"
+#include "rand.h"
+
+int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen,
+            const unsigned char *from, int flen, int num)
+       {
+       int i,j;
+       const unsigned char *p;
+
+       p=from;
+       if ((num != (flen+1)) || (*(p++) != 01))
+               {
+               RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_BLOCK_TYPE_IS_NOT_01);
+               return(-1);
+               }
+
+       /* scan over padding data */
+       j=flen-1; /* one for type. */
+       for (i=0; i<j; i++)
+               {
+               if (*p != 0xff) /* should decrypt to 0xff */
+                       {
+                       if (*p == 0)
+                               { p++; break; }
+                       else    {
+                               RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_BAD_FIXED_HEADER_DECRYPT);
+                               return(-1);
+                               }
+                       }
+               p++;
+               }
+
+       if (i == j)
+               {
+               RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_NULL_BEFORE_BLOCK_MISSING);
+               return(-1);
+               }
+
+       if (i < 8)
+               {
+               RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_BAD_PAD_BYTE_COUNT);
+               return(-1);
+               }
+       i++; /* Skip over the '\0' */
+       j-=i;
+       if (j > tlen)
+               {
+               RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_DATA_TOO_LARGE);
+               return(-1);
+               }
+       memcpy(to,p,(unsigned int)j);
+
+       return(j);
+       }
+
+int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen,
+            const unsigned char *from, int flen)
+       {
+       int i,j;
+       unsigned char *p;
+       
+       if (flen > (tlen-11))
+               {
+               RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+               return(0);
+               }
+       
+       p=(unsigned char *)to;
+
+       *(p++)=0;
+       *(p++)=2; /* Public Key BT (Block Type) */
+
+       /* pad out with non-zero random data */
+       j=tlen-3-flen;
+
+       if (RAND_bytes(p,j) <= 0)
+               return(0);
+       for (i=0; i<j; i++)
+               {
+               if (*p == '\0')
+                       do      {
+                               if (RAND_bytes(p,1) <= 0)
+                                       return(0);
+                               } while (*p == '\0');
+               p++;
+               }
+
+       *(p++)='\0';
+
+       memcpy(p,from,(unsigned int)flen);
+       return(1);
+       }
+
diff --git a/crypto/openssl/sha/sha.h b/crypto/openssl/sha/sha.h
new file mode 100644 (file)
index 0000000..f3e1285
--- /dev/null
@@ -0,0 +1,149 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// explicitly define SHA_LONG as uint32_t
+// added SHA_SEGMENT everywhere
+
+#ifndef HEADER_SHA_H
+#define HEADER_SHA_H
+
+#include "openssl/cryptlib.h"
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#if defined(OPENSSL_NO_SHA) || (defined(OPENSSL_NO_SHA0) && defined(OPENSSL_NO_SHA1))
+#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(OPENSSL_SYS_WIN16) || defined(__LP32__)
+#define SHA_LONG unsigned long
+#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
+#define SHA_LONG unsigned long
+#define SHA_LONG_LOG2 3
+#else
+#define SHA_LONG uint32_t
+#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 OPENSSL_NO_SHA0
+int SHA_Init(SHA_CTX *c);
+int SHA_Update(SHA_CTX *c, const void *data, unsigned long len);
+int 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, const unsigned char *data);
+#endif
+#ifndef OPENSSL_NO_SHA1
+int SHA1_Init(SHA_CTX *c) SHA_SEGMENT;
+int SHA1_Update(SHA_CTX *c, const void *data, unsigned long len) SHA_SEGMENT;
+int SHA1_Final(unsigned char *md, SHA_CTX *c) SHA_SEGMENT;
+unsigned char *SHA1(const unsigned char *d, unsigned long n,unsigned char *md) SHA_SEGMENT;
+void SHA1_Transform(SHA_CTX *c, const unsigned char *data) SHA_SEGMENT;
+#endif
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/crypto/openssl/sha/sha1dgst.c b/crypto/openssl/sha/sha1dgst.c
new file mode 100644 (file)
index 0000000..031f4e5
--- /dev/null
@@ -0,0 +1,99 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+
+#if !defined(OPENSSL_NO_SHA1) && !defined(OPENSSL_NO_SHA)
+
+#undef  SHA_0
+#define SHA_1
+
+#include "cryptlib.h"
+
+const char *SHA1_version="SHA1" OPENSSL_VERSION_PTEXT;
+
+/* The implementation is in ../md32_common.h */
+
+#include "sha_locl.h"
+
+#endif
+
diff --git a/crypto/openssl/sha/sha_locl.h b/crypto/openssl/sha/sha_locl.h
new file mode 100644 (file)
index 0000000..d4c0225
--- /dev/null
@@ -0,0 +1,495 @@
+/* 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.]
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// added SHA_SEGMENT everywhere
+
+#include "sha.h"
+
+#ifndef SHA_LONG_LOG2
+#define SHA_LONG_LOG2  2       /* default to 32 bits */
+#endif
+
+#define DATA_ORDER_IS_BIG_ENDIAN
+
+#define HASH_LONG               SHA_LONG
+#define HASH_LONG_LOG2          SHA_LONG_LOG2
+#define HASH_CTX                SHA_CTX
+#define HASH_CBLOCK             SHA_CBLOCK
+#define HASH_LBLOCK             SHA_LBLOCK
+#define HASH_MAKE_STRING(c,s)   do {   \
+       unsigned long ll;               \
+       ll=(c)->h0; HOST_l2c(ll,(s));   \
+       ll=(c)->h1; HOST_l2c(ll,(s));   \
+       ll=(c)->h2; HOST_l2c(ll,(s));   \
+       ll=(c)->h3; HOST_l2c(ll,(s));   \
+       ll=(c)->h4; HOST_l2c(ll,(s));   \
+       } while (0)
+
+#if defined(SHA_0)
+
+# define HASH_UPDATE                   SHA_Update
+# define HASH_TRANSFORM                SHA_Transform
+# define HASH_FINAL                    SHA_Final
+# define HASH_INIT                     SHA_Init
+# define HASH_BLOCK_HOST_ORDER         sha_block_host_order
+# define HASH_BLOCK_DATA_ORDER         sha_block_data_order
+# define Xupdate(a,ix,ia,ib,ic,id)     (ix=(a)=(ia^ib^ic^id))
+
+  void sha_block_host_order (SHA_CTX *c, const void *p,int num) SHA_SEGMENT;
+  void sha_block_data_order (SHA_CTX *c, const void *p,int num) SHA_SEGMENT;
+
+#elif defined(SHA_1)
+
+# define HASH_UPDATE                   SHA1_Update
+# define HASH_TRANSFORM                SHA1_Transform
+# define HASH_FINAL                    SHA1_Final
+# define HASH_INIT                     SHA1_Init
+# define HASH_BLOCK_HOST_ORDER         sha1_block_host_order
+# define HASH_BLOCK_DATA_ORDER         sha1_block_data_order
+# if defined(__MWERKS__) && defined(__MC68K__)
+   /* Metrowerks for Motorola fails otherwise:-( <appro@fy.chalmers.se> */
+#  define Xupdate(a,ix,ia,ib,ic,id)    do { (a)=(ia^ib^ic^id);         \
+                                            ix=(a)=ROTATE((a),1);      \
+                                       } while (0)
+# else
+#  define Xupdate(a,ix,ia,ib,ic,id)    ( (a)=(ia^ib^ic^id),    \
+                                         ix=(a)=ROTATE((a),1)  \
+                                       )
+# endif
+
+# ifdef SHA1_ASM
+#  if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__)
+#   define sha1_block_host_order               sha1_block_asm_host_order
+#   define DONT_IMPLEMENT_BLOCK_HOST_ORDER
+#   define sha1_block_data_order               sha1_block_asm_data_order
+#   define DONT_IMPLEMENT_BLOCK_DATA_ORDER
+#   define HASH_BLOCK_DATA_ORDER_ALIGNED       sha1_block_asm_data_order
+#  endif
+# endif
+  void sha1_block_host_order (SHA_CTX *c, const void *p,int num) SHA_SEGMENT;
+  void sha1_block_data_order (SHA_CTX *c, const void *p,int num) SHA_SEGMENT;
+
+#else
+# error "Either SHA_0 or SHA_1 must be defined."
+#endif
+
+#include "md32_common.h"
+
+#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
+
+int HASH_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;
+       return 1;
+       }
+
+#define K_00_19        0x5a827999UL
+#define K_20_39 0x6ed9eba1UL
+#define K_40_59 0x8f1bbcdcUL
+#define K_60_79 0xca62c1d6UL
+
+/* 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)
+
+#define BODY_00_15(i,a,b,c,d,e,f,xi) \
+       (f)=xi+(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,xi,xa,xb,xc,xd) \
+       Xupdate(f,xi,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,xi,xa,xb,xc,xd) \
+       Xupdate(f,xi,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,xb,xc,xd) \
+       Xupdate(f,xa,xa,xb,xc,xd); \
+       (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,xb,xc,xd) \
+       Xupdate(f,xa,xa,xb,xc,xd); \
+       (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,xb,xc,xd) \
+       Xupdate(f,xa,xa,xb,xc,xd); \
+       (f)=xa+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \
+       (b)=ROTATE((b),30);
+
+#ifdef X
+#undef X
+#endif
+#ifndef MD32_XARRAY
+  /*
+   * Originally X was an array. As it's automatic it's natural
+   * to expect RISC compiler to accomodate at least part of it in
+   * the register bank, isn't it? Unfortunately not all compilers
+   * "find" this expectation reasonable:-( On order to make such
+   * compilers generate better code I replace X[] with a bunch of
+   * X0, X1, etc. See the function body below...
+   *                                   <appro@fy.chalmers.se>
+   */
+# define X(i)  XX##i
+#else
+  /*
+   * However! Some compilers (most notably HP C) get overwhelmed by
+   * that many local variables so that we have to have the way to
+   * fall down to the original behavior.
+   */
+# define X(i)  XX[i]
+#endif
+
+#ifndef DONT_IMPLEMENT_BLOCK_HOST_ORDER
+void HASH_BLOCK_HOST_ORDER (SHA_CTX *c, const void *d, int num)
+       {
+       const SHA_LONG *W=d;
+       register unsigned MD32_REG_T A,B,C,D,E,T;
+#ifndef MD32_XARRAY
+       unsigned MD32_REG_T     XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
+                               XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
+#else
+       SHA_LONG        XX[16];
+#endif
+
+       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[ 0]);
+       BODY_00_15( 1,T,A,B,C,D,E,W[ 1]);
+       BODY_00_15( 2,E,T,A,B,C,D,W[ 2]);
+       BODY_00_15( 3,D,E,T,A,B,C,W[ 3]);
+       BODY_00_15( 4,C,D,E,T,A,B,W[ 4]);
+       BODY_00_15( 5,B,C,D,E,T,A,W[ 5]);
+       BODY_00_15( 6,A,B,C,D,E,T,W[ 6]);
+       BODY_00_15( 7,T,A,B,C,D,E,W[ 7]);
+       BODY_00_15( 8,E,T,A,B,C,D,W[ 8]);
+       BODY_00_15( 9,D,E,T,A,B,C,W[ 9]);
+       BODY_00_15(10,C,D,E,T,A,B,W[10]);
+       BODY_00_15(11,B,C,D,E,T,A,W[11]);
+       BODY_00_15(12,A,B,C,D,E,T,W[12]);
+       BODY_00_15(13,T,A,B,C,D,E,W[13]);
+       BODY_00_15(14,E,T,A,B,C,D,W[14]);
+       BODY_00_15(15,D,E,T,A,B,C,W[15]);
+
+       BODY_16_19(16,C,D,E,T,A,B,X( 0),W[ 0],W[ 2],W[ 8],W[13]);
+       BODY_16_19(17,B,C,D,E,T,A,X( 1),W[ 1],W[ 3],W[ 9],W[14]);
+       BODY_16_19(18,A,B,C,D,E,T,X( 2),W[ 2],W[ 4],W[10],W[15]);
+       BODY_16_19(19,T,A,B,C,D,E,X( 3),W[ 3],W[ 5],W[11],X( 0));
+
+       BODY_20_31(20,E,T,A,B,C,D,X( 4),W[ 4],W[ 6],W[12],X( 1));
+       BODY_20_31(21,D,E,T,A,B,C,X( 5),W[ 5],W[ 7],W[13],X( 2));
+       BODY_20_31(22,C,D,E,T,A,B,X( 6),W[ 6],W[ 8],W[14],X( 3));
+       BODY_20_31(23,B,C,D,E,T,A,X( 7),W[ 7],W[ 9],W[15],X( 4));
+       BODY_20_31(24,A,B,C,D,E,T,X( 8),W[ 8],W[10],X( 0),X( 5));
+       BODY_20_31(25,T,A,B,C,D,E,X( 9),W[ 9],W[11],X( 1),X( 6));
+       BODY_20_31(26,E,T,A,B,C,D,X(10),W[10],W[12],X( 2),X( 7));
+       BODY_20_31(27,D,E,T,A,B,C,X(11),W[11],W[13],X( 3),X( 8));
+       BODY_20_31(28,C,D,E,T,A,B,X(12),W[12],W[14],X( 4),X( 9));
+       BODY_20_31(29,B,C,D,E,T,A,X(13),W[13],W[15],X( 5),X(10));
+       BODY_20_31(30,A,B,C,D,E,T,X(14),W[14],X( 0),X( 6),X(11));
+       BODY_20_31(31,T,A,B,C,D,E,X(15),W[15],X( 1),X( 7),X(12));
+
+       BODY_32_39(32,E,T,A,B,C,D,X( 0),X( 2),X( 8),X(13));
+       BODY_32_39(33,D,E,T,A,B,C,X( 1),X( 3),X( 9),X(14));
+       BODY_32_39(34,C,D,E,T,A,B,X( 2),X( 4),X(10),X(15));
+       BODY_32_39(35,B,C,D,E,T,A,X( 3),X( 5),X(11),X( 0));
+       BODY_32_39(36,A,B,C,D,E,T,X( 4),X( 6),X(12),X( 1));
+       BODY_32_39(37,T,A,B,C,D,E,X( 5),X( 7),X(13),X( 2));
+       BODY_32_39(38,E,T,A,B,C,D,X( 6),X( 8),X(14),X( 3));
+       BODY_32_39(39,D,E,T,A,B,C,X( 7),X( 9),X(15),X( 4));
+
+       BODY_40_59(40,C,D,E,T,A,B,X( 8),X(10),X( 0),X( 5));
+       BODY_40_59(41,B,C,D,E,T,A,X( 9),X(11),X( 1),X( 6));
+       BODY_40_59(42,A,B,C,D,E,T,X(10),X(12),X( 2),X( 7));
+       BODY_40_59(43,T,A,B,C,D,E,X(11),X(13),X( 3),X( 8));
+       BODY_40_59(44,E,T,A,B,C,D,X(12),X(14),X( 4),X( 9));
+       BODY_40_59(45,D,E,T,A,B,C,X(13),X(15),X( 5),X(10));
+       BODY_40_59(46,C,D,E,T,A,B,X(14),X( 0),X( 6),X(11));
+       BODY_40_59(47,B,C,D,E,T,A,X(15),X( 1),X( 7),X(12));
+       BODY_40_59(48,A,B,C,D,E,T,X( 0),X( 2),X( 8),X(13));
+       BODY_40_59(49,T,A,B,C,D,E,X( 1),X( 3),X( 9),X(14));
+       BODY_40_59(50,E,T,A,B,C,D,X( 2),X( 4),X(10),X(15));
+       BODY_40_59(51,D,E,T,A,B,C,X( 3),X( 5),X(11),X( 0));
+       BODY_40_59(52,C,D,E,T,A,B,X( 4),X( 6),X(12),X( 1));
+       BODY_40_59(53,B,C,D,E,T,A,X( 5),X( 7),X(13),X( 2));
+       BODY_40_59(54,A,B,C,D,E,T,X( 6),X( 8),X(14),X( 3));
+       BODY_40_59(55,T,A,B,C,D,E,X( 7),X( 9),X(15),X( 4));
+       BODY_40_59(56,E,T,A,B,C,D,X( 8),X(10),X( 0),X( 5));
+       BODY_40_59(57,D,E,T,A,B,C,X( 9),X(11),X( 1),X( 6));
+       BODY_40_59(58,C,D,E,T,A,B,X(10),X(12),X( 2),X( 7));
+       BODY_40_59(59,B,C,D,E,T,A,X(11),X(13),X( 3),X( 8));
+
+       BODY_60_79(60,A,B,C,D,E,T,X(12),X(14),X( 4),X( 9));
+       BODY_60_79(61,T,A,B,C,D,E,X(13),X(15),X( 5),X(10));
+       BODY_60_79(62,E,T,A,B,C,D,X(14),X( 0),X( 6),X(11));
+       BODY_60_79(63,D,E,T,A,B,C,X(15),X( 1),X( 7),X(12));
+       BODY_60_79(64,C,D,E,T,A,B,X( 0),X( 2),X( 8),X(13));
+       BODY_60_79(65,B,C,D,E,T,A,X( 1),X( 3),X( 9),X(14));
+       BODY_60_79(66,A,B,C,D,E,T,X( 2),X( 4),X(10),X(15));
+       BODY_60_79(67,T,A,B,C,D,E,X( 3),X( 5),X(11),X( 0));
+       BODY_60_79(68,E,T,A,B,C,D,X( 4),X( 6),X(12),X( 1));
+       BODY_60_79(69,D,E,T,A,B,C,X( 5),X( 7),X(13),X( 2));
+       BODY_60_79(70,C,D,E,T,A,B,X( 6),X( 8),X(14),X( 3));
+       BODY_60_79(71,B,C,D,E,T,A,X( 7),X( 9),X(15),X( 4));
+       BODY_60_79(72,A,B,C,D,E,T,X( 8),X(10),X( 0),X( 5));
+       BODY_60_79(73,T,A,B,C,D,E,X( 9),X(11),X( 1),X( 6));
+       BODY_60_79(74,E,T,A,B,C,D,X(10),X(12),X( 2),X( 7));
+       BODY_60_79(75,D,E,T,A,B,C,X(11),X(13),X( 3),X( 8));
+       BODY_60_79(76,C,D,E,T,A,B,X(12),X(14),X( 4),X( 9));
+       BODY_60_79(77,B,C,D,E,T,A,X(13),X(15),X( 5),X(10));
+       BODY_60_79(78,A,B,C,D,E,T,X(14),X( 0),X( 6),X(11));
+       BODY_60_79(79,T,A,B,C,D,E,X(15),X( 1),X( 7),X(12));
+       
+       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;
+               }
+       }
+#endif
+
+#ifndef DONT_IMPLEMENT_BLOCK_DATA_ORDER
+void HASH_BLOCK_DATA_ORDER (SHA_CTX *c, const void *p, int num)
+       {
+       const unsigned char *data=p;
+       register unsigned MD32_REG_T A,B,C,D,E,T,l;
+#ifndef MD32_XARRAY
+       unsigned MD32_REG_T     XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
+                               XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
+#else
+       SHA_LONG        XX[16];
+#endif
+
+       A=c->h0;
+       B=c->h1;
+       C=c->h2;
+       D=c->h3;
+       E=c->h4;
+
+       for (;;)
+               {
+
+       HOST_c2l(data,l); X( 0)=l;              HOST_c2l(data,l); X( 1)=l;
+       BODY_00_15( 0,A,B,C,D,E,T,X( 0));       HOST_c2l(data,l); X( 2)=l;
+       BODY_00_15( 1,T,A,B,C,D,E,X( 1));       HOST_c2l(data,l); X( 3)=l;
+       BODY_00_15( 2,E,T,A,B,C,D,X( 2));       HOST_c2l(data,l); X( 4)=l;
+       BODY_00_15( 3,D,E,T,A,B,C,X( 3));       HOST_c2l(data,l); X( 5)=l;
+       BODY_00_15( 4,C,D,E,T,A,B,X( 4));       HOST_c2l(data,l); X( 6)=l;
+       BODY_00_15( 5,B,C,D,E,T,A,X( 5));       HOST_c2l(data,l); X( 7)=l;
+       BODY_00_15( 6,A,B,C,D,E,T,X( 6));       HOST_c2l(data,l); X( 8)=l;
+       BODY_00_15( 7,T,A,B,C,D,E,X( 7));       HOST_c2l(data,l); X( 9)=l;
+       BODY_00_15( 8,E,T,A,B,C,D,X( 8));       HOST_c2l(data,l); X(10)=l;
+       BODY_00_15( 9,D,E,T,A,B,C,X( 9));       HOST_c2l(data,l); X(11)=l;
+       BODY_00_15(10,C,D,E,T,A,B,X(10));       HOST_c2l(data,l); X(12)=l;
+       BODY_00_15(11,B,C,D,E,T,A,X(11));       HOST_c2l(data,l); X(13)=l;
+       BODY_00_15(12,A,B,C,D,E,T,X(12));       HOST_c2l(data,l); X(14)=l;
+       BODY_00_15(13,T,A,B,C,D,E,X(13));       HOST_c2l(data,l); X(15)=l;
+       BODY_00_15(14,E,T,A,B,C,D,X(14));
+       BODY_00_15(15,D,E,T,A,B,C,X(15));
+
+       BODY_16_19(16,C,D,E,T,A,B,X( 0),X( 0),X( 2),X( 8),X(13));
+       BODY_16_19(17,B,C,D,E,T,A,X( 1),X( 1),X( 3),X( 9),X(14));
+       BODY_16_19(18,A,B,C,D,E,T,X( 2),X( 2),X( 4),X(10),X(15));
+       BODY_16_19(19,T,A,B,C,D,E,X( 3),X( 3),X( 5),X(11),X( 0));
+
+       BODY_20_31(20,E,T,A,B,C,D,X( 4),X( 4),X( 6),X(12),X( 1));
+       BODY_20_31(21,D,E,T,A,B,C,X( 5),X( 5),X( 7),X(13),X( 2));
+       BODY_20_31(22,C,D,E,T,A,B,X( 6),X( 6),X( 8),X(14),X( 3));
+       BODY_20_31(23,B,C,D,E,T,A,X( 7),X( 7),X( 9),X(15),X( 4));
+       BODY_20_31(24,A,B,C,D,E,T,X( 8),X( 8),X(10),X( 0),X( 5));
+       BODY_20_31(25,T,A,B,C,D,E,X( 9),X( 9),X(11),X( 1),X( 6));
+       BODY_20_31(26,E,T,A,B,C,D,X(10),X(10),X(12),X( 2),X( 7));
+       BODY_20_31(27,D,E,T,A,B,C,X(11),X(11),X(13),X( 3),X( 8));
+       BODY_20_31(28,C,D,E,T,A,B,X(12),X(12),X(14),X( 4),X( 9));
+       BODY_20_31(29,B,C,D,E,T,A,X(13),X(13),X(15),X( 5),X(10));
+       BODY_20_31(30,A,B,C,D,E,T,X(14),X(14),X( 0),X( 6),X(11));
+       BODY_20_31(31,T,A,B,C,D,E,X(15),X(15),X( 1),X( 7),X(12));
+
+       BODY_32_39(32,E,T,A,B,C,D,X( 0),X( 2),X( 8),X(13));
+       BODY_32_39(33,D,E,T,A,B,C,X( 1),X( 3),X( 9),X(14));
+       BODY_32_39(34,C,D,E,T,A,B,X( 2),X( 4),X(10),X(15));
+       BODY_32_39(35,B,C,D,E,T,A,X( 3),X( 5),X(11),X( 0));
+       BODY_32_39(36,A,B,C,D,E,T,X( 4),X( 6),X(12),X( 1));
+       BODY_32_39(37,T,A,B,C,D,E,X( 5),X( 7),X(13),X( 2));
+       BODY_32_39(38,E,T,A,B,C,D,X( 6),X( 8),X(14),X( 3));
+       BODY_32_39(39,D,E,T,A,B,C,X( 7),X( 9),X(15),X( 4));
+
+       BODY_40_59(40,C,D,E,T,A,B,X( 8),X(10),X( 0),X( 5));
+       BODY_40_59(41,B,C,D,E,T,A,X( 9),X(11),X( 1),X( 6));
+       BODY_40_59(42,A,B,C,D,E,T,X(10),X(12),X( 2),X( 7));
+       BODY_40_59(43,T,A,B,C,D,E,X(11),X(13),X( 3),X( 8));
+       BODY_40_59(44,E,T,A,B,C,D,X(12),X(14),X( 4),X( 9));
+       BODY_40_59(45,D,E,T,A,B,C,X(13),X(15),X( 5),X(10));
+       BODY_40_59(46,C,D,E,T,A,B,X(14),X( 0),X( 6),X(11));
+       BODY_40_59(47,B,C,D,E,T,A,X(15),X( 1),X( 7),X(12));
+       BODY_40_59(48,A,B,C,D,E,T,X( 0),X( 2),X( 8),X(13));
+       BODY_40_59(49,T,A,B,C,D,E,X( 1),X( 3),X( 9),X(14));
+       BODY_40_59(50,E,T,A,B,C,D,X( 2),X( 4),X(10),X(15));
+       BODY_40_59(51,D,E,T,A,B,C,X( 3),X( 5),X(11),X( 0));
+       BODY_40_59(52,C,D,E,T,A,B,X( 4),X( 6),X(12),X( 1));
+       BODY_40_59(53,B,C,D,E,T,A,X( 5),X( 7),X(13),X( 2));
+       BODY_40_59(54,A,B,C,D,E,T,X( 6),X( 8),X(14),X( 3));
+       BODY_40_59(55,T,A,B,C,D,E,X( 7),X( 9),X(15),X( 4));
+       BODY_40_59(56,E,T,A,B,C,D,X( 8),X(10),X( 0),X( 5));
+       BODY_40_59(57,D,E,T,A,B,C,X( 9),X(11),X( 1),X( 6));
+       BODY_40_59(58,C,D,E,T,A,B,X(10),X(12),X( 2),X( 7));
+       BODY_40_59(59,B,C,D,E,T,A,X(11),X(13),X( 3),X( 8));
+
+       BODY_60_79(60,A,B,C,D,E,T,X(12),X(14),X( 4),X( 9));
+       BODY_60_79(61,T,A,B,C,D,E,X(13),X(15),X( 5),X(10));
+       BODY_60_79(62,E,T,A,B,C,D,X(14),X( 0),X( 6),X(11));
+       BODY_60_79(63,D,E,T,A,B,C,X(15),X( 1),X( 7),X(12));
+       BODY_60_79(64,C,D,E,T,A,B,X( 0),X( 2),X( 8),X(13));
+       BODY_60_79(65,B,C,D,E,T,A,X( 1),X( 3),X( 9),X(14));
+       BODY_60_79(66,A,B,C,D,E,T,X( 2),X( 4),X(10),X(15));
+       BODY_60_79(67,T,A,B,C,D,E,X( 3),X( 5),X(11),X( 0));
+       BODY_60_79(68,E,T,A,B,C,D,X( 4),X( 6),X(12),X( 1));
+       BODY_60_79(69,D,E,T,A,B,C,X( 5),X( 7),X(13),X( 2));
+       BODY_60_79(70,C,D,E,T,A,B,X( 6),X( 8),X(14),X( 3));
+       BODY_60_79(71,B,C,D,E,T,A,X( 7),X( 9),X(15),X( 4));
+       BODY_60_79(72,A,B,C,D,E,T,X( 8),X(10),X( 0),X( 5));
+       BODY_60_79(73,T,A,B,C,D,E,X( 9),X(11),X( 1),X( 6));
+       BODY_60_79(74,E,T,A,B,C,D,X(10),X(12),X( 2),X( 7));
+       BODY_60_79(75,D,E,T,A,B,C,X(11),X(13),X( 3),X( 8));
+       BODY_60_79(76,C,D,E,T,A,B,X(12),X(14),X( 4),X( 9));
+       BODY_60_79(77,B,C,D,E,T,A,X(13),X(15),X( 5),X(10));
+       BODY_60_79(78,A,B,C,D,E,T,X(14),X( 0),X( 6),X(11));
+       BODY_60_79(79,T,A,B,C,D,E,X(15),X( 1),X( 7),X(12));
+       
+       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;
+
+               }
+       }
+#endif
diff --git a/crypto/rand.h b/crypto/rand.h
new file mode 100644 (file)
index 0000000..058f3f1
--- /dev/null
@@ -0,0 +1,37 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef RAND_H
+#define RAND_H
+
+#include "includes.h"
+
+void RAND_init(void);
+void RAND_stop(void);
+
+int32_t RAND_bytes(char *buf, uint32_t len);
+void RAND_add_event_entropy(EventType *e);
+void RAND_add_net_entropy(void);
+
+#endif
diff --git a/crypto/rand_armstubs.c b/crypto/rand_armstubs.c
new file mode 100644 (file)
index 0000000..dc36ff2
--- /dev/null
@@ -0,0 +1,78 @@
+/**********
+ * Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "rand.h"
+#include "armstubs.h"
+
+void RAND_init(void) {
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    PealCall(arm_module, sym, 0);
+}
+
+
+void RAND_stop(void) {
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    PealCall(arm_module, sym, 0);
+}
+
+
+int32_t RAND_bytes(char *buf, uint32_t len) {
+    uint32_t param[2];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param[0] = (uint32_t)buf;
+    param[1] = (uint32_t)len;
+    return (int32_t) PealCall(arm_module, sym, param);
+}
+
+
+void RAND_add_event_entropy(EventType *e) {
+    uint32_t param[1];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    param[0] = (uint32_t)e;
+    PealCall(arm_module, sym, param);
+}
+
+
+void RAND_add_net_entropy(void) {
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+
+    PealCall(arm_module, sym, 0);
+}
+
+
diff --git a/data/connectionlist.c b/data/connectionlist.c
new file mode 100644 (file)
index 0000000..2ec9255
--- /dev/null
@@ -0,0 +1,248 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "recordlist.h"
+#include "rsrc/rsrc.h"
+#include "formutils.h"
+
+#include "connectionlist.h"
+
+/* connection record format:
+   1 byte length
+   n bytes hostname\0
+   1 byte length
+   n bytes portname\0 (empty defaults to "22")
+   1 byte length
+   n bytes username\0
+*/
+
+#define ConnectionDBName "pssh Connection List"
+#define ConnectionDBType 'Conn'
+static DmOpenRef ConnectionDB = 0;
+static RecordList *ConnectionList = NULL;
+
+
+extern DmOpenRef OpenDB(UInt32 type, char *name, Boolean resDB, Boolean create);
+
+static Boolean ReadConnectionRecord(char *recordP, char **hostname, char **portname, char **username) CONNECTIONLIST_SEGMENT;
+static void DrawConnectionRecord(MemPtr recordP, UInt16 index, RectanglePtr bounds)  CONNECTIONLIST_SEGMENT;
+
+
+Boolean ConnectionListInit(void)
+{
+    ConnectionDB = OpenDB(ConnectionDBType, ConnectionDBName, false, true);
+    if (!ConnectionDB) return false;
+
+    ConnectionList = 
+        RecordListNew(ConnectionDB, MainFormID, MainConnectionTableID, 
+                      MainConnectionScrollbarID, DrawConnectionRecord);
+    if (!ConnectionList) return false;
+
+    return true;
+}
+
+
+void ConnectionListFree(void)
+{
+    if (ConnectionList) RecordListFree(ConnectionList);
+    if (ConnectionDB)   DmCloseDatabase(ConnectionDB);
+}
+
+void ConnectionListUpdate(void) {
+    RecordListUpdate(ConnectionList);
+}
+
+UInt16 ConnectionListSelectedIndex(void) {
+    return RecordListSelectedIndex(ConnectionList);
+}
+
+void ConnectionListSetSelectedIndex(UInt16 index) {
+    RecordListSetSelectedIndex(ConnectionList, index);
+}
+
+void ConnectionListClearSelection(void) {
+    RecordListClearSelection(ConnectionList);
+}
+
+void ConnectionListDeleteSelectedRecord(void) {
+    RecordListDeleteSelectedRecord(ConnectionList);
+}
+
+Boolean ConnectionListHandleEvent(EventPtr event) {
+    return RecordListHandleEvent(ConnectionList, event);
+}
+
+
+
+// returned values are only usable until recordP is unlocked
+static Boolean ReadConnectionRecord(char *recordP, char **hostname, 
+                                    char **portname, char **username)
+{
+#define CHECK_SPACE(n) do { if (p+(n)>end) goto bad; } while (0)
+
+    Boolean ok = true;
+    uint8_t *p = recordP;
+    uint8_t *end = p + MemPtrSize(recordP);
+    uint8_t len;
+
+    // hostname field
+    CHECK_SPACE(1);
+    len = *p++;
+    CHECK_SPACE(len);
+    if (p[len-1] != '\0') goto bad;
+    if (hostname) *hostname = p;
+    p += len;
+
+    // port number field
+    CHECK_SPACE(1);
+    len = *p++;
+    CHECK_SPACE(len);
+    if (p[len-1] != '\0') goto bad;
+    if (portname) {
+        if (len > 1) {
+            *portname = p;
+        } else {
+            // no port specified - use default port
+            *portname = "22";
+        }
+    }
+    p += len;
+
+    // username field
+    CHECK_SPACE(1);
+    len = *p++;
+    CHECK_SPACE(len);
+    if (p[len-1] != '\0') goto bad;
+    if (username) *username = p;
+    p += len;
+
+    return true;
+
+ bad: 
+    return false;
+
+#undef CHECK_SPACE
+}
+
+
+MemHandle ConnectionListReadSelectedRecord(char **hostname, char **portname, char **username)
+{
+    MemHandle recordH;
+    MemPtr recordP;
+    Boolean ok;
+
+    recordH = RecordListQuerySelectedRecord(ConnectionList);
+    if (!recordH) return false;
+
+    recordP = MemHandleLock(recordH);
+    ok = ReadConnectionRecord(recordP, hostname, portname, username);
+    
+    if (!ok) {
+        MemHandleUnlock(recordH);
+        return NULL;
+    } else {
+        return recordH;
+    }
+}
+
+
+Boolean ConnectionListWriteSelectedRecord(FieldPtr hostFld, FieldPtr portFld, FieldPtr userFld)
+{
+    Boolean ok = true;
+    MemHandle recordH;
+    UInt32 size;
+
+    // resize record and write data to it
+    
+    size = (1+FldGetTextLength(hostFld)+1 + 
+            1+FldGetTextLength(portFld)+1 + 
+            1+FldGetTextLength(userFld)+1);
+    
+    recordH = RecordListGetSelectedRecord(ConnectionList, size);
+    if (!recordH) {
+        // error resizing or opening record
+        // complain, leave existing record intact, don't connect
+        // fixme
+        ok = false;
+    } else {
+        Err err = 0;
+        UInt32 written = 0;
+        MemPtr recordP = MemHandleLock(recordH);
+        if (!err) err = PrvStoreFieldToRecord(hostFld, recordP, &written);
+        if (!err) err = PrvStoreFieldToRecord(portFld, recordP, &written);
+        if (!err) err = PrvStoreFieldToRecord(userFld, recordP, &written);
+        MemHandleUnlock(recordH);
+        RecordListReleaseRecord(ConnectionList, recordH, true);
+        if (err) {
+            // error writing record
+            // complain, delete record, don't connect
+            // fixme
+            ok = false;
+        }
+    }
+
+    return ok;
+}
+
+
+
+static void DrawConnectionRecord(MemPtr recordP, UInt16 index, 
+                                 RectanglePtr bounds)
+{
+    char *hostname;
+    char *portname;
+    char *username;
+
+    if (ReadConnectionRecord(recordP, &hostname, &portname, &username)) 
+    {
+        // "username@hostname"
+        // "username@hostname:portname"  (non-default port only)
+        int x = bounds->topLeft.x + 1;
+        int y = bounds->topLeft.y;
+        int len;
+        char *buf;
+        int showPort;
+
+        showPort = (0 != strcmp(portname, "") && 0 != strcmp(portname, "22"));
+
+        len = strlen(username) + strlen("@") + strlen(hostname);
+        if (showPort) {
+            len += strlen(":") + strlen(portname);
+        }
+
+        buf = arena_malloc(len + 1);
+        strcpy(buf, username);
+        strcat(buf, "@");
+        strcat(buf, hostname);
+        if (showPort) {
+            strcat(buf, ":");
+            strcat(buf, portname);
+        }
+        
+        WinDrawTruncChars(buf, len, x, y, 
+                          bounds->topLeft.x + bounds->extent.x - x - 1);
+    }
+}
+
diff --git a/data/connectionlist.h b/data/connectionlist.h
new file mode 100644 (file)
index 0000000..ea1d1e1
--- /dev/null
@@ -0,0 +1,46 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef CONNECTIONLIST_H
+#define CONNECTIONLIST_H
+
+#include "includes.h"
+#include "data/recordlist.h"
+
+
+Boolean ConnectionListInit(void) CONNECTIONLIST_SEGMENT;
+void ConnectionListFree(void) CONNECTIONLIST_SEGMENT;
+
+void ConnectionListUpdate(void) CONNECTIONLIST_SEGMENT;
+Boolean ConnectionListHandleEvent(EventPtr event) CONNECTIONLIST_SEGMENT;
+
+UInt16 ConnectionListSelectedIndex(void) CONNECTIONLIST_SEGMENT;
+void ConnectionListSetSelectedIndex(UInt16 index) CONNECTIONLIST_SEGMENT;
+void ConnectionListClearSelection(void) CONNECTIONLIST_SEGMENT;
+
+MemHandle ConnectionListReadSelectedRecord(char **hostname, char **portname, char **username) CONNECTIONLIST_SEGMENT;
+Boolean ConnectionListWriteSelectedRecord(FieldPtr hostFld, FieldPtr portFld, FieldPtr userFld)CONNECTIONLIST_SEGMENT;
+void ConnectionListDeleteSelectedRecord(void) CONNECTIONLIST_SEGMENT;
+
+#endif
diff --git a/data/hostkeys.c b/data/hostkeys.c
new file mode 100644 (file)
index 0000000..805afae
--- /dev/null
@@ -0,0 +1,457 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "recordlist.h"
+#include "rsrc/rsrc.h"
+#include "ssh/openssh/key.h"
+#include "ssh/openssh/match.h"
+
+#include "hostkeys.h"
+
+
+/* host key record format:
+
+   2 bytes length
+   n bytes hostname,hostname,hostname\0
+   2 bytes length
+   n bytes key blob
+*/
+
+
+#define HostKeyDBName "pssh Known Host Keys"
+#define HostKeyDBType 'HKey'
+static DmOpenRef HostKeyDB = 0;
+static RecordList *HostKeyList = NULL;
+
+static Boolean ReadHostKeyRecord(uint8_t *recordP, char **hostnames, uint8_t **keyblob, uint16_t *keybloblen) HOSTKEYS_SEGMENT;
+static Boolean WriteHostKeyRecord(MemPtr recordP, const char *hostnames, uint8_t *keyblob, uint16_t keybloblen) HOSTKEYS_SEGMENT;
+static void DrawHostKeyRecord(MemPtr recordP, UInt16 index, RectanglePtr bounds) HOSTKEYS_SEGMENT;
+
+extern DmOpenRef OpenDB(UInt32 type, char *name, Boolean resDB, Boolean create);
+
+Boolean HostKeysInit(void)
+{
+    HostKeyDB = OpenDB(HostKeyDBType, HostKeyDBName, false, true);
+    if (!HostKeyDB) return false;
+
+    HostKeyList = 
+        RecordListNew(HostKeyDB, HostKeysFormID, HostKeysFormKeyTableID, 
+                      HostKeysFormKeyScrollbarID, DrawHostKeyRecord);
+    if (!HostKeyList) return false;
+
+    return true;
+}
+
+
+void HostKeysFree(void)
+{
+    RecordListFree(HostKeyList);
+    DmCloseDatabase(HostKeyDB);
+}
+
+
+void HostKeysUpdate(void)
+{
+    return RecordListUpdate(HostKeyList);
+}
+
+
+Boolean HostKeysHandleEvent(EventPtr event)
+{
+    return RecordListHandleEvent(HostKeyList, event);
+}
+
+
+UInt16 HostKeysSelectedIndex(void)
+{
+    return RecordListSelectedIndex(HostKeyList);
+}
+
+
+void HostKeysDeleteSelectedRecord(void)
+{
+    return RecordListDeleteSelectedRecord(HostKeyList);
+}
+
+
+static Boolean ReadHostKeyRecord(uint8_t *recordP, char **hostnames, 
+                                 uint8_t **keyblob, uint16_t *keybloblen)
+{
+#define CHECK_SPACE(n) do { if (p+(n)>end) goto bad; } while (0)
+
+    uint8_t *p;
+    uint8_t *end;
+    uint16_t len;
+
+    p = recordP;
+    end = recordP + MemPtrSize(recordP);
+
+    // read hostnames string
+
+    CHECK_SPACE(2);
+    len = *(uint16_t *)p;
+    p += 2;
+    CHECK_SPACE(len);
+    *hostnames = (char *)p;
+    if ((*hostnames)[len-1] != '\0') goto bad;
+    p += len;
+
+    // read key blob
+    
+    CHECK_SPACE(2);
+    *keybloblen = *(uint16_t *)p;
+    p += 2;
+    CHECK_SPACE(*keybloblen);
+    *keyblob = p;
+
+    p += *keybloblen;
+
+    // allow trailing data for forward compatibility
+
+    return true;
+
+ bad:
+    return false;
+
+#undef CHECK_SPACE
+}
+
+
+static Boolean WriteHostKeyRecord(MemPtr recordP, const char *hostnames, 
+                                  uint8_t *keyblob, uint16_t keybloblen)
+{
+    Err err = 0;
+    uint32_t offset = 0;
+    uint16_t hostnameslen = strlen(hostnames) + 1;
+
+    if (!err) err = DmWrite(recordP, offset, &hostnameslen, 2);
+    offset += 2;
+    if (!err) err = DmWrite(recordP, offset, hostnames, hostnameslen);
+    offset += hostnameslen;
+    if (!err) err = DmWrite(recordP, offset, &keybloblen, 2);
+    offset += 2;
+    if (!err) err = DmWrite(recordP, offset, keyblob, keybloblen);
+
+    return (err == 0);
+}
+
+
+
+MemHandle HostKeysQuerySelectedRecord(char **hostnames, 
+                                      uint8_t **keyblob, uint16_t *keybloblen)
+{
+    return HostKeysQueryIndexedRecord(RecordListSelectedIndex(HostKeyList), 
+                                      hostnames, keyblob, keybloblen);
+}
+
+
+MemHandle HostKeysQueryIndexedRecord(UInt16 index, char **hostnames, 
+                                     uint8_t **keyblob, uint16_t *keybloblen)
+{
+    MemHandle recordH;
+    MemPtr recordP;
+    Boolean ok;
+
+    recordH = RecordListQueryIndexedRecord(HostKeyList, index);
+    if (!recordH) return NULL;
+
+    recordP = MemHandleLock(recordH);
+    ok = ReadHostKeyRecord(recordP, hostnames, keyblob, keybloblen);
+    
+    if (!ok) {
+        MemHandleUnlock(recordH);
+        return NULL;
+    } else {
+        return recordH;
+    }
+}
+
+
+UInt16 HostKeysFindRecordForHostname(const char *hostname)
+{
+    UInt16 count = RecordListCount(HostKeyList);
+    UInt16 index;
+    MemHandle recordH;
+    char *savedhosts;
+    uint8_t *keyblob;
+    uint16_t keybloblen;
+
+    for (index = 0; index < count; index++) {
+        if ((recordH = HostKeysQueryIndexedRecord(index, &savedhosts, 
+                                                  &keyblob, &keybloblen)))
+        {
+            char *host = match_list(hostname, savedhosts, NULL);
+            MemHandleUnlock(recordH);
+            if (host) {
+                xfree(host);
+                return index;
+            }
+        }
+    }
+
+    return noRecord;
+}
+
+
+UInt16 HostKeysFindRecordForKey(Key *hostkey)
+{
+    UInt16 count = RecordListCount(HostKeyList);
+    UInt16 index;
+    MemHandle recordH;
+    char *savedhosts;
+    uint8_t *keyblob;
+    uint16_t keybloblen;
+
+    for (index = 0; index < count; index++) {
+        if ((recordH = HostKeysQueryIndexedRecord(index, &savedhosts, 
+                                                  &keyblob, &keybloblen)))
+        {
+            Key *savedkey = key_from_blob(keyblob, keybloblen);
+            Boolean match = key_equal(savedkey, hostkey);
+            key_free(savedkey);
+            MemHandleUnlock(recordH);
+            
+            if (match) return index;
+        }
+    }
+
+    return noRecord;
+}
+
+
+Boolean HostKeysAddRecord(const char *hostname, Key *hostkey)
+{
+    uint16_t keybloblen = 1;
+    uint32_t recordlen;
+    MemHandle recordH;
+    MemPtr recordP;
+    uint8_t *keyblob;
+    Boolean ok;
+
+    key_to_blob(hostkey, &keyblob, &keybloblen);
+
+    recordlen = 2L + strlen(hostname) + 1 + 2 + keybloblen;
+    RecordListClearSelection(HostKeyList);
+    recordH = RecordListGetSelectedRecord(HostKeyList, recordlen);
+    if (!recordH) {
+        xfree(keyblob);
+        return false;
+    }
+
+    recordP = MemHandleLock(recordH);
+
+    ok = WriteHostKeyRecord(recordP, hostname, keyblob, keybloblen);
+
+    // fixme delete new record on failure
+    xfree(keyblob);
+    MemHandleUnlock(recordH);
+    RecordListReleaseRecord(HostKeyList, recordH, true);
+
+    return ok;
+}
+
+
+Boolean HostKeysAddHostnameToRecord(const char *hostname, UInt16 index)
+{
+    MemHandle recordH;
+    MemPtr recordP;
+    uint32_t recordlen;
+    char *hostnames;
+    uint8_t *keyblob;
+    uint16_t keybloblen;
+    Boolean result = false;
+    Boolean ok;
+    char *newhostnames;
+    uint8_t *newkeyblob;
+
+    RecordListClearSelection(HostKeyList);
+    RecordListSetSelectedIndex(HostKeyList, index);
+
+    recordH = RecordListQuerySelectedRecord(HostKeyList);
+    if (!recordH) return false;
+
+    // new length includes comma and new hostname
+    // (assumes record contains at least 1 hostname, and that 
+    // the new hostname isn't there already)
+    recordlen = MemHandleSize(recordH) + strlen(hostname) + strlen(",");
+
+    recordH = DmResizeRecord(HostKeyDB, index, recordlen);
+    if (!recordH) return false;
+    recordP = MemHandleLock(recordH);
+
+    ok = ReadHostKeyRecord(recordP, &hostnames, &keyblob, &keybloblen);
+    if (!ok) goto bad;
+    
+    newhostnames = arena_malloc(strlen(hostnames) + strlen(",") + strlen(hostname) + 1);
+    strcpy(newhostnames, hostnames);
+    strcat(newhostnames, ",");
+    strcat(newhostnames, hostname);
+
+    newkeyblob = arena_malloc(keybloblen);
+    memcpy(newkeyblob, keyblob, keybloblen);
+    
+    ok = WriteHostKeyRecord(recordP, newhostnames, newkeyblob, keybloblen);
+    arena_free(newhostnames);
+    arena_free(newkeyblob);
+    if (!ok) goto bad;
+
+    result = true;
+
+ bad:
+    // fixme destroy record on failure
+    MemHandleUnlock(recordH);
+    RecordListReleaseRecord(HostKeyList, recordH, true);
+    return result;
+}
+
+
+
+Boolean HostKeysRemoveHostnameFromRecord(const char *hostname, UInt16 index)
+{
+    MemHandle recordH;
+    MemPtr recordP;
+    uint32_t recordlen;
+    char *hostnames;
+    uint8_t *keyblob;
+    uint16_t keybloblen;
+    Boolean ok;
+    char *newhostnames;
+    uint8_t *newkeyblob;
+    char *start, *end;
+
+    RecordListClearSelection(HostKeyList);
+    RecordListSetSelectedIndex(HostKeyList, index);
+
+    recordH = RecordListQuerySelectedRecord(HostKeyList);
+    if (!recordH) return false;
+    recordP = MemHandleLock(recordH);
+
+    ok = ReadHostKeyRecord(recordP, &hostnames, &keyblob, &keybloblen);
+    if (!ok) {
+        MemHandleUnlock(recordH);
+        return false;
+    }
+
+    // If this is the only hostname in the record - kill it completely
+    if (0 == strcasecmp(hostnames, hostname)) {
+        MemHandleUnlock(recordH);
+        RecordListDeleteSelectedRecord(HostKeyList);
+        return true;
+    }
+
+    // Make a copy of newhostnames that does not include hostname
+    newhostnames = arena_strdup(hostnames);
+    start = end = NULL;
+    if (!start) {
+        // try ...,hostname,...
+        char *commahostnamecomma = arena_malloc(1 + strlen(hostname) + 1 + 1);
+        strcpy(commahostnamecomma, ",");
+        strcat(commahostnamecomma, hostname);
+        strcat(commahostnamecomma, ",");
+        start = strcasestr(newhostnames, commahostnamecomma);
+        if (start) end = start + strlen(commahostnamecomma);
+        arena_free(commahostnamecomma);
+    }
+    if (!start) {
+        // try hostname,...
+        char *hostnamecomma = arena_malloc(strlen(hostname) + 1 + 1);
+        strcpy(hostnamecomma, hostname);
+        strcat(hostnamecomma, ",");
+        if (0 == strncmp(newhostnames, hostnamecomma, strlen(hostnamecomma))) {
+            start = newhostnames;
+            end = start + strlen(hostnamecomma);
+        }
+        arena_free(hostnamecomma);
+    }
+    if (!start) {
+        // try ...,hostname
+        char *commahostname = arena_malloc(1 + strlen(hostname) + 1);
+        strcpy(commahostname, ",");
+        strcat(commahostname, hostname);
+        start = strrchr(newhostnames, ',');
+        if (start  &&  0 == strcmp(start, commahostname)) {
+            end = start + strlen(commahostname);
+        }
+        arena_free(commahostname);
+    }
+    if (!start) {
+        // didn't find hostname in hostname list
+        MemHandleUnlock(recordH);
+        arena_free(newhostnames);
+        return false;
+    }
+
+    // kill [start..end]
+    memmove(start, end, strlen(end)+1);
+    
+    newkeyblob = arena_malloc(keybloblen);
+    memcpy(newkeyblob, keyblob, keybloblen);
+    
+    recordlen = 2L + strlen(newhostnames) + 1 + 2 + keybloblen;
+    
+    // Reopen the record for writing and resize
+    MemHandleUnlock(recordH);
+    recordH = DmResizeRecord(HostKeyDB, RecordListSelectedIndex(HostKeyList), 
+                             recordlen);
+    if (!recordH) {
+        arena_free(newhostnames);
+        arena_free(newkeyblob);
+        return false;
+    }
+
+    // Write the new record data
+    recordP = MemHandleLock(recordH);
+    ok = WriteHostKeyRecord(recordP, newhostnames, newkeyblob, keybloblen);
+    MemHandleUnlock(recordH);
+    RecordListReleaseRecord(HostKeyList, recordH, true);
+    arena_free(newhostnames);
+    arena_free(newkeyblob);
+    if (!ok) return false;
+
+    return true;
+}
+
+
+static void DrawHostKeyRecord(MemPtr recordP, UInt16 index, 
+                              RectanglePtr bounds)
+{
+    char *hostnames;
+    uint8_t *keyblob;
+    uint16_t keybloblen;
+
+    if (ReadHostKeyRecord(recordP, &hostnames, 
+                          &keyblob, &keybloblen))
+    {
+        // "hostname,hostname,hostname"
+        int len;
+        int x = bounds->topLeft.x + 1;
+        int y = bounds->topLeft.y;
+
+        len = StrLen(hostnames);
+        WinDrawTruncChars(hostnames, len, x, y, 
+                          bounds->topLeft.x + bounds->extent.x - x - 1);
+        x += FntCharsWidth(hostnames, len);
+    }
+}
diff --git a/data/hostkeys.h b/data/hostkeys.h
new file mode 100644 (file)
index 0000000..f725d1b
--- /dev/null
@@ -0,0 +1,51 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef HOSTKEYS_H
+#define HOSTKEYS_H
+
+#include "includes.h"
+#include "data/recordlist.h"
+#include "ssh/openssh/key.h"
+
+void HostKeysFree(void) HOSTKEYS_SEGMENT;
+Boolean HostKeysInit(void) HOSTKEYS_SEGMENT;
+
+void HostKeysUpdate(void) HOSTKEYS_SEGMENT;
+Boolean HostKeysHandleEvent(EventPtr event) HOSTKEYS_SEGMENT;
+
+UInt16 HostKeysSelectedIndex(void) HOSTKEYS_SEGMENT;
+
+MemHandle HostKeysQueryIndexedRecord(UInt16 index, char **hostnames, uint8_t **keyblob, uint16_t *keybloblen) HOSTKEYS_SEGMENT;
+MemHandle HostKeysQuerySelectedRecord(char **hostnames, uint8_t **keyblob, uint16_t *keybloblen) HOSTKEYS_SEGMENT;
+void HostKeysDeleteSelectedRecord(void) HOSTKEYS_SEGMENT;
+
+UInt16 HostKeysFindRecordForHostname(const char *hostname) HOSTKEYS_SEGMENT;
+UInt16 HostKeysFindRecordForKey(Key *hostkey) HOSTKEYS_SEGMENT;
+
+Boolean HostKeysAddRecord(const char *hostname, Key *hostkey) HOSTKEYS_SEGMENT;
+Boolean HostKeysAddHostnameToRecord(const char *hostname, UInt16 index) HOSTKEYS_SEGMENT;
+Boolean HostKeysRemoveHostnameFromRecord(const char *hostname, UInt16 index) HOSTKEYS_SEGMENT;
+
+#endif
diff --git a/data/memolist.c b/data/memolist.c
new file mode 100644 (file)
index 0000000..a384bc5
--- /dev/null
@@ -0,0 +1,118 @@
+/**********
+ * Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "recordlist.h"
+#include "rsrc/rsrc.h"
+#include "formutils.h"
+
+#include "memolist.h"
+
+
+#define MemoDBName "MemoDB"
+static DmOpenRef MemoDB = 0;
+static RecordList *MemoList = NULL;
+
+static void DrawMemo(MemPtr recordP, UInt16 index, RectanglePtr bounds) DATA_SEGMENT;
+
+Boolean MemoListInit(void)
+{
+    MemoDB = DmOpenDatabaseByTypeCreator('DATA', 'memo', dmModeReadWrite);
+    if (!MemoDB) {
+        return false;
+    }
+
+    MemoList = RecordListNew(MemoDB, MemoFormID, MemoFormTableID, 
+                             MemoFormScrollbarID, DrawMemo);
+    if (!MemoList) {
+        DmCloseDatabase(MemoDB);
+        return false;
+    }
+    return true;
+}
+
+void MemoListFree(void)
+{
+    if (MemoList) RecordListFree(MemoList);
+    if (MemoDB) DmCloseDatabase(MemoDB);
+    MemoList = NULL;
+    MemoDB = 0;
+}
+
+void MemoListUpdate(void) {
+    if (MemoList) RecordListUpdate(MemoList);
+}
+
+UInt16 MemoListSelectedIndex(void) {
+    if (MemoList) return RecordListSelectedIndex(MemoList);
+    else return noRecord;
+}
+
+void MemoListSetSelectedIndex(UInt16 index) {
+    if (MemoList) RecordListSetSelectedIndex(MemoList, index);
+}
+
+void MemoListClearSelection(void) {
+    if (MemoList) RecordListClearSelection(MemoList);
+}
+
+Boolean MemoListHandleEvent(EventPtr event) {
+    if (MemoList) return RecordListHandleEvent(MemoList, event);
+    else return false;
+}
+
+MemHandle MemoListQuerySelectedRecord(void)
+{
+    if (MemoList) {
+        UInt16 index = RecordListSelectedIndex(MemoList);
+        if (index != noRecord) {
+            // hack to cope with hidden records, which RecordList cannot
+            UInt16 realIndex = 0;
+            Err err = DmSeekRecordInCategory(MemoDB, &realIndex, index, 
+                                             dmSeekForward, dmAllCategories);
+            if (!err) {
+                return RecordListQueryIndexedRecord(MemoList, realIndex);
+            }
+        }
+    } 
+
+    return NULL;
+}
+
+static void DrawMemo(MemPtr recordP, UInt16 index, RectanglePtr bounds)
+{
+    int x = bounds->topLeft.x + 1;
+    int y = bounds->topLeft.y;
+    
+    char *start = recordP;
+    char *endR = strchr(start, '\r');
+    char *endN = strchr(start, '\n');
+    char *end = start + MemPtrSize(start);
+    uint16_t length = end - start;
+
+    if (endR) length = MIN(length, endR - start);
+    if (endN) length = MIN(length, endN - start);
+
+    WinDrawTruncChars(start, length, x, y, bounds->topLeft.x + bounds->extent.x - x - 1);
+}
diff --git a/data/memolist.h b/data/memolist.h
new file mode 100644 (file)
index 0000000..1f999c4
--- /dev/null
@@ -0,0 +1,44 @@
+/**********
+ * Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef MEMOLIST_H
+#define MEMOLIST_H
+
+#include "includes.h"
+#include "data/recordlist.h"
+#include "ssh/openssh/key.h"
+
+Boolean MemoListInit(void) DATA_SEGMENT;
+void MemoListFree(void) DATA_SEGMENT;
+
+void MemoListUpdate(void) DATA_SEGMENT;
+Boolean MemoListHandleEvent(EventPtr event) DATA_SEGMENT;
+
+UInt16 MemoListSelectedIndex(void) DATA_SEGMENT;
+void MemoListSetSelectedIndex(UInt16 index) DATA_SEGMENT;
+void MemoListClearSelection(void) DATA_SEGMENT;
+
+MemHandle MemoListQuerySelectedRecord(void) DATA_SEGMENT;
+
+#endif
diff --git a/data/prefs.c b/data/prefs.c
new file mode 100644 (file)
index 0000000..ecc5445
--- /dev/null
@@ -0,0 +1,206 @@
+/**********
+ * Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "prefs.h"
+
+
+// There is one global default prefs list. 
+// There is also a set of override values for each connection, mostly 
+// for terminal settings.
+
+// Each preference is a RESOURCE
+// res type: 'dflt' or some ID for a connection override
+// res id: which pref
+
+/* 
+   interface: 
+   echo password (NO)
+   keyboard pane(s)
+   
+   terminal:
+   TERM type ("xterm")
+   scrollback line count (500?)
+   scroll down on input (NO)
+   scroll down on keypress (YES)
+   
+   ssh:
+   compression (NO) (fixme implement)
+   ciphers ("aes128-cbc,3des-cbc")
+   authmethod (fixme implement)
+   
+   putty terminal:
+   wrap_mode (YES==autowrap)
+   dec_om "DEC Origin Mode" (YES)
+   lfhascr "Implicit CR in every LF" (NO)
+   bce "Background Color Erase" (?)
+   blink_text "Blink" (NO)
+   answerback "Answerback to ^E" ("pssh")
+   localecho (NO)
+   localedit (NO)
+   printing (NO)
+
+   putty keyboard:
+   bksp_is_delete "Backspace is DEL" (YES==^? rather than ^H)
+   rxvt_homeend "rxvt Home and End" (NO)
+   funky_type "Function Keys" (DIGITAL, Linux, xterm, VT400, VT100+, SCO)
+   app_cursor "Application Cursor Keys" (NO?)
+   app_keypad "Application Keypad" (NO?)
+   nethack "NetHack Keypad" (NO)
+   compose (NO) (use real compose key on keyboard?)
+   ctrlalt (NO)
+   
+   lots more putty...
+   
+*/
+
+
+#define noRecord ((UInt16)0xffff)
+
+
+static DmOpenRef PrefsDB = 0;
+// fixme implement overrides
+
+extern DmOpenRef OpenDB(UInt32 type, char *name, Boolean resDB, Boolean create);
+
+int PrefsInit(void)
+{
+    PrefsDB = OpenDB('Pref', "pssh Preferences", true, true);
+    return (PrefsDB != 0);
+}
+
+
+static MemHandle PrefsGetHandle(uint32_t which, Boolean fallback)
+{
+    UInt16 index;
+
+    // fixme search override here unless fallback==false
+
+    // search default prefs
+    index = DmFindResource(PrefsDB, 'dflt', which, NULL);
+    if (index == noRecord) return NULL;
+
+    return DmGetResourceIndex(PrefsDB, index);
+}
+
+
+uint32_t PrefsGetInt(uint32_t which, uint32_t defaultValue)
+{
+    uint32_t result;
+    uint32_t *p;
+    MemHandle h = PrefsGetHandle(which, true);
+    if (!h) return defaultValue;
+    if (MemHandleSize(h) != 4) return defaultValue;
+    
+    p = MemHandleLock(h);
+    result = *p;
+    MemHandleUnlock(h);
+    DmReleaseResource(h);
+
+    return result;
+}
+
+
+void PrefsPutInt(uint32_t which, uint32_t value)
+{
+    uint32_t *p;
+    MemHandle h = PrefsGetHandle(which, false);
+    if (h  &&  MemHandleSize(h) == sizeof(value)) {
+        // resource exists, and it's the right size
+        p = MemHandleLock(h);
+        DmWrite(p, 0, &value, sizeof(value));
+        MemHandleUnlock(h);
+        DmReleaseResource(h);
+        return;
+    }
+    else if (h) {
+        // resource exists, but its the wrong size
+        h = DmResizeResource(h, sizeof(value));
+        p = MemHandleLock(h);
+        DmWrite(p, 0, &value, sizeof(value));
+        MemHandleUnlock(h);
+        DmReleaseResource(h);
+    }
+    else {
+        // resource does not exist
+        h = DmNewResource(PrefsDB, 'dflt', which, sizeof(value));
+        p = MemHandleLock(h);
+        DmWrite(p, 0, &value, sizeof(value));
+        MemHandleUnlock(h);
+        DmReleaseResource(h);
+    }
+}
+
+
+char *PrefsGetString(uint32_t which, char *defaultValue)
+{
+    char *result;
+    char *p;
+    size_t size;
+    MemHandle h = PrefsGetHandle(which, true);
+    if (!h) return arena_strdup(defaultValue);
+    size = MemHandleSize(h);
+    
+    p = MemHandleLock(h);
+    result = arena_malloc(size + 1); // be paranoid about nul terminator
+    memcpy(result, p, size);
+    result[size] = '\0';
+    MemHandleUnlock(h);
+    DmReleaseResource(h);
+
+    return result;
+}
+
+
+void PrefsPutString(uint32_t which, char *value)
+{
+    char *p;
+    size_t sizeNeeded = strlen(value)+1;
+    MemHandle h = PrefsGetHandle(which, false);
+    if (h  &&  MemHandleSize(h) >= sizeNeeded) {
+        // resource exists, and it's big enough
+        p = MemHandleLock(h);
+        DmWrite(p, 0, value, sizeNeeded);
+        MemHandleUnlock(h);
+        DmReleaseResource(h);
+        return;
+    }
+    else if (h) {
+        // resource exists, but it's the wrong size
+        h = DmResizeResource(h, sizeNeeded);
+        p = MemHandleLock(h);
+        DmWrite(p, 0, value, sizeNeeded);
+        MemHandleUnlock(h);
+        DmReleaseResource(h);        
+    }
+    else {
+        // resource does not exist
+        h = DmNewResource(PrefsDB, 'dflt', which, sizeNeeded);
+        p = MemHandleLock(h);
+        DmWrite(p, 0, value, sizeNeeded);
+        MemHandleUnlock(h);
+        DmReleaseResource(h);
+    }
+}
+
diff --git a/data/prefs.h b/data/prefs.h
new file mode 100644 (file)
index 0000000..86b297a
--- /dev/null
@@ -0,0 +1,115 @@
+/**********
+ * Copyright (c) 2004-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+
+#ifndef PREFS_H
+#define PREFS_H
+
+#include "includes.h"
+
+// Preference values
+// NEVER CHANGE THESE, only add to them.
+
+// non-terminal interface
+#define prefEchoPassword 1 // boolean
+#define prefTopPane 2      // int
+#define prefBottomPane 3   // int
+#define prefNoAutoOff 4    // unused
+#define prefHideTitleBar 5 // boolean
+#define prefHideInputArea 6 // boolean
+// #define prefHideStatusBar 7 // unused
+
+// ssh
+#define prefCipherAES128CBC 100 // boolean
+#define prefCipher3DESCBC 101   // boolean
+#define prefAuthPublicKey 102   // boolean
+#define prefAuthPassword 103    // boolean
+#define prefCompressZLib 104    // boolean
+#define prefAuthKbdInt   105    // boolean
+
+// basic terminal
+#define prefTerminalType 200          // string
+#define prefScrollbackLines 201       // int
+#define prefScrollDownOnActivity 202  // boolean
+#define prefScrollDownOnTyping 203    // boolean
+#define prefTerminalFont 204          // int
+#define prefTerminalForeColor 205     // int
+#define prefTerminalBackColor 206     // int
+#define prefBellBeep 207              // boolean
+#define prefBellFlash 208             // boolean
+#define prefBackspace 209             // boolean
+#define prefBackquote 210             // boolean
+
+// values for prefTerminalFont:
+#define font4x6 1
+#define font6x10 2
+#define fontDefault font4x6
+
+
+// values for prefTerminalFore/BackColor
+#define blackColor   0
+#define redColor     1
+#define greenColor   2
+#define yellowColor  3
+#define blueColor    4
+#define magentaColor 5
+#define cyanColor    6
+#define whiteColor   7
+#define defaultForeColor blackColor
+#define defaultBackColor whiteColor
+
+// values for prefScrollbackLines
+#define defaultScrollbackLines 500
+#define maxScrollbackLines 9999
+
+// values for bell
+#define defaultBellBeep 1
+#define defaultBellFlash 0
+
+// values for scroll behavior
+#define defaultScrollDownOnTyping 1
+#define defaultScrollDownOnActivity 0
+
+// values for compression
+// fixme change to 1?
+#define defaultCompressZLib 0
+
+// values for backspace - default is DEL
+#define backspaceDEL 0
+#define backspaceBS 1
+#define defaultBackspace backspaceDEL
+
+// values for backquote
+#define backquoteNormal 0
+#define backquoteESC 1
+#define defaultBackquote backquoteNormal
+
+int PrefsInit(void);
+uint32_t PrefsGetInt(uint32_t which, uint32_t defaultValue);
+void PrefsPutInt(uint32_t which, uint32_t value);
+
+char *PrefsGetString(uint32_t which, char *defaultValue);
+void PrefsPutString(uint32_t which, char *value);
+
+#endif
diff --git a/data/publickeys.c b/data/publickeys.c
new file mode 100644 (file)
index 0000000..dcce090
--- /dev/null
@@ -0,0 +1,389 @@
+/**********
+ * Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "publickeys.h"
+#include "recordlist.h"
+#include "rsrc/rsrc.h"
+#include "ssh/openssh/buffer.h"
+#include "ssh/openssh/bufaux.h"
+#include "ssh/openssh/key.h"
+#include "ssh/keyimport.h"
+
+
+#define PublicKeyDBName "pssh Public Keys"
+#define PublicKeyDBType 'PKey'
+static DmOpenRef PublicKeyDB = 0;
+static RecordList *PublicKeyList = NULL;
+
+/*
+  public key record format:
+  1 byte encrypted
+  2 bytes length
+  n bytes comment\0
+  4 bytes length
+  n bytes public keyblob
+  4 bytes length
+  n bytes private key\0 (base64 text, maybe with encrypted body)
+*/
+
+static Boolean ReadPublicKeyRecord(uint8_t *recordP, Boolean *encrypted, char **comment, uint8_t **pubkey, uint16_t *pubkeylen, uint8_t **privkey, uint16_t *privkeylen) PUBLICKEYS_SEGMENT;
+static queue_t *PublicKeysWithEncryption(Boolean wantEncrypted) PUBLICKEYS_SEGMENT;
+static void DrawPublicKeyRecord(MemPtr recordP, UInt16 index, RectanglePtr bounds) PUBLICKEYS_SEGMENT;
+static Boolean SavePublicKey(Boolean encrypted, char *comment, uint16_t commentlen, char *pubkey, uint16_t pubkeylen, char *privkey, uint16_t privkeylen) PUBLICKEYS_SEGMENT;
+static queue_t *PublicKeysWithEncryption(Boolean encrypted) PUBLICKEYS_SEGMENT;
+
+
+extern DmOpenRef OpenDB(UInt32 type, char *name, Boolean resDB, Boolean create);
+
+Boolean PublicKeysInit(void)
+{
+    PublicKeyDB = OpenDB(PublicKeyDBType, PublicKeyDBName, false, true);
+    if (!PublicKeyDB) return false;
+
+    PublicKeyList = 
+        RecordListNew(PublicKeyDB, PublicKeysFormID, PublicKeysFormKeyTableID, 
+                      PublicKeysFormKeyScrollbarID, DrawPublicKeyRecord);
+    if (!PublicKeyList) return false;
+
+    return true;
+}
+
+
+
+void PublicKeysFree(void)
+{
+    RecordListFree(PublicKeyList);
+    DmCloseDatabase(PublicKeyDB);
+}
+
+
+void PublicKeysUpdate(void)
+{
+    return RecordListUpdate(PublicKeyList);
+}
+
+
+Boolean PublicKeysHandleEvent(EventPtr event)
+{
+    return RecordListHandleEvent(PublicKeyList, event);
+}
+
+
+UInt16 PublicKeysSelectedIndex(void)
+{
+    return RecordListSelectedIndex(PublicKeyList);
+}
+
+
+void PublicKeysDeleteSelectedRecord(void)
+{
+    return RecordListDeleteSelectedRecord(PublicKeyList);
+}
+
+
+static Boolean ReadPublicKeyRecord(uint8_t *recordP, Boolean *encrypted, 
+                                   char **comment, 
+                                   uint8_t **pubkey, uint16_t *pubkeylen, 
+                                   uint8_t **privkey, uint16_t *privkeylen)
+{
+#define CHECK_SPACE(n) do { if (p+(n)>end) goto bad; } while (0)
+
+    uint8_t c;
+    uint16_t len;
+    uint32_t len32;
+    uint8_t *p = recordP;
+    uint8_t *end = p + MemPtrSize(p);
+    
+    CHECK_SPACE(1);
+    c = *(uint8_t *)p;
+    if (encrypted) *encrypted = (c == 1);
+    p++;
+
+    CHECK_SPACE(2);
+    len = *(uint16_t *)p;
+    p += 2;
+    CHECK_SPACE(len);
+    if (comment) *comment = p;
+    p += len;
+
+    CHECK_SPACE(4);
+    len32 = *(uint32_t *)p;
+    p += 4;
+    CHECK_SPACE(len32);
+    if (len32 == 0) goto bad;
+    if (pubkey) *pubkey = p;
+    if (pubkeylen) *pubkeylen = len32;
+    p += len32;
+
+    CHECK_SPACE(4);
+    len32 = *(uint32_t *)p;
+    p += 4;
+    CHECK_SPACE(len32);
+    if (len32 == 0) goto bad;
+    if (privkey) *privkey = p;
+    if (privkeylen) *privkeylen = len32;
+    p += len32;
+
+    // allow trailing data for forward compatibility
+
+    return true;
+
+ bad:
+    return false;
+}
+
+
+MemHandle PublicKeysQuerySelectedRecord(Boolean *encrypted, char **comment, 
+                                        uint8_t **pubkey, uint16_t *pubkeylen, 
+                                        uint8_t **privkey,uint16_t *privkeylen)
+{
+    return PublicKeysQueryIndexedRecord(RecordListSelectedIndex(PublicKeyList),
+                                        encrypted, comment, 
+                                        pubkey, pubkeylen, 
+                                        privkey, privkeylen);
+}
+
+
+MemHandle PublicKeysQueryIndexedRecord(UInt16 index, 
+                                       Boolean *encrypted, char **comment, 
+                                       uint8_t **pubkey, uint16_t *pubkeylen, 
+                                       uint8_t **privkey, uint16_t *privkeylen)
+{
+    MemHandle recordH;
+    MemPtr recordP;
+    Boolean ok;
+
+    recordH = RecordListQueryIndexedRecord(PublicKeyList, index);
+    if (!recordH) return NULL;
+
+    recordP = MemHandleLock(recordH);
+    ok = ReadPublicKeyRecord(recordP, encrypted, comment, 
+                             pubkey, pubkeylen, 
+                             privkey, privkeylen);
+    
+    if (!ok) {
+        MemHandleUnlock(recordH);
+        return NULL;
+    } else {
+        return recordH;
+    }
+}
+
+
+Key *PublicKeyForRecord(MemPtr recordP)
+{
+    uint8_t *pubkeyblob;
+    uint16_t pubkeylen;
+
+    Boolean ok = ReadPublicKeyRecord(recordP, NULL, NULL, 
+                                     &pubkeyblob, &pubkeylen, 
+                                     NULL, NULL);
+
+    if (!ok) return NULL;
+    else return key_from_blob(pubkeyblob, pubkeylen);
+}
+
+
+Key *PrivateKeyForRecord(MemPtr recordP, char *passphrase)
+{
+    uint8_t *privkeytext;
+    uint16_t privkeylen;
+
+    Boolean ok = ReadPublicKeyRecord(recordP, NULL, NULL, 
+                                     NULL, NULL, 
+                                     &privkeytext, &privkeylen);
+
+    if (!ok) return NULL;
+    return openssh_read(privkeytext, privkeylen, passphrase ? passphrase : "");
+}
+
+
+static queue_t *PublicKeysWithEncryption(Boolean wantEncrypted)
+{
+    MemHandle h;
+    MemPtr p;
+    UInt16 i;
+    Boolean encrypted;
+    UInt16 count = RecordListCount(PublicKeyList);
+    queue_t *result = queue_new();
+    
+    for (i = 0; i < count; i++) {
+        h = RecordListQueryIndexedRecord(PublicKeyList, i);
+        if (h  &&  MemHandleSize(h) >= 1) {
+            p = MemHandleLock(h);
+            encrypted = (*(uint8_t *)p) == 1;
+            if (encrypted == wantEncrypted) {
+                queue_enqueue(result, h);
+            }
+            MemHandleUnlock(h);
+        }
+    }
+    
+    return result;
+}
+
+queue_t *PhraselessPublicKeys(void)
+{
+    return PublicKeysWithEncryption(false);
+}
+
+queue_t *PhrasefulPublicKeys(void)
+{
+    return PublicKeysWithEncryption(true);
+}
+
+
+static void DrawPublicKeyRecord(MemPtr recordP, UInt16 index, 
+                                RectanglePtr bounds)
+{
+    Boolean encrypted;
+    char *comment;
+
+    if (ReadPublicKeyRecord(recordP, &encrypted, &comment, 
+                            NULL, NULL, NULL, NULL))
+    {
+        // fixme draw something for encrypted keys
+        int len;
+        int x = bounds->topLeft.x + 1;
+        int y = bounds->topLeft.y;
+
+        len = StrLen(comment);
+        WinDrawTruncChars(comment, len, x, y, 
+                          bounds->topLeft.x + bounds->extent.x - x - 1);
+        x += FntCharsWidth(comment, len);
+    }
+}
+
+
+
+// comment MAY NOT be nul-terminated
+// commentlen MUST NOT include nul char
+// pubkey MAY NOT be nul-terminated
+// pubkeylen MUST NOT include nul char
+// privkey MAY NOT be nul-terminated
+// privkeylen MUST NOT include nul char
+// NOTHING overlaps the selected record, if any
+static Boolean SavePublicKey(Boolean encrypted, 
+                             char *comment, uint16_t commentlen, 
+                             char *pubkey, uint16_t pubkeylen, 
+                             char *privkey, uint16_t privkeylen)
+{
+    Boolean result = false;
+    Buffer b;
+    MemHandle recordH;
+    MemPtr recordP;
+
+    buffer_init(&b);
+
+    // encrypted
+    buffer_put_char(&b, encrypted ? 1 : 0);
+
+    // comment\0
+    buffer_put_short(&b, commentlen + 1);
+    buffer_append(&b, comment, commentlen);
+    buffer_put_char(&b, '\0');
+
+    // public key (binary)
+    buffer_put_int(&b, pubkeylen);
+    buffer_append(&b, pubkey, pubkeylen);
+
+    // private key\0 (text)
+    buffer_put_int(&b, privkeylen + 1);
+    buffer_append(&b, privkey, privkeylen);
+    buffer_put_char(&b, '\0');
+
+
+    // write to record (might be new)
+    recordH = RecordListGetSelectedRecord(PublicKeyList, buffer_len(&b));
+    if (!recordH) goto done;
+
+    recordP = MemHandleLock(recordH);
+    DmWrite(recordP, 0, buffer_ptr(&b), buffer_len(&b));
+    MemHandleUnlock(recordH);
+    RecordListReleaseRecord(PublicKeyList, recordH, true);
+    result = true;
+
+ done: 
+    buffer_free(&b);
+    return result;
+}
+
+
+// privkey MAY NOT be nul-terminated
+// privkeylen MUST NOT include nul char
+// comment MAY NOT be nul-terminated
+// commentlen MUST NOT include nul char
+Boolean SaveImportedPublicKey(Boolean encrypted, 
+                              char *comment, uint16_t commentlen,
+                              Key *pubkey, 
+                              char *privkey, uint16_t privkeylen)
+{
+    Boolean ok = false;
+    uint8_t *pubkeybytes;
+    uint16_t pubkeylen;
+
+    key_to_blob(pubkey, &pubkeybytes, &pubkeylen);
+
+    RecordListClearSelection(PublicKeyList);
+    ok = SavePublicKey(encrypted, comment, commentlen, pubkeybytes, pubkeylen, 
+                       privkey, privkeylen);
+
+    xfree(pubkeybytes);
+    return ok;
+}
+
+
+// Mirrors PublicKeysQueryIndexedRecord()
+// comment MUST be nul-terminated
+// privkey MUST be nul-terminated
+// privkeylen MUST include nul char
+// NOTHING overlaps the selected record, if any
+Boolean WritePublicKeyRecord(Boolean encrypted, 
+                             char *comment, 
+                             char *pubkey, uint16_t pubkeylen, 
+                             char *privkey, uint16_t privkeylen)
+{
+    return SavePublicKey(encrypted, 
+                         comment, strlen(comment), // no nul char
+                         pubkey, pubkeylen, 
+                         privkey, privkeylen - 1); // ignore nul char
+}
+
+
+char *NameForPublicKey(MemHandle h)
+{
+    char *comment;
+    char *result = NULL;
+    uint8_t *p = MemHandleLock(h);
+
+    if (ReadPublicKeyRecord(p, NULL, &comment, NULL, NULL, NULL, NULL)) {
+        result = arena_strdup(comment);
+    }
+
+    MemHandleUnlock(h);
+
+    if (!result) return arena_strdup("<error>");
+    else return result;
+}
diff --git a/data/publickeys.h b/data/publickeys.h
new file mode 100644 (file)
index 0000000..fbd60f5
--- /dev/null
@@ -0,0 +1,60 @@
+/**********
+ * Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef PUBLICKEYS_H
+#define PUBLICKEYS_H
+
+#include "includes.h"
+#include "queue.h"
+#include "data/recordlist.h"
+#include "ssh/openssh/key.h"
+
+Boolean PublicKeysInit(void) PUBLICKEYS_SEGMENT;
+void PublicKeysFree(void) PUBLICKEYS_SEGMENT;
+void PublicKeysUpdate(void) PUBLICKEYS_SEGMENT;
+Boolean PublicKeysHandleEvent(EventPtr event) PUBLICKEYS_SEGMENT;
+
+UInt16 PublicKeysSelectedIndex(void) PUBLICKEYS_SEGMENT;
+void PublicKeysDeleteSelectedRecord(void) PUBLICKEYS_SEGMENT;
+MemHandle PublicKeysQuerySelectedRecord(Boolean *encrypted, char **comment, uint8_t **pubkey, uint16_t *pubkeylen, uint8_t **privkey, uint16_t *privkeylen) PUBLICKEYS_SEGMENT;
+MemHandle PublicKeysQueryIndexedRecord(UInt16 index, Boolean *encrypted, char **comment, uint8_t **pubkey, uint16_t *pubkeylen, uint8_t **privkey, uint16_t *privkeylen) PUBLICKEYS_SEGMENT;
+
+Key *PublicKeyForRecord(MemPtr recordP) PUBLICKEYS_SEGMENT;
+Key *PrivateKeyForRecord(MemPtr recordP, char *passphrase) PUBLICKEYS_SEGMENT;
+char *NameForPublicKey(MemHandle recordH) PUBLICKEYS_SEGMENT;
+queue_t *PhraselessPublicKeys(void) PUBLICKEYS_SEGMENT;
+queue_t *PhrasefulPublicKeys(void) PUBLICKEYS_SEGMENT;
+
+Boolean SaveImportedPublicKey(Boolean encrypted, 
+                              char *comment, uint16_t commentlen,
+                              Key *pubkey, 
+                              char *privkey, uint16_t privkeylen)
+     PUBLICKEYS_SEGMENT;
+Boolean WritePublicKeyRecord(Boolean encrypted, 
+                             char *comment, 
+                             char *pubkey, uint16_t pubkeylen, 
+                             char *privkey, uint16_t privkeylen)
+     PUBLICKEYS_SEGMENT;
+
+#endif
diff --git a/data/recordlist.c b/data/recordlist.c
new file mode 100644 (file)
index 0000000..db44d9c
--- /dev/null
@@ -0,0 +1,446 @@
+/**********
+ * Copyright (c) 2003-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "formutils.h"
+#include "recordlist.h"
+
+
+struct RecordList {
+    DmOpenRef db;
+
+    UInt16 formID;
+    UInt16 tableID;
+    UInt16 scrollbarID;
+
+    RecordListDrawProc draw;
+
+    UInt16 topVisibleIndex;
+    UInt16 selectedIndex;
+};
+
+static RecordList **recordListList = NULL;
+static int recordListCount = 0;
+static int recordListAllocated = 0;
+
+static RecordList *RecordListForTable(TablePtr table) RECORDLIST_SEGMENT;
+static void AddRecordList(RecordList *rl) RECORDLIST_SEGMENT;
+static void RemoveRecordList(RecordList *rl) RECORDLIST_SEGMENT;
+static Int16 IndexToRow(RecordList *rl, UInt16 index) RECORDLIST_SEGMENT;
+static Int16 TotalRowCount(TablePtr table) RECORDLIST_SEGMENT;
+static Int16 VisibleRowCount(TablePtr table) RECORDLIST_SEGMENT;
+static void RecordListRepopulate(RecordList *rl) RECORDLIST_SEGMENT;
+static void RecordListDraw(RecordList *rl) RECORDLIST_SEGMENT;
+static void RecordListDrawRecord(void *t, Int16 row, Int16 column, RectanglePtr bounds) RECORDLIST_SEGMENT;
+
+static RecordList *RecordListForTable(TablePtr table)
+{
+    int i;
+    UInt16 tableIndex;
+    UInt16 tableID;
+    UInt16 formID;
+
+    formID = FrmGetActiveFormID();
+    tableIndex = FrmGetObjectIndexFromPtr(FrmGetActiveForm(), table);
+    tableID = FrmGetObjectId(FrmGetActiveForm(), tableIndex);
+
+    for (i = 0; i < recordListCount; i++) {
+        RecordList *r = recordListList[i];
+        if (r->formID == formID  &&  r->tableID == tableID) return r;
+    }
+
+    return NULL;
+}
+
+
+static void AddRecordList(RecordList *rl)
+{
+    if (recordListCount == recordListAllocated) {
+        RecordList **newList;
+        int i;
+
+        recordListAllocated += recordListAllocated + 1;
+        newList = MemPtrNew(recordListAllocated * sizeof(RecordList *));
+        for (i = 0; i < recordListCount; i++) {
+            newList[i] = recordListList[i];
+        }
+        if (recordListList) MemPtrFree(recordListList);
+        recordListList = newList;
+    }
+
+    recordListList[recordListCount++] = rl;
+}
+
+
+static void RemoveRecordList(RecordList *rl)
+{
+    int i;
+    
+    for (i = 0; i < recordListCount; i++) {
+        if (recordListList[i] == rl) {
+            recordListList[i] = recordListList[--recordListCount];
+            return;
+        }
+    }
+}
+
+
+// create and populate
+RecordList *RecordListNew(DmOpenRef newDB, UInt16 newFormID, UInt16 newTableID, UInt16 newScrollbarID, RecordListDrawProc newDraw)
+{
+    RecordList *rl = MemPtrNew(sizeof(RecordList));
+    rl->db = newDB;
+    rl->formID = newFormID;
+    rl->tableID = newTableID;
+    rl->scrollbarID = newScrollbarID;
+    rl->draw = newDraw;
+
+    // fixme read some preferences and restore last selection and visible
+    rl->topVisibleIndex = 0;
+    rl->selectedIndex = noRecord;
+
+    AddRecordList(rl);
+    return rl;
+}
+
+
+void RecordListFree(RecordList *rl)
+{
+    // fixme write some preferences here
+    RemoveRecordList(rl);
+    MemPtrFree(rl);
+}
+
+
+UInt16 RecordListCount(RecordList *rl)
+{
+    return DmNumRecords(rl->db);
+}
+
+
+static Int16 IndexToRow(RecordList *rl, UInt16 index)
+{
+    if (index != noRecord  &&  index >= rl->topVisibleIndex  &&  
+        index < DmNumRecords(rl->db)) 
+    {
+        return index - rl->topVisibleIndex;
+    } else {
+        return -1;
+    }
+}
+
+
+static Int16 TotalRowCount(TablePtr table)
+{
+    return TblGetNumberOfRows(table);
+}
+
+
+static Int16 VisibleRowCount(TablePtr table)
+{
+    Coord rowHeight;
+    RectangleType bounds;
+    TblGetBounds(table, &bounds);
+    rowHeight = TblGetRowHeight(table, 0);
+    return MIN(bounds.extent.y / rowHeight, TotalRowCount(table));
+}
+
+
+void RecordListUpdate(RecordList *rl)
+{
+    RecordListRepopulate(rl);
+    FrmUpdateForm(rl->formID, rl->tableID);
+}
+
+
+static void RecordListRepopulate(RecordList *rl)
+{
+    TablePtr table;
+    int totalRows, row, visibleRows, totalRecords;
+    UInt16 index;
+
+    if (FrmGetActiveFormID() != rl->formID) return;
+
+    table = PrvGetObjectByID(rl->tableID);
+    totalRecords = RecordListCount(rl);
+    totalRows = TotalRowCount(table);
+    visibleRows = VisibleRowCount(table);
+
+    if (rl->topVisibleIndex + visibleRows > totalRecords) {
+        // top visible leaves a gap at the bottom - move it up
+        rl->topVisibleIndex = MAX(totalRecords - visibleRows, 0);
+    }
+
+    index = rl->topVisibleIndex;
+    
+    for (row = 0; row < visibleRows; row++) {
+        MemHandle 
+            recordH = DmQueryNextInCategory(rl->db, &index, dmAllCategories);
+        if (!recordH) {
+            // no record for this row or any further rows
+            break;
+        } else {
+            // install record into row
+            // UInt32 uniqueID; 
+            // DmRecordInfo(ConnectionDB, index, NULL, &uniqueID, NULL);
+
+            TblSetItemStyle(table, row, 0, customTableItem);
+
+            TblSetRowUsable(table, row, true);
+            TblSetRowID(table, row, index);
+            // TblSetRowData(table, row, uniqueID);
+            TblMarkRowInvalid(table, row);
+
+            index++;
+        }
+    }
+
+    // mark the rest of the table unusable, if any
+    for ( ; row < totalRows; row++) {
+        TblSetRowUsable(table, row, false);
+        TblSetRowID(table, row, noRecord);
+        TblMarkRowInvalid(table, row);
+    }
+
+    TblSetCustomDrawProcedure(table, 0, RecordListDrawRecord);
+    TblSetColumnUsable(table, 0, true);
+
+    // update scoll bar
+    {
+        ScrollBarPtr scl = PrvGetObjectByID(rl->scrollbarID);
+        Int16 value, min, max, pageSize;
+
+        min = 0;
+        pageSize = visibleRows - 1; // page-scroll overlaps by 1
+        if (totalRecords > pageSize) {
+            max = totalRecords - pageSize - 1;
+            value = rl->topVisibleIndex;
+        } else {
+            // everything fits at once with no scrolling
+            value = 0;
+            max = 0;
+            pageSize = 0;
+        }
+        SclSetScrollBar(scl, value, min, max, pageSize);
+    }
+}
+
+
+static void RecordListDraw(RecordList *rl)
+{
+    TablePtr table;
+    int row, visibleRows;
+
+    if (FrmGetActiveFormID() != rl->formID) return;
+
+    table = PrvGetObjectByID(rl->tableID);
+    visibleRows = VisibleRowCount(table);
+
+    TblDrawTable(table); // draws with NO selection!
+    row = IndexToRow(rl, rl->selectedIndex);
+    if (row >= 0  &&  row < visibleRows) {
+        // fixme use TblGetLastUsableRow?
+        TblUnhighlightSelection(table);
+        TblSelectItem(table, row, 0);
+    }
+}
+
+
+UInt16 RecordListSelectedIndex(RecordList *rl)
+{
+    return rl->selectedIndex;
+}
+
+
+void RecordListSetSelectedIndex(RecordList *rl, UInt16 index)
+{
+    rl->selectedIndex = index;
+    // fixme scroll to selectedIndex if it's not in view
+    RecordListUpdate(rl);
+}
+
+
+void RecordListClearSelection(RecordList *rl)
+{
+    rl->selectedIndex = noRecord;
+    RecordListUpdate(rl);
+}
+
+
+MemHandle RecordListQuerySelectedRecord(RecordList *rl)
+{
+    UInt16 index = RecordListSelectedIndex(rl);
+    return RecordListQueryIndexedRecord(rl, index);
+}
+
+
+MemHandle RecordListQueryIndexedRecord(RecordList *rl, UInt16 index)
+{
+    if (index == noRecord) return NULL;
+    else return DmQueryRecord(rl->db, index);
+}
+
+
+MemHandle RecordListGetIndexedRecord(RecordList *rl, UInt16 index)
+{
+    if (index == noRecord) return NULL;
+    else return DmGetRecord(rl->db, index);
+}
+
+
+// if createWithSize is ZERO, then return the record if found or NULL.
+// if createWithSize is NON-ZERO, then return the RESIZED record or a NEW one.
+// If a new record is created, the selection is CHANGED to that record.
+// The returned record must be released with RecordListReleaseRecord.
+MemHandle RecordListGetSelectedRecord(RecordList *rl, UInt32 createWithSize)
+{
+    UInt16 index = RecordListSelectedIndex(rl);
+
+    if (index != noRecord) {
+        if (createWithSize == 0) {
+            // Selection exists and no resize requested.
+            return DmGetRecord(rl->db, index);
+        } else {
+            // Selection exists and resize requested.
+            return DmResizeRecord(rl->db, index, createWithSize);
+        }
+    }
+    else {
+        if (createWithSize == 0) {
+            // No selection and no creation requested. 
+            return NULL;
+        } else {
+            // No selection but record creation requested.
+            MemHandle recordH;
+            index = DmNumRecords(rl->db);
+            recordH = DmNewRecord(rl->db, &index, createWithSize);
+            if (recordH) {
+                // zero it out
+                DmSet(MemHandleLock(recordH), 0, createWithSize, 0);
+                MemHandleUnlock(recordH);
+                RecordListSetSelectedIndex(rl, index);
+            }
+            return recordH;
+        }
+    }
+}
+
+
+void RecordListReleaseRecord(RecordList *rl, MemHandle recordH, Boolean dirty)
+{
+    DmOpenRef db = rl->db;
+    UInt16 index = DmSearchRecord(recordH, &db);
+    // fixme errors
+    DmReleaseRecord(db, index, dirty);
+    if (dirty) RecordListUpdate(rl);
+}
+
+
+void RecordListDeleteSelectedRecord(RecordList *rl)
+{
+    RecordListDeleteIndexedRecord(rl, rl->selectedIndex);
+}
+
+
+void RecordListDeleteIndexedRecord(RecordList *rl, UInt16 index)
+{
+    if (index != noRecord) {
+        DmRemoveRecord(rl->db, index);
+        if (index == rl->selectedIndex) {
+            rl->selectedIndex = noRecord;
+        }
+        RecordListUpdate(rl);
+    }
+}
+
+
+static void RecordListDrawRecord(void *t, Int16 row, Int16 column, 
+                                 RectanglePtr bounds)
+{
+    TablePtr table = (TablePtr)t;
+    UInt16 index;
+    MemHandle recordH;
+
+    RecordList *rl = RecordListForTable(table);
+
+    index = TblGetRowID(table, row);
+    if (index == noRecord) return;
+
+    recordH = DmQueryRecord(rl->db, index);
+    if (recordH) {
+        WinPushDrawState();
+
+        rl->draw(MemHandleLock(recordH), index, bounds);
+
+        WinPopDrawState();
+        MemHandleUnlock(recordH); 
+    }
+}
+
+
+Boolean RecordListHandleEvent(RecordList *rl, EventPtr event)
+{
+    switch (event->eType) {
+    case winEnterEvent:
+        if (FrmGetFormId((FormPtr)event->data.winEnter.enterWindow) == rl->formID) {
+            // fixme could record dirty indicator
+            FrmUpdateForm(rl->formID, rl->tableID);
+        }
+        break;
+
+    case frmUpdateEvent:
+        if (event->data.frmUpdate.updateCode == rl->tableID) {
+            RecordListRepopulate(rl);
+            RecordListDraw(rl);
+        }
+        return true;  // default handler erases form
+
+    case tblSelectEvent:
+        if (RecordListForTable(event->data.tblSelect.pTable) == rl) {
+            RecordListSetSelectedIndex(rl, event->data.tblSelect.row + 
+                                       rl->topVisibleIndex);
+        }
+        break;
+
+    case tblExitEvent:
+        if (RecordListForTable(event->data.tblExit.pTable) == rl) {
+            RecordListClearSelection(rl);
+        }
+        break;
+
+    case sclRepeatEvent:
+        if (event->data.sclRepeat.scrollBarID == rl->scrollbarID) {
+            Int16 delta = (event->data.sclRepeat.newValue - 
+                           event->data.sclRepeat.value);
+            rl->topVisibleIndex += delta;
+            RecordListUpdate(rl);
+        }
+        break;
+
+    default: 
+        break;
+    }
+
+    return false;
+}
diff --git a/data/recordlist.h b/data/recordlist.h
new file mode 100644 (file)
index 0000000..61c6834
--- /dev/null
@@ -0,0 +1,63 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// recordlist.h
+// A database, a table, and a scroll bar.
+
+
+#ifndef RECORDLIST_H
+#define RECORDLIST_H
+
+#include "includes.h"
+
+#define noRecord ((UInt16)0xffff)
+
+typedef struct RecordList RecordList;
+
+typedef void (*RecordListDrawProc)(MemPtr record, UInt16 index, 
+                                   RectanglePtr bounds);
+
+RecordList *RecordListNew(DmOpenRef newDB, UInt16 newFormID, 
+                          UInt16 newTableID, UInt16 newScrollbarID, 
+                          RecordListDrawProc newDraw) RECORDLIST_SEGMENT;
+void RecordListFree(RecordList *rl) RECORDLIST_SEGMENT;
+void RecordListUpdate(RecordList *rl) RECORDLIST_SEGMENT;
+UInt16 RecordListCount(RecordList *rl) RECORDLIST_SEGMENT;
+
+UInt16 RecordListSelectedIndex(RecordList *rl) RECORDLIST_SEGMENT;
+void RecordListSetSelectedIndex(RecordList *rl, UInt16 index) RECORDLIST_SEGMENT;
+void RecordListClearSelection(RecordList *rl) RECORDLIST_SEGMENT;
+
+MemHandle RecordListQuerySelectedRecord(RecordList *rl) RECORDLIST_SEGMENT;
+MemHandle RecordListGetSelectedRecord(RecordList *rl, UInt32 createWithSize) RECORDLIST_SEGMENT;
+void RecordListReleaseRecord(RecordList *rl, MemHandle recordH, Boolean dirty) RECORDLIST_SEGMENT;
+void RecordListDeleteSelectedRecord(RecordList *rl) RECORDLIST_SEGMENT;
+
+MemHandle RecordListQueryIndexedRecord(RecordList *rl, UInt16 index) RECORDLIST_SEGMENT;
+MemHandle RecordListGetIndexedRecord(RecordList *rl, UInt16 index) RECORDLIST_SEGMENT;
+void RecordListDeleteIndexedRecord(RecordList *rl, UInt16 index) RECORDLIST_SEGMENT;
+
+Boolean RecordListHandleEvent(RecordList *rl, EventPtr event) RECORDLIST_SEGMENT;
+
+#endif
diff --git a/forms/DIA.c b/forms/DIA.c
new file mode 100644 (file)
index 0000000..2ed6f15
--- /dev/null
@@ -0,0 +1,770 @@
+/* $Id: DIA.c,v 1.1 2005/05/15 09:06:03 admin Exp $ */
+/*******************************************************************************
+    Copyright (c) 2004, Alexander R. Pruss
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification,
+    are permitted provided that the following conditions are met:
+
+        Redistributions of source code must retain the above copyright notice, this
+        list of conditions and the following disclaimer.
+
+        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.
+
+        Neither the name of the PalmResize Project nor the names of its
+        contributors may be used to endorse or promote products derived from this
+        software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER 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.
+*******************************************************************************/
+
+
+#include "resize.h"
+
+#include "DIA.h"
+
+#ifdef SUPPORT_DIA_HANDERA
+#include <Vga.h>
+#include <Silk.h>
+#endif
+
+#ifdef SUPPORT_DIA_SONY
+#include "SonySystemResources.h"
+#include "SonySystemFtr.h"
+#include "SonySilkLib.h"
+
+#ifndef vskResizeVertically
+#  define vskResizeVertically     1
+#endif
+#ifndef vskResizeHorizontally
+#  define vskResizeHorizontally   2
+#endif
+#endif
+
+#define COORDSYS_STACK_LEN 10
+
+
+static DIAHardwareType  hardware = DIA_HARDWARE_NONE;
+static UInt32           displayChangeNotification = 0;
+static Boolean          haveNotification;
+static UInt16           card;
+static LocalID          db;
+static Boolean          palmHiRes;
+static Boolean          sony1AllowResize = false;
+static UInt16           coordSysStack[ 10 ];
+static UInt16           coordSysStackPtr = 0;
+#ifdef SUPPORT_DIA_SONY
+static UInt16           sonyRefNum;
+#endif
+#ifdef SUPPORT_DIA_HANDERA
+static VgaRotateModeType savedHanderaRotation;
+static VgaScreenModeType savedHanderaScreenMode;
+#endif
+
+
+
+#ifdef SUPPORT_DIA_HANDERA
+static DIAHardwareType InitializeHandera( void )
+{
+    UInt32 version;
+    if ( _TRGSilkFeaturePresent( &version ) ) {
+        VgaRotateModeType rotation;
+        VgaScreenModeType screenMode;
+
+        VgaGetScreenMode( &screenMode, &rotation );
+
+        savedHanderaScreenMode = screenMode;
+        savedHanderaRotation   = rotation;
+
+        if ( screenMode != screenMode1To1 )
+            VgaSetScreenMode( screenMode1To1, rotation );
+
+        return DIA_HARDWARE_HANDERA;
+    }
+    else {
+        return DIA_HARDWARE_NONE;
+    }
+}
+#else
+# define InitializeHandera() DIA_HARDWARE_NONE
+#endif
+
+
+
+#ifdef SUPPORT_DIA_SONY
+static DIAHardwareType InitializeSony( void )
+{
+    Err    err;
+    UInt32 version;
+
+    err = SysLibFind( sonySysLibNameSilk, &sonyRefNum );
+    if ( err == sysErrLibNotFound ) {
+        err = SysLibLoad( 'libr', sonySysFileCSilkLib, &sonyRefNum );
+    }
+    if ( err != errNone )
+        return DIA_HARDWARE_NONE;
+    if ( errNone == FtrGet( sonySysFtrCreator, sonySysFtrNumVskVersion, 
+                        &version ) ) {
+        /* Version 2 and up */
+        err = VskOpen( sonyRefNum );
+        if ( errNone == err )
+            return DIA_HARDWARE_SONY2;
+    }
+#if 0
+    else {
+        /* Version 1 and up */
+        err = SilkLibOpen( sonyRefNum );
+        if ( errNone == err ) {
+            /* Make sure we are in a Hi-Res mode */
+            UInt32 width;
+            UInt32 height;
+            UInt16 sonyHiResRefNum;
+
+            err = SysLibFind( sonySysLibNameHR, &sonyHiResRefNum );
+            if ( err == sysErrLibNotFound )
+                err = SysLibLoad( 'libr', sonySysFileCHRLib, &sonyHiResRefNum );
+
+            if ( err == errNone ) {
+
+                err = HROpen( sonyHiResRefNum );
+                HRWinScreenMode( sonyHiResRefNum, winScreenModeGet, &width,
+                     &height, NULL, NULL );
+
+                if ( width < hrWidth ) {
+
+                    width  = hrWidth;
+                    height = hrHeight;
+                    if ( errNone != HRWinScreenMode( sonyHiResRefNum,
+                                        winScreenModeSet,
+                                        &width, &height, NULL, NULL ) ) {
+                        HRClose( sonyHiResRefNum );
+                        return DIA_HARDWARE_NONE;
+                    }
+                }
+                HRClose( sonyHiResRefNum );
+            }
+            else
+                return DIA_HARDWARE_NONE;
+        }
+
+        SilkLibDisableResize( sonyRefNum );
+
+        sony1AllowResize = false;
+
+        return DIA_HARDWARE_SONY1;
+    }
+#endif
+    return DIA_HARDWARE_NONE;
+}
+#else
+# define InitializeSony() DIA_HARDWARE_NONE
+#endif
+
+
+
+#ifdef HAVE_PALM_DIA_SDK
+static DIAHardwareType InitializePalm( void )
+{
+    UInt32 version;
+    Err    err;
+    err = FtrGet( pinCreator, pinFtrAPIVersion, &version );
+    if ( err != errNone )
+        return DIA_HARDWARE_NONE;
+    if ( pinAPIVersion1_1 <= version )
+        return DIA_HARDWARE_PALM11;
+    else if ( pinAPIVersion1_0 <= version )
+        return DIA_HARDWARE_PALM10;
+    else
+        return DIA_HARDWARE_NONE;
+}
+#else
+# define InitializePalm() DIA_HARDWARE_NONE
+#endif
+
+
+
+/* Check if this is an unknown device with non-standard screen size
+   so we can make proper use of the screen size. */
+static DIAHardwareType InitializeUnknown( void )
+{
+    Coord extentX;
+    Coord extentY;
+    PushCoordinateSystemToStandard();
+    WinGetDisplayExtent( &extentX, &extentY );
+    PopCoordinateSystem();
+    if ( extentX != STD_EXTENT_X || extentY != STD_EXTENT_Y )
+        return DIA_HARDWARE_UNKNOWN;
+    else
+        return DIA_HARDWARE_NONE;
+}
+
+
+
+static void RegisterNotification( void )
+{
+    Err      err;
+
+    haveNotification = false;
+    switch ( hardware ) {
+#ifdef SUPPORT_DIA_SONY
+        case DIA_HARDWARE_SONY1:
+        case DIA_HARDWARE_SONY2:
+            displayChangeNotification = sysNotifyDisplayChangeEvent;
+            break;
+#endif
+#ifdef SUPPORT_DIA_HANDERA
+        case DIA_HARDWARE_HANDERA:
+            displayChangeNotification = trgNotifySilkEvent;
+            break;
+#endif
+#ifdef HAVE_PALM_DIA_SDK
+        case DIA_HARDWARE_PALM10:
+        case DIA_HARDWARE_PALM11:
+            displayChangeNotification = sysNotifyDisplayResizedEvent;
+            break;
+#endif
+        default:
+            return;
+    }
+    err = SysCurAppDatabase( &card, &db );
+    if ( err != errNone )
+        return;
+    err = SysNotifyRegister( card, db, displayChangeNotification, NULL,
+        sysNotifyNormalPriority, 0 );
+    haveNotification = ( err == errNone );
+}
+
+
+
+static void UnregisterNotification( void )
+{
+    if ( haveNotification ) {
+        SysNotifyUnregister( card, db, displayChangeNotification,
+            sysNotifyNormalPriority );
+        haveNotification = false;
+    }
+}
+
+
+
+DIAHardwareType InitializeDIA( void )
+{
+    Err    err;
+    UInt32 version;
+
+    err       = FtrGet( sysFtrCreator, sysFtrNumWinVersion, &version );
+
+    palmHiRes = ( err == errNone && 4 <= version );
+
+    hardware = InitializeHandera();
+    if ( hardware == DIA_HARDWARE_NONE )
+        hardware = InitializePalm();
+    if ( hardware == DIA_HARDWARE_NONE )
+        hardware = InitializeSony();
+    if ( hardware == DIA_HARDWARE_NONE )
+        hardware = InitializeUnknown();
+    RegisterNotification();
+
+    return hardware;
+}
+
+
+
+void TerminateDIA( void )
+{
+    UnregisterNotification();
+    if ( GetDIAState() == DIA_STATE_NO_STATUS_BAR )
+        SetDIAState( DIA_STATE_MIN );
+    switch ( hardware ) {
+#ifdef SUPPORT_DIA_SONY
+        case DIA_HARDWARE_SONY1:
+            SilkLibClose( sonyRefNum );
+            break;
+        case DIA_HARDWARE_SONY2:
+            VskClose( sonyRefNum );
+            break;
+#endif
+#ifdef SUPPORT_DIA_HANDERA
+        case DIA_HARDWARE_HANDERA: {
+            VgaRotateModeType rotation;
+            VgaScreenModeType screenMode;
+
+            VgaGetScreenMode( &screenMode, &rotation );
+
+            if ( screenMode != savedHanderaScreenMode ||
+                 savedHanderaRotation != rotation ) {
+                VgaSetScreenMode( savedHanderaScreenMode,
+                    savedHanderaRotation );
+            }
+        }
+#endif
+        default:
+            break;
+    }
+    hardware = DIA_HARDWARE_NONE;
+}
+
+
+
+
+void SetDIAState( DIAStateType state )
+{
+    DIAStateType oldState = GetDIAState();
+    if ( DIA_HARDWARE_HANDERA == hardware && oldState == state )
+        return;
+
+    switch ( hardware ) {
+#ifdef SUPPORT_DIA_SONY
+        case DIA_HARDWARE_SONY1: {
+            Boolean oldAllow;
+
+            oldAllow = sony1AllowResize;
+
+            if ( ! oldAllow )
+                SetDIAAllowResize( true );
+
+            switch ( state ) {
+                case DIA_STATE_MAX:
+                    SilkLibResizeDispWin( sonyRefNum, silkResizeNormal );
+                    break;
+                case DIA_STATE_MIN:
+                    SilkLibResizeDispWin( sonyRefNum, silkResizeToStatus );
+                    break;
+                case DIA_STATE_NO_STATUS_BAR:
+                    SilkLibResizeDispWin( sonyRefNum, silkResizeMax );
+                    break;
+                default:
+                    break;
+            }
+            break;
+
+            if ( ! oldAllow )
+                SetDIAAllowResize( false );
+        }
+
+        case DIA_HARDWARE_SONY2: {
+            Boolean oldAllow;
+            UInt16  allowState;
+
+            if ( errNone == VskGetState( sonyRefNum, vskStateEnable,
+                               &allowState ) )
+                oldAllow = ( allowState != 0 );
+            else
+                oldAllow = false;
+
+            if ( ! oldAllow ) {
+                SetDIAAllowResize( true );
+            }
+
+            switch ( state ) {
+                case DIA_STATE_MAX:
+                    VskSetState( sonyRefNum, vskStateResize, vskResizeMax );
+                    break;
+                case DIA_STATE_MIN:
+                    VskSetState( sonyRefNum, vskStateResize, vskResizeMin );
+                    break;
+                case DIA_STATE_NO_STATUS_BAR:
+                    VskSetState( sonyRefNum, vskStateResize, vskResizeNone );
+                    break;
+                default:
+                    break;
+            }
+            break;
+
+            if ( ! oldAllow )
+                SetDIAAllowResize( false );
+        }
+#endif
+#ifdef SUPPORT_DIA_HANDERA
+        case DIA_HARDWARE_HANDERA:
+            switch ( state ) {
+                case DIA_STATE_MAX:
+                    SilkMaximizeWindow();
+                    break;
+                case DIA_STATE_MIN:
+                case DIA_STATE_NO_STATUS_BAR:
+                    SilkMinimizeWindow();
+                    break;
+                default:
+                    break;
+            }
+            break;
+#endif
+#ifdef HAVE_PALM_DIA_SDK
+        case DIA_HARDWARE_PALM10:
+        case DIA_HARDWARE_PALM11:
+            switch ( state ) {
+                case DIA_STATE_MAX:
+                    PINSetInputAreaState( pinInputAreaOpen );
+                    break;
+                case DIA_STATE_MIN:
+                    PINSetInputAreaState( pinInputAreaClosed );
+                    StatShow();
+                    break;
+                case DIA_STATE_NO_STATUS_BAR:
+                    PINSetInputAreaState( pinInputAreaClosed );
+                    StatHide();
+                    break;
+                default:
+                    break;
+            }
+            break;
+#endif
+        default:
+            break;
+    }
+}
+
+
+
+DIAStateType GetDIAState( void )
+{
+    switch ( hardware ) {
+#ifdef SUPPORT_DIA_SONY
+        case DIA_HARDWARE_SONY1: {
+            Coord extentY;
+            PushCoordinateSystemToStandard();
+            WinGetDisplayExtent( NULL, &extentY );
+            PopCoordinateSystem();
+            if ( 240 <= extentY )
+                return DIA_STATE_NO_STATUS_BAR;
+            else if ( 225 <= extentY )
+                return DIA_STATE_MIN;
+            else
+                return DIA_STATE_MAX;
+            break;
+        }
+        case DIA_HARDWARE_SONY2: {
+            UInt16 state;
+            Err    err;
+            err = VskGetState( sonyRefNum, vskStateResize, &state );
+            if ( err != errNone )
+                return DIA_STATE_UNDEFINED;
+            switch ( state ) {
+                case vskResizeMax:
+                    return DIA_STATE_MAX;
+                case vskResizeMin:
+                    return DIA_STATE_MIN;
+                case vskResizeNone:
+                    return DIA_STATE_NO_STATUS_BAR;
+                default:
+                    return DIA_STATE_UNDEFINED;
+            }
+        }
+#endif
+#ifdef SUPPORT_DIA_HANDERA
+        case DIA_HARDWARE_HANDERA:
+            if ( SilkWindowMaximized() )
+                return DIA_STATE_MAX;
+            else
+                return DIA_STATE_MIN;
+#endif
+#ifdef HAVE_PALM_DIA_SDK
+        case DIA_HARDWARE_PALM10:
+        case DIA_HARDWARE_PALM11:
+            switch ( PINGetInputAreaState() ) {
+                case pinInputAreaOpen:
+                    return DIA_STATE_MAX;
+                case pinInputAreaClosed:
+                case pinInputAreaNone: {
+                    Err    err;
+                    UInt32 value;
+
+                    err = StatGetAttribute( statAttrBarVisible, &value );
+
+                    if ( err != errNone || value != 0 )
+                        return DIA_STATE_MIN;
+                    else
+                        return DIA_STATE_NO_STATUS_BAR;
+                }
+                default:
+                    return DIA_STATE_UNDEFINED;
+            }
+#endif
+        default:
+            return DIA_STATE_MAX;
+    }
+}
+
+
+
+void SetDIAAllowResize( Boolean allow )
+{
+    switch ( hardware ) {
+#ifdef SUPPORT_DIA_SONY
+        case DIA_HARDWARE_SONY2:
+            if ( allow ) {
+                /* If available, enable horizontal resize */
+                if ( 0x03 <= VskGetAPIVersion( sonyRefNum ) )
+                    VskSetState( sonyRefNum, vskStateEnable,
+                        vskResizeHorizontally );
+                /* Enable vertical resize */
+                VskSetState( sonyRefNum, vskStateEnable,
+                    vskResizeVertically );
+            }
+            else {
+                VskSetState( sonyRefNum, vskStateEnable, 0 );
+            }
+            break;
+        case DIA_HARDWARE_SONY1:
+            if ( allow )
+                SilkLibEnableResize( sonyRefNum );
+            else
+                SilkLibDisableResize( sonyRefNum );
+
+            sony1AllowResize = allow;
+
+            break;
+#endif
+#ifdef HAVE_PALM_DIA_SDK
+        case DIA_HARDWARE_PALM11:
+        case DIA_HARDWARE_PALM10:
+            PINSetInputTriggerState( allow ? pinInputTriggerEnabled :
+                                                 pinInputTriggerDisabled );
+            SysSetOrientationTriggerState( allow ?
+                sysOrientationTriggerEnabled : sysOrientationTriggerDisabled );
+            break;
+#endif
+        /* Note: On Handera, resizing is always enabled */
+        default:
+            break;
+    }
+}
+
+
+
+
+static Boolean MatchLastExtents( void )
+{
+    static Coord lastX;
+    static Coord lastY;
+    Coord        extentX;
+    Coord        extentY;
+
+    extentX = lastX;
+    extentY = lastY;
+
+    PushCoordinateSystemToStandard();
+
+    WinGetDisplayExtent( &lastX, &lastY );
+
+    PopCoordinateSystem();
+
+    return extentX == lastX && extentY == lastY;
+}
+
+
+
+
+Boolean HandleResizeNotification( UInt32 notificationType )
+{
+    switch ( notificationType ) {
+#ifdef SUPPORT_DIA_SONY
+        case sysNotifyDisplayChangeEvent:
+#endif
+#ifdef HAVE_PALM_DIA_SDK
+        case sysNotifyDisplayResizedEvent:
+#endif
+#ifdef SUPPORT_DIA_HANDERA
+        case trgNotifySilkEvent:
+#endif
+        {
+            EventType e;
+
+            if ( ! MatchLastExtents() ) {
+                SetHaveWinDisplayChangedEvent( true );
+                if ( hardware != DIA_HARDWARE_PALM11 ) {
+                    MemSet( &e, sizeof(EventType), 0 );
+                    e.eType = winDisplayChangedEvent;
+                    EvtAddUniqueEventToQueue( &e, 0, true );
+                }
+            }
+            return true;
+        }    
+        default:
+            return false;
+    }
+}
+
+
+
+void SetCustomDIAPolicy( UInt16 formID )
+{
+#ifdef HAVE_PALM_DIA_SDK
+       if ( hardware == DIA_HARDWARE_PALM10 || hardware == DIA_HARDWARE_PALM11 ) {
+           FormType* formPtr;
+        formPtr = FrmGetFormPtr( formID );
+        if ( formPtr != NULL ) {
+            FrmSetDIAPolicyAttr( formPtr, frmDIAPolicyCustom );
+        }
+    }
+#endif
+}
+
+
+
+DIAHardwareType GetDIAHardware( void )
+{
+    return hardware;
+}
+
+
+
+void SetDIAConstraints( WinHandle winH, Boolean big, Boolean allowBig )
+{
+#ifdef HAVE_PALM_DIA_SDK
+       if ( hardware == DIA_HARDWARE_PALM10 || hardware == DIA_HARDWARE_PALM11 ) {
+           PushCoordinateSystemToStandard();
+
+        WinSetConstraintsSize( winH,
+            STD_EXTENT_Y,
+            big ? MAX_EXTENT_Y : STD_EXTENT_Y,
+            allowBig ? MAX_EXTENT_Y : STD_EXTENT_Y,
+            STD_EXTENT_X,
+            big ? MAX_EXTENT_X : STD_EXTENT_X,
+            allowBig ? MAX_EXTENT_X : STD_EXTENT_X );
+
+        PopCoordinateSystem();
+    }
+#endif
+}
+
+
+
+/* Check which DIA state covers more screen space */
+Int16 CompareDIAState( DIAStateType x, DIAStateType y )
+{
+    if ( y == DIA_STATE_UNDEFINED )
+        y = DIA_STATE_MAX;
+    if ( x == DIA_STATE_UNDEFINED )
+        x = DIA_STATE_MAX;
+    if ( x == y )
+        return 0;
+    switch ( x ) {
+        case DIA_STATE_MIN:
+            return y == DIA_STATE_NO_STATUS_BAR ? 1 : -1;
+        case DIA_STATE_NO_STATUS_BAR:
+            return -1;
+        case DIA_STATE_MAX:
+        default:
+            return 1;
+    }
+}
+
+
+
+static UInt16 SafeWinSetCoordinateSystem( UInt16 coordSys )
+{
+    if ( ! palmHiRes || NULL == WinGetDrawWindow() )
+        return kCoordinatesStandard;
+    else
+        return WinSetCoordinateSystem( coordSys );
+}
+
+
+
+void PushCoordinateSystemToStandard( void )
+{
+    coordSysStack[ coordSysStackPtr++ ] =
+        SafeWinSetCoordinateSystem( kCoordinatesStandard );
+}
+
+
+
+
+void PopCoordinateSystem( void )
+{
+    SafeWinSetCoordinateSystem( coordSysStack[ --coordSysStackPtr ] );
+}
+
+
+
+void GetHiddenStatusBarArea( RectangleType* area )
+{
+    MemSet( area, sizeof( RectangleType ), 0 );
+
+    if ( DIA_STATE_NO_STATUS_BAR != GetDIAState() ) {
+        return;
+    }
+
+    switch ( hardware ) {
+        case DIA_HARDWARE_SONY2:
+        case DIA_HARDWARE_SONY1:
+        case DIA_HARDWARE_PALM11:
+        case DIA_HARDWARE_PALM10: {
+            Coord extentX;
+            Coord extentY;
+
+            WinGetDisplayExtent( &extentX, &extentY );
+            switch ( extentX ) {
+                case 160:  /* 160 x 240 */
+                    area->topLeft.x = 0;
+                    area->topLeft.y = 225;
+                    area->extent.x  = 160;
+                    area->extent.y  = 240 - 225;
+                    break;
+                case 240: /* 240 x 160 */
+                    area->topLeft.x = 225;
+                    area->topLeft.y = 0;
+                    area->extent.x  = 240 - 225;
+                    area->extent.y  = 160;
+                    break;
+                case 320: /* 320 x 480 */
+                    area->topLeft.x = 0;
+                    area->topLeft.y = 450;
+                    area->extent.x  = 320;
+                    area->extent.y  = 480 - 450;
+                    break;
+                case 480: /* 480 x 320 */
+                    area->topLeft.x = 450;
+                    area->topLeft.y = 0;
+                    area->extent.x  = 480 - 450;
+                    area->extent.y  = 320;
+                    break;
+                default:
+                    break;
+            }
+            break;
+        }
+        default:
+            break;
+    }
+}
+
+
+
+FontID HanderaAdjustFont
+       (
+       FontID font
+       )
+{
+#ifdef SUPPORT_DIA_HANDERA
+    if ( hardware == DIA_HARDWARE_HANDERA &&
+         0 == ( font & fntAppFontCustomBase ) )
+        return VgaBaseToVgaFont( font );
+    else
+#endif
+        return font;
+}
+
+
+
+Coord HanderaCoord( Coord x )
+{
+#ifdef SUPPORT_DIA_HANDERA
+    return hardware == DIA_HARDWARE_HANDERA ? x * 3 / 2 : x;
+#else
+    return x;
+#endif
+}
diff --git a/forms/DIA.h b/forms/DIA.h
new file mode 100644 (file)
index 0000000..f267fb7
--- /dev/null
@@ -0,0 +1,91 @@
+/* $Id: DIA.h,v 1.1 2005/05/15 09:06:03 admin Exp $ */
+/*******************************************************************************
+    Copyright (c) 2004, Alexander R. Pruss
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification,
+    are permitted provided that the following conditions are met:
+
+        Redistributions of source code must retain the above copyright notice, this
+        list of conditions and the following disclaimer.
+
+        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.
+
+        Neither the name of the PalmResize Project nor the names of its
+        contributors may be used to endorse or promote products derived from this
+        software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER 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.
+*******************************************************************************/
+
+#ifndef _ARP_DIA_H
+#define _ARP_DIA_H
+
+//#include "viewer.h"
+
+#include "resize.h"
+
+typedef enum {
+    DIA_HARDWARE_NONE = 0,
+    DIA_HARDWARE_HANDERA,
+    DIA_HARDWARE_SONY1,
+    DIA_HARDWARE_SONY2,
+    DIA_HARDWARE_PALM10,
+    DIA_HARDWARE_PALM11,
+    DIA_HARDWARE_UNKNOWN
+} DIAHardwareType;
+
+#ifdef SUPPORT_DIA
+
+extern DIAHardwareType InitializeDIA( void ) DIA_SECTION;
+extern void TerminateDIA( void ) DIA_SECTION;
+extern void SetDIAState( DIAStateType state ) DIA_SECTION;
+extern void SetDIAAllowResize( Boolean allow ) DIA_SECTION;
+extern Boolean HandleResizeNotification( UInt32 notificationType )
+     /* not DIA_SECTION in case other notifications arrive */;
+extern DIAStateType GetDIAState( void ) DIA_SECTION;
+extern void SetCustomDIAPolicy( UInt16 formID ) DIA_SECTION;
+extern DIAHardwareType GetDIAHardware( void ) DIA_SECTION;
+extern void SetDIAConstraints( WinHandle winH, Boolean defaultBig,
+    Boolean allowBig ) DIA_SECTION;
+/* Check which DIA state covers more screen space */
+extern Int16 CompareDIAState( DIAStateType x, DIAStateType y )
+    DIA_SECTION;
+extern void GetHiddenStatusBarArea( RectangleType* area ) DIA_SECTION;
+/* These two functions should NOT be used by code other than that in
+   resize.c and DIA.c. */
+extern void PushCoordinateSystemToStandard( void ) DIA_SECTION;
+extern void PopCoordinateSystem( void ) DIA_SECTION;
+extern FontID HanderaAdjustFont( FontID font ) DIA_SECTION;
+extern Coord HanderaCoord( Coord x ) DIA_SECTION;
+
+#else
+
+#define InitializeDIA()              DIA_HARDWARE_NONE
+#define TerminateDIA()
+#define SetDIAState( s )
+#define SetDIAAllowResize( a )
+#define HandleResizeNotification( n ) false
+#define GetDIAState()                DIA_STATE_MAX
+#define SetCustomDIAPolicy( f )
+#define GetDIAHardware()             DIA_HARDWARE_NONE
+#define SetDIAConstraints( w, d, a )
+#define CompareDIAState( x, y )      0
+#define GetHiddenStatusBarArea( a )  MemSet( a, sizeof( RectangleType ), 0 )
+#define HanderaAdjustFont( font )    ( font )
+#define HanderaCoord( x )            ( x )
+
+#endif
+
+#endif /* _ARP_DIA_H */
diff --git a/forms/about.c b/forms/about.c
new file mode 100644 (file)
index 0000000..4ea9dcd
--- /dev/null
@@ -0,0 +1,192 @@
+/**********
+ * Copyright (c) 2003-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "formutils.h"
+#include "forms/resize.h"
+#include "rsrc/rsrc.h"
+
+#include "about.h"
+
+
+Boolean AboutFormHandleEvent(EventPtr e)
+{
+    FormPtr frmP = FrmGetActiveForm();
+
+    if (ResizeHandleEvent(e)) return true;
+
+    switch (e->eType) {
+    case frmOpenEvent:
+        FrmDrawForm(frmP);
+        return true;
+
+    case ctlSelectEvent:
+        if (e->data.ctlSelect.controlID == AboutFormOKButtonID) {
+            FrmReturnToForm(0);
+            return true;
+        }
+        return false;
+
+    default:
+        return false;
+    }
+}
+
+
+#define credits \
+    "pssh is brought to you by:\n" \
+    "Greg Parker: www.sealiesoftware.com\n\n" \
+    "Eric Young and the OpenSSL team: www.OpenSSL.org\n\n" \
+    "Tatu Ylonen, Markus Friedl, Niels Provos, and the OpenSSH team: www.OpenSSH.org\n\n" \
+    "Simon Tatham and the PuTTY team: www.chiark.greenend.org.uk/~sgtatham/putty/\n\n" \
+    "Aaron Gifford: www.aarongifford.com\n\n" \
+    "Alex Pruss: sf.net/projects/palmresize\n\n" \
+    "Lauri Aarnio: www.nixu.fi/~lauri/\n\n" \
+    "Walter Francis, Ton van Overbeek, David Carrel, Brian Wingerter, David Nolan, Jason Perry, Dan Vollmer, Olaf Kolling, Chris Weiss, Alexander Burke, Andreas Amann, Duncan Hudson, Jon Winters, Brian Parker, Ronny Hippler, Guy Davies, Thomas Arendsen Hein, Stefan Braunstein, Michael Bongartz, Olaf Ippisch, Michael Frotscher, Daniel Arvesen, and everyone else who has reported bugs and tested bug fixes\n\n" \
+    "---\n\n" \
+    "This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)\n" \
+    "This product contains cryptographic software written by Eric Young (eay@cryptsoft.com)"
+
+
+Boolean CreditsFormHandleEvent(EventPtr e)
+{
+    FormPtr frmP = FrmGetActiveForm();
+
+    if (ResizeHandleEvent(e)) return true;
+
+    switch (e->eType) {
+    case frmOpenEvent:
+        PrvSetFieldToValueByID(CreditsFormFieldID, credits);
+        PrvUpdateScrollbarForField(CreditsFormFieldID, 
+                                   CreditsFormScrollbarID);
+        FrmDrawForm(frmP);
+        return true;
+
+    case sclRepeatEvent:
+        if (e->data.sclRepeat.scrollBarID == CreditsFormScrollbarID) {
+            PrvScrollField(CreditsFormFieldID, e);
+        }
+        return false;
+
+    case ctlSelectEvent:
+        if (e->data.ctlSelect.controlID == CreditsFormOKButtonID) {
+            PrvSetFieldToValueByID(CreditsFormFieldID, "");
+            FrmReturnToForm(0);
+            return true;
+        }
+        return false;
+
+    default:
+        return false;
+    }
+}
+
+
+static char *BannerText = NULL;
+static int BannerDone;
+
+void Banner(char *text)
+{
+    int i;
+    int shift = 0;
+    int sawNewline = false;
+    Err err;
+    EventType event;
+
+    // Reformat the banner:
+    // elide '\r'
+    // fixme elide lone '\n' or something
+
+    shift = 0;
+    for (i = 0; text[i]; i++) {
+        if (text[i] == '\r') {
+            shift++;
+        } else if (text[i] == '\n'  &&  !sawNewline) {
+            text[i-shift] = ' ';
+            sawNewline = true;
+        } else {
+            sawNewline = (text[i] == '\n');
+            text[i-shift] = text[i];
+        }
+    }
+    text[i-shift] = '\0';
+    
+    BannerText = text;
+    BannerDone = false;
+    
+    FrmPopupForm(BannerFormID);
+
+    // Don't return to main loop, because we can't handle network traffic 
+    // until the banner is dismissed.
+    // fixme suck
+    
+    do {
+        EvtGetEvent(&event, -1);
+        if (!SysHandleEvent(&event)) {
+            if (!MenuHandleEvent(NULL, &event, &err)) {
+                if (!ApplicationHandleEvent(&event)) {
+                    FrmDispatchEvent(&event);
+                }
+            }
+        }
+    } while (event.eType != appStopEvent  &&  !BannerDone);
+}
+
+
+Boolean BannerFormHandleEvent(EventPtr e)
+{
+    FormPtr frmP = FrmGetActiveForm();
+
+    if (ResizeHandleEvent(e)) return true;
+
+    switch (e->eType) {
+    case frmOpenEvent:
+        PrvSetFieldToValueByID(BannerFormFieldID, BannerText);
+        PrvUpdateScrollbarForField(BannerFormFieldID, 
+                                   BannerFormScrollbarID);
+        FrmDrawForm(frmP);
+
+        // fixme resize form based on length of banner text
+
+        return true;
+
+    case sclRepeatEvent:
+        if (e->data.sclRepeat.scrollBarID == BannerFormScrollbarID) {
+            PrvScrollField(BannerFormFieldID, e);
+        }
+        return false;
+
+    case ctlSelectEvent:
+        if (e->data.ctlSelect.controlID == BannerFormOKButtonID) {
+            PrvSetFieldToValueByID(BannerFormFieldID, "");
+            BannerDone = true;
+            FrmReturnToForm(0);
+            return true;
+        }
+        return false;
+
+    default:
+        return false;
+    }
+}
diff --git a/forms/about.h b/forms/about.h
new file mode 100644 (file)
index 0000000..8ff3b48
--- /dev/null
@@ -0,0 +1,34 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef ABOUT_H
+#define ABOUT_H
+
+
+Boolean AboutFormHandleEvent(EventPtr e) FORMS_SEGMENT;
+Boolean CreditsFormHandleEvent(EventPtr e) FORMS_SEGMENT;
+Boolean BannerFormHandleEvent(EventPtr e) FORMS_SEGMENT;
+void Banner(char *text) FORMS_SEGMENT;
+
+#endif
diff --git a/forms/connectionprefsform.c b/forms/connectionprefsform.c
new file mode 100644 (file)
index 0000000..c783948
--- /dev/null
@@ -0,0 +1,205 @@
+/**********
+ * Copyright (c) 2004-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// fixme allow subsystems to register with Prefs for change notices 
+// (rather than hardcoding those here)
+
+#include "includes.h"
+#include "formutils.h"
+#include "data/prefs.h"
+#include "ssh/ssh.h"
+#include "rsrc/rsrc.h"
+#include "forms/resize.h"
+
+#include "connectionprefsform.h"
+
+
+extern struct ssh_session_t *ss;
+
+static void LoadConnectionPrefsForm(void) FORMS_SEGMENT;
+static void SaveConnectionPrefsForm(void) FORMS_SEGMENT;
+
+static void LoadConnectionPrefsForm(void)
+{
+    uint32_t value;
+    char *str;
+
+    // ciphers
+    value = PrefsGetInt(prefCipherAES128CBC, 1);
+    PrvSetControlValue(ConnectionPrefsFormAESCheckboxID, value ? 1 : 0);
+    value = PrefsGetInt(prefCipher3DESCBC, 1);
+    PrvSetControlValue(ConnectionPrefsForm3DESCheckboxID, value ? 1 : 0);
+
+    // authmethods
+    value = PrefsGetInt(prefAuthPublicKey, 1);
+    PrvSetControlValue(ConnectionPrefsFormPublicKeyCheckboxID, value ? 1 : 0);
+    value = PrefsGetInt(prefAuthPassword, 1);
+    PrvSetControlValue(ConnectionPrefsFormPasswordCheckboxID, value ? 1 : 0);
+    value = PrefsGetInt(prefAuthKbdInt, 1);
+    PrvSetControlValue(ConnectionPrefsFormKbdIntCheckboxID, value ? 1 : 0);
+
+    // compression
+    value = PrefsGetInt(prefCompressZLib, 0);
+    PrvSetControlValue(ConnectionPrefsFormZLibCheckboxID, value ? 1 : 0);
+
+    // terminal type
+    str = PrefsGetString(prefTerminalType, "xterm");
+    PrvSetFieldToValueByID(ConnectionPrefsFormTerminalFieldID, str);
+    arena_free(str);
+}
+
+
+static void SaveConnectionPrefsForm(void)
+{
+    uint32_t value;
+    int selection;
+
+    // ciphers
+    value = PrefsGetInt(prefCipherAES128CBC, 1);
+    selection = PrvGetControlValue(ConnectionPrefsFormAESCheckboxID);
+    if (value != selection) PrefsPutInt(prefCipherAES128CBC, selection);
+    value = PrefsGetInt(prefCipher3DESCBC, 1);
+    selection = PrvGetControlValue(ConnectionPrefsForm3DESCheckboxID);
+    if (value != selection) PrefsPutInt(prefCipher3DESCBC, selection);
+
+    // authmethods
+    value = PrefsGetInt(prefAuthPublicKey, 1);
+    selection = PrvGetControlValue(ConnectionPrefsFormPublicKeyCheckboxID);
+    if (value != selection) PrefsPutInt(prefAuthPublicKey, selection);
+    value = PrefsGetInt(prefAuthPassword, 1);
+    selection = PrvGetControlValue(ConnectionPrefsFormPasswordCheckboxID);
+    if (value != selection) PrefsPutInt(prefAuthPassword, selection);
+    value = PrefsGetInt(prefAuthKbdInt, 1);
+    selection = PrvGetControlValue(ConnectionPrefsFormKbdIntCheckboxID);
+    if (value != selection) PrefsPutInt(prefAuthKbdInt, selection);
+
+    // compression
+    value = PrefsGetInt(prefCompressZLib, 0);
+    selection = PrvGetControlValue(ConnectionPrefsFormZLibCheckboxID);
+    if (value != selection) PrefsPutInt(prefCompressZLib, selection);
+
+    // terminal type
+    {
+        char buf[21];
+        PrvCopyFieldContents(ConnectionPrefsFormTerminalFieldID, buf);
+        PrefsPutString(prefTerminalType, buf);
+    }
+}
+
+
+Boolean ConnectionPrefsFormHandleEvent(EventPtr e)
+{
+    FormPtr frmP = FrmGetActiveForm();
+
+    if (ResizeHandleEvent(e)) return true;
+
+    switch (e->eType) {
+    case frmOpenEvent:
+        LoadConnectionPrefsForm();
+        FrmDrawForm(frmP);
+        return true;
+
+    case popSelectEvent: {
+        if (e->data.popSelect.listID == ConnectionPrefsFormTerminalListID) {
+            FieldPtr fld;
+            char *str = LstGetSelectionText(e->data.popSelect.listP,
+                                            e->data.popSelect.selection);
+            PrvSetFieldToValueByID(ConnectionPrefsFormTerminalFieldID, str);
+            fld = PrvGetObjectByID(ConnectionPrefsFormTerminalFieldID);
+            FldEraseField(fld);
+            FldDrawField(fld);
+        }
+
+        // DON'T let popup trigger see this event and change its name
+        return true; 
+    }
+
+    case ctlSelectEvent:
+        switch (e->data.ctlSelect.controlID) {
+        case ConnectionPrefsFormOKButtonID:
+            // save values; leave form
+            SaveConnectionPrefsForm();
+            FrmReturnToForm(0);
+            return true;
+
+        case ConnectionPrefsFormCancelButtonID:
+            // DON'T save values; leave form
+            FrmReturnToForm(0);
+            return true;
+
+        case ConnectionPrefsFormTerminalTriggerID: {
+            // Before displaying terminal type popup, select the popup entry 
+            // that matches the current field value, if any
+            FieldPtr fld;
+            ListPtr lst;
+            char *fldStr;
+            int i, count;
+
+            fld = PrvGetObjectByID(ConnectionPrefsFormTerminalFieldID);
+            fldStr = FldGetTextPtr(fld);
+            lst = PrvGetObjectByID(ConnectionPrefsFormTerminalListID);
+            count = LstGetNumberOfItems(lst);
+            for (i = 0; i < count; i++) {
+                char *lstStr = LstGetSelectionText(lst, i);
+                if (0 == strcmp(lstStr, fldStr)) {
+                    LstSetSelection(lst, i);
+                    break;
+                }
+            }
+            if (i == count) {
+                LstSetSelection(lst, noListSelection);
+            }
+            
+            return false; // continue with ordinary processing
+        }
+
+        // checkboxes
+
+        // Require at least one cipher to be checked
+        case ConnectionPrefsFormAESCheckboxID:
+            if (!PrvGetControlValue(ConnectionPrefsFormAESCheckboxID)  &&  
+                !PrvGetControlValue(ConnectionPrefsForm3DESCheckboxID))
+            {
+                PrvSetControlValue(ConnectionPrefsForm3DESCheckboxID, 1);
+            }
+            return false;
+        case ConnectionPrefsForm3DESCheckboxID:
+            if (!PrvGetControlValue(ConnectionPrefsFormAESCheckboxID)  &&  
+                !PrvGetControlValue(ConnectionPrefsForm3DESCheckboxID))
+            {
+                PrvSetControlValue(ConnectionPrefsFormAESCheckboxID, 1);
+            }
+            return false;
+
+        default:
+            return false;
+        }
+
+    case frmCloseEvent:
+        return false;
+
+    default:
+        return false;
+    }
+}
diff --git a/forms/connectionprefsform.h b/forms/connectionprefsform.h
new file mode 100644 (file)
index 0000000..4a4c86f
--- /dev/null
@@ -0,0 +1,32 @@
+/**********
+ * Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef CONNECTIONPREFSFORM_H
+#define CONNECTIONPREFSFORM_H
+
+#include "includes.h"
+
+Boolean ConnectionPrefsFormHandleEvent(EventPtr e) FORMS_SEGMENT;
+
+#endif
diff --git a/forms/detailsform.c b/forms/detailsform.c
new file mode 100644 (file)
index 0000000..3dc62fe
--- /dev/null
@@ -0,0 +1,123 @@
+/**********
+ * Copyright (c) 2003-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "formutils.h"
+#include "data/connectionlist.h"
+#include "rsrc/rsrc.h"
+#include "forms/resize.h"
+
+#include "detailsform.h"
+
+
+static Boolean LoadDetailsForm(void) FORMS_SEGMENT;
+static Boolean SaveDetailsForm(void) FORMS_SEGMENT;
+
+
+static Boolean LoadDetailsForm(void)
+{
+    MemHandle recordH;
+    Boolean ok = true;
+    char *hostname;
+    char *username;
+    char *portname;
+
+    recordH=ConnectionListReadSelectedRecord(&hostname, &portname, &username);
+    if (!recordH) return false;
+
+    if (ok) ok = PrvSetFieldToValueByID(DetailsFormHostFieldID, hostname);
+    if (ok) ok = PrvSetFieldToValueByID(DetailsFormPortFieldID, portname);
+    if (ok) ok = PrvSetFieldToValueByID(DetailsFormUsernameFieldID, username);
+
+    MemHandleUnlock(recordH);
+
+    return ok;    
+}
+
+
+static Boolean SaveDetailsForm(void)
+{
+    FieldPtr hostFld = PrvGetObjectByID(DetailsFormHostFieldID);
+    FieldPtr portFld = PrvGetObjectByID(DetailsFormPortFieldID);
+    FieldPtr userFld = PrvGetObjectByID(DetailsFormUsernameFieldID);
+
+    if (FldDirty(hostFld)  ||  FldDirty(portFld)  ||  FldDirty(userFld)) {
+        return ConnectionListWriteSelectedRecord(hostFld, portFld, userFld);
+    } else {
+        return true;
+    }
+}
+
+
+Boolean DetailsFormHandleEvent(EventPtr e)
+{
+    FormPtr frmP = FrmGetActiveForm();
+
+    if (ResizeHandleEvent(e)) return true;
+
+    switch (e->eType) {
+    case frmOpenEvent: {
+        LoadDetailsForm();
+        FrmDrawForm(frmP);
+        return true;
+    }
+
+    case ctlSelectEvent:
+        switch (e->data.ctlSelect.controlID) {
+        case DetailsFormOKButtonID:
+            // save connection info, return to main form
+            // Don't validate - let the user enter anything
+            if (!SaveDetailsForm()) {
+                // failed to save connection info
+                // fixme
+            }
+            FrmReturnToForm(0);
+            break;
+
+        case DetailsFormCancelButtonID:
+            // return to main form
+            FrmReturnToForm(0);
+            break;
+
+        case DetailsFormDeleteButtonID:
+            if (0 == FrmAlert(DeleteConnectionAlertID)) {
+                ConnectionListDeleteSelectedRecord();
+                FrmReturnToForm(0);
+            }
+            break;
+
+        default:
+            break;
+        }
+
+        return true;
+
+    case frmCloseEvent:
+        return false;
+
+    default: 
+        return false;
+    }
+}
+
diff --git a/forms/detailsform.h b/forms/detailsform.h
new file mode 100644 (file)
index 0000000..835ec70
--- /dev/null
@@ -0,0 +1,32 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef DETAILSFORM_H
+#define DETAILSFORM_H
+
+#include "includes.h"
+
+Boolean DetailsFormHandleEvent(EventPtr e) FORMS_SEGMENT;
+
+#endif
diff --git a/forms/displayprefsform.c b/forms/displayprefsform.c
new file mode 100644 (file)
index 0000000..c599d4f
--- /dev/null
@@ -0,0 +1,328 @@
+/**********
+ * Copyright (c) 2004-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// fixme allow subsystems to register with Prefs for change notices 
+// (rather than hardcoding those here)
+
+#include "includes.h"
+#include "formutils.h"
+#include "data/prefs.h"
+#include "ssh/ssh.h"
+#include "rsrc/rsrc.h"
+#include "forms/resize.h"
+
+#include "displayprefsform.h"
+
+
+extern struct ssh_session_t *ss;
+
+static void LoadDisplayPrefsForm(void) FORMS_SEGMENT;
+static void SaveDisplayPrefsForm(void) FORMS_SEGMENT;
+static Boolean SampleTextEventHandler(struct FormGadgetTypeInCallback *gadget, 
+                                      UInt16 cmd, void *paramP) FORMS_SEGMENT;
+static void InvalidateSampleText(void) FORMS_SEGMENT;
+static void DrawSampleText(RectangleType bounds) FORMS_SEGMENT;
+
+static void LoadDisplayPrefsForm(void)
+{
+    uint32_t value;
+    char *str;
+
+    // font
+    value = PrefsGetInt(prefTerminalFont, font4x6);
+    PrvSetControlValue(DisplayPrefsFormSmallFontCheckboxID, 
+                       value == font4x6 ? 1 : 0);
+    PrvSetControlValue(DisplayPrefsFormLargeFontCheckboxID, 
+                       value == font6x10 ? 1 : 0);
+    // else some future font size - ignore
+
+    // colors
+    value = PrefsGetInt(prefTerminalForeColor, blackColor);
+    if (value < 8) {
+        ListPtr lst = PrvGetObjectByID(DisplayPrefsFormForeColorListID);
+        LstSetSelection(lst, value);
+        PrvSetControlLabel(DisplayPrefsFormForeColorTriggerID, 
+                           LstGetSelectionText(lst, value));
+    }
+    value = PrefsGetInt(prefTerminalBackColor, whiteColor);
+    if (value < 8) {
+        ListPtr lst = PrvGetObjectByID(DisplayPrefsFormBackColorListID);
+        LstSetSelection(lst, value);
+        PrvSetControlLabel(DisplayPrefsFormBackColorTriggerID, 
+                           LstGetSelectionText(lst, value));
+    }
+
+    // scrollback lines
+    value = PrefsGetInt(prefScrollbackLines, defaultScrollbackLines);
+    if (value > maxScrollbackLines) value = defaultScrollbackLines;
+    {
+        char buf[5];
+        snprintf(buf, sizeof(buf), "%lu", value);
+        PrvSetFieldToValueByID(DisplayPrefsFormScrollbackFieldID, buf);
+    }
+
+    // scroll to bottom
+    value = PrefsGetInt(prefScrollDownOnActivity, defaultScrollDownOnActivity);
+    PrvSetControlValue(DisplayPrefsFormActivityCheckboxID, value ? 1 : 0);
+    value = PrefsGetInt(prefScrollDownOnTyping, defaultScrollDownOnTyping);
+    PrvSetControlValue(DisplayPrefsFormTypingCheckboxID, value ? 1 : 0);
+
+    // bell
+    value = PrefsGetInt(prefBellBeep, defaultBellBeep);
+    PrvSetControlValue(DisplayPrefsFormBeepCheckboxID, value ? 1 : 0);
+    value = PrefsGetInt(prefBellFlash, defaultBellFlash);
+    PrvSetControlValue(DisplayPrefsFormFlashCheckboxID, value ? 1 : 0);
+}
+
+
+static void SaveDisplayPrefsForm(void)
+{
+    uint32_t value;
+    int selection;
+    Boolean sshChanged = false;
+
+    // font
+    value = PrefsGetInt(prefTerminalFont, font4x6);
+    if (PrvGetControlValue(DisplayPrefsFormSmallFontCheckboxID) && value != font4x6) {
+        PrefsPutInt(prefTerminalFont, font4x6);
+        sshChanged = true;
+    } else if (PrvGetControlValue(DisplayPrefsFormLargeFontCheckboxID) && value != font6x10) {
+        PrefsPutInt(prefTerminalFont, font6x10);
+        sshChanged = true;
+    }
+
+    // color
+    value = PrefsGetInt(prefTerminalForeColor, defaultForeColor);
+    selection = LstGetSelection(PrvGetObjectByID(DisplayPrefsFormForeColorListID));
+    if (selection != value  &&  selection != noListSelection) {
+        PrefsPutInt(prefTerminalForeColor, selection);
+        sshChanged = true;
+    }
+    value = PrefsGetInt(prefTerminalBackColor, defaultBackColor);
+    selection = LstGetSelection(PrvGetObjectByID(DisplayPrefsFormBackColorListID));
+    if (selection != value  &&  selection != noListSelection) {
+        PrefsPutInt(prefTerminalBackColor, selection);
+        sshChanged = true;
+    }
+
+    // scrollback lines
+    {
+        char buf[5];
+        uint32_t lines;
+        value = PrefsGetInt(prefScrollbackLines, defaultScrollbackLines);
+        PrvCopyFieldContents(DisplayPrefsFormScrollbackFieldID, buf);
+        if (strlen(buf) > 0) {
+            lines = StrAToI(buf);
+            if (value != lines) {
+                PrefsPutInt(prefScrollbackLines, lines);
+                sshChanged = true;
+            }
+        }
+    }
+
+    // scroll to bottom
+    value = PrefsGetInt(prefScrollDownOnActivity, defaultScrollDownOnActivity);
+    selection = PrvGetControlValue(DisplayPrefsFormActivityCheckboxID);
+    if (value != selection) {
+        PrefsPutInt(prefScrollDownOnActivity, selection);
+        sshChanged = true;
+    }
+    value = PrefsGetInt(prefScrollDownOnTyping, defaultScrollDownOnTyping);
+    selection = PrvGetControlValue(DisplayPrefsFormTypingCheckboxID);
+    if (value != selection) {
+        PrefsPutInt(prefScrollDownOnTyping, selection);
+        sshChanged = true;
+    }
+
+    // bell
+    value = PrefsGetInt(prefBellBeep, defaultBellBeep);
+    selection = PrvGetControlValue(DisplayPrefsFormBeepCheckboxID);
+    if (value != selection) {
+        PrefsPutInt(prefBellBeep, selection);
+        sshChanged = true;
+    }
+    value = PrefsGetInt(prefBellFlash, defaultBellFlash);
+    selection = PrvGetControlValue(DisplayPrefsFormFlashCheckboxID);
+    if (value != selection) {
+        PrefsPutInt(prefBellFlash, selection);
+        sshChanged = true;
+    }
+
+    if (sshChanged) ssh_reread_prefs(ss);
+}
+
+
+static void InvalidateSampleText(void)
+{
+    EventType e2;
+    e2.eType = frmGadgetMiscEvent;
+    e2.data.gadgetMisc.gadgetID = DisplayPrefsFormSampleTextGadgetID;
+    e2.data.gadgetMisc.gadgetP = 
+        PrvGetObjectByID(e2.data.gadgetMisc.gadgetID);
+    e2.data.gadgetMisc.selector = 0;
+    e2.data.gadgetMisc.dataP = NULL;
+    EvtAddEventToQueue(&e2);
+}
+
+
+Boolean DisplayPrefsFormHandleEvent(EventPtr e)
+{
+    FormPtr frmP = FrmGetActiveForm();
+
+    if (ResizeHandleEvent(e)) return true;
+
+    switch (e->eType) {
+    case frmOpenEvent:
+        FrmSetGadgetHandler(FrmGetActiveForm(), 
+                            PrvGetObjectIndexByID(DisplayPrefsFormSampleTextGadgetID),
+                            SampleTextEventHandler);
+        LoadDisplayPrefsForm();
+        FrmDrawForm(frmP);
+        return true;
+
+    case popSelectEvent: {
+        // force sample text to redraw with new colors
+        InvalidateSampleText();
+        return false;
+    }
+
+    case ctlSelectEvent:
+        switch (e->data.ctlSelect.controlID) {
+        case DisplayPrefsFormOKButtonID:
+            // save values; leave form
+            SaveDisplayPrefsForm();
+            FrmReturnToForm(0);
+            return true;
+
+        case DisplayPrefsFormCancelButtonID:
+            // DON'T save values; leave form
+            FrmReturnToForm(0);
+            return true;
+
+        // checkboxes
+
+        case DisplayPrefsFormSmallFontCheckboxID:
+            PrvSetControlValue(DisplayPrefsFormLargeFontCheckboxID, 0);
+            InvalidateSampleText();
+            return true;
+        case DisplayPrefsFormLargeFontCheckboxID:
+            PrvSetControlValue(DisplayPrefsFormSmallFontCheckboxID, 0);
+            InvalidateSampleText();
+            return true;
+
+        default:
+            return false;
+        }
+
+    case frmCloseEvent:
+        return false;
+
+    default:
+        return false;
+    }
+}
+
+// fixme
+extern void set_palm_color(int fg_color, int bg_color);
+
+static void DrawSampleText(RectangleType bounds)
+{
+    uint32_t fg_color;
+    uint32_t bg_color;
+    char *str = "Sample terminal text";
+    Int16 width, height;
+    Int16 x, y;
+
+    WinPushDrawState();
+    
+    fg_color = LstGetSelection(PrvGetObjectByID(DisplayPrefsFormForeColorListID));
+    bg_color = LstGetSelection(PrvGetObjectByID(DisplayPrefsFormBackColorListID));
+    set_palm_color(fg_color * 2, bg_color * 2);
+    
+    if (PrvGetControlValue(DisplayPrefsFormSmallFontCheckboxID)) {
+        FntSetFont(font_for_screen(font4x6));
+    } else {
+        FntSetFont(font_for_screen(font6x10));
+    }
+
+    width = FntCharsWidth(str, strlen(str));
+    height = FntLineHeight();
+
+    x = bounds.topLeft.x + (bounds.extent.x / 2) - (width / 2);
+    y = bounds.topLeft.y + (bounds.extent.y / 2) - (height / 2);
+    
+    WinEraseRectangle(&bounds, 0);
+    WinDrawChars(str, strlen(str), x, y);
+    
+    WinPopDrawState();
+}
+
+
+static Boolean SampleTextEventHandler(struct FormGadgetTypeInCallback *gadget, 
+                                      UInt16 cmd, void *paramP)
+{
+    Boolean handled = false; 
+
+    switch (cmd) { 
+    case formGadgetDrawCmd: 
+        // Sent to active gadgets any time form is  
+        // drawn or redrawn. 
+        DrawSampleText(gadget->rect);
+        handled = true; 
+        break; 
+
+    case formGadgetHandleEventCmd: {
+        EventPtr e = (EventPtr)paramP;
+        // Sent when form receives a gadget event.  
+        // paramP points to EventType structure.  
+        if (e->eType == frmGadgetEnterEvent) { 
+            // penDown in gadget's bounds.  
+            // do nothing
+            handled = true; 
+        } else if (e->eType == frmGadgetMiscEvent) { 
+            // This event is sent by your application 
+            // when it needs to send info to the gadget 
+            DrawSampleText(gadget->rect);
+            handled = true;
+        } 
+        break; 
+    }
+
+    case formGadgetDeleteCmd:  
+        // Perform any cleanup prior to deletion. 
+        break; 
+
+    case formGadgetEraseCmd:  
+        // FrmHideObject takes care of this if you  
+        // return false.  
+        handled = false; 
+        break; 
+
+    default:
+        handled = false;
+        break;
+    } 
+
+    return handled; 
+} 
diff --git a/forms/displayprefsform.h b/forms/displayprefsform.h
new file mode 100644 (file)
index 0000000..9ad3167
--- /dev/null
@@ -0,0 +1,32 @@
+/**********
+ * Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef DISPLAYPREFSFORM_H
+#define DISPLAYPREFSFORM_H
+
+#include "includes.h"
+
+Boolean DisplayPrefsFormHandleEvent(EventPtr e) FORMS_SEGMENT;
+
+#endif
diff --git a/forms/hostkeydetailsform.c b/forms/hostkeydetailsform.c
new file mode 100644 (file)
index 0000000..3b6aed4
--- /dev/null
@@ -0,0 +1,143 @@
+/**********
+ * Copyright (c) 2003-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "formutils.h"
+#include "data/hostkeys.h"
+#include "rsrc/rsrc.h"
+#include "ssh/openssh/key.h"
+#include "ssh/openssh/uuencode.h"
+#include "forms/resize.h"
+
+#include "hostkeydetailsform.h"
+
+
+static Boolean LoadHostKeyDetailsForm(void) FORMS_SEGMENT;
+
+
+static Boolean LoadHostKeyDetailsForm(void)
+{
+    MemHandle recordH;
+    Boolean ok = true;
+    char *hostnames;
+    uint8_t *keyblob;
+    uint16_t keybloblen;
+    Key *key;
+
+    recordH = HostKeysQuerySelectedRecord(&hostnames, &keyblob, &keybloblen);
+    if (!recordH) return false;
+
+    if (ok) ok = PrvSetFieldToValueByID(HostKeyDetailsFormHostFieldID, hostnames);
+    
+    if (ok) ok = ((key = key_from_blob(keyblob, keybloblen)) != NULL);
+    if (ok) ok = PrvSetFieldToValueByID(HostKeyDetailsFormKeyTypeFieldID, key_type(key));
+    if (ok) {
+        // uuencode(blob) is what OpenSSH uses for known_hosts files
+        uint8_t *uubuf = xmalloc(2*keybloblen);
+        int uulen = uuencode(keyblob, keybloblen, uubuf, 2*keybloblen);
+        if (uulen > 0) {
+            ok = PrvSetFieldToValueByID(HostKeyDetailsFormKeyFieldID, uubuf);
+        }
+        xfree(uubuf);
+    }
+
+    PrvUpdateScrollbarForField(HostKeyDetailsFormKeyFieldID, 
+                               HostKeyDetailsFormKeyScrollbarID);
+
+    MemHandleUnlock(recordH);
+
+    return ok;    
+}
+
+
+Boolean HostKeyDetailsFormHandleEvent(EventPtr e)
+{
+    FormPtr frmP = FrmGetActiveForm();
+
+    if (ResizeHandleEvent(e)) return true;
+
+    switch (e->eType) {
+    case frmOpenEvent: {
+        LoadHostKeyDetailsForm();
+        FrmDrawForm(frmP);
+        return true;
+    }
+
+    case sclRepeatEvent:
+        if (e->data.sclRepeat.scrollBarID == HostKeyDetailsFormKeyScrollbarID){
+            PrvScrollField(HostKeyDetailsFormKeyFieldID, e);
+        }
+        return false;
+
+    case ctlSelectEvent:
+        switch (e->data.ctlSelect.controlID) {
+        case HostKeyDetailsFormOKButtonID:
+            FrmReturnToForm(0);
+            break;
+
+        case HostKeyDetailsFormDeleteButtonID:
+            if (0 == FrmAlert(DeleteHostKeyAlertID)) {
+                HostKeysDeleteSelectedRecord();
+                FrmReturnToForm(0);
+            }
+            break;
+
+        default:
+            break;
+        }
+
+        return true;
+
+    case frmCloseEvent:
+        return false;
+
+    default: 
+        return false;
+    }
+}
+
+/*
+static Boolean HostKeyDetailsFormResize(FormPtr frmP)
+{
+    Int16 dh, dv;
+    Boolean changed = CollapseResizeForm(frmP, false, &dh, &dv);
+    
+    if (!changed) return false;
+
+    // key data field: resize to width and height
+    // key data scrollbar: resize to width and height
+    // host field: resize to width (fixme)
+    // key type field: resize to width (fixme)
+    // everything else: move vertically
+
+    CollapseMoveResizeFormObject(frmP, HostKeyDetailsFormOKButtonID, dh, dv, 0, 0);
+    CollapseMoveResizeFormObject(frmP, HostKeyDetailsFormDeleteButtonID, dh, dv, 0, 0);
+
+    PrvResizeFieldAndScrollbar(frmP, dh, dv, 
+                               FrmGetObjectIndex(frmP, HostKeyDetailsFormKeyFieldID),
+                               FrmGetObjectIndex(frmP, HostKeyDetailsFormKeyScrollbarID));
+    
+    return true;
+}
+*/
diff --git a/forms/hostkeydetailsform.h b/forms/hostkeydetailsform.h
new file mode 100644 (file)
index 0000000..4771a72
--- /dev/null
@@ -0,0 +1,32 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef HOSTKEYDETAILSFORM_H
+#define HOSTKEYDETAILSFORM_H
+
+#include "includes.h"
+
+Boolean HostKeyDetailsFormHandleEvent(EventPtr e) FORMS_SEGMENT;
+
+#endif
diff --git a/forms/hostkeysform.c b/forms/hostkeysform.c
new file mode 100644 (file)
index 0000000..e2ebae7
--- /dev/null
@@ -0,0 +1,84 @@
+/**********
+ * Copyright (c) 2003-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "formutils.h"
+#include "forms/resize.h"
+#include "data/hostkeys.h"
+#include "rsrc/rsrc.h"
+
+#include "hostkeysform.h"
+
+
+Boolean HostKeysFormHandleEvent(EventPtr e)
+{
+    FormPtr frmP = FrmGetActiveForm();
+
+    if (ResizeHandleEvent(e)) return true;
+    if (HostKeysHandleEvent(e)) return true;
+
+    switch (e->eType) {
+    case frmOpenEvent:
+        HostKeysUpdate();
+        FrmDrawForm(frmP);
+        return true;
+
+    case ctlSelectEvent:
+        switch (e->data.ctlSelect.controlID) {
+
+        case HostKeysFormOKButtonID:
+            FrmReturnToForm(0);
+            break;
+
+        case HostKeysFormDetailsButtonID:
+            if (HostKeysSelectedIndex() != noRecord) {
+                FrmPopupForm(HostKeyDetailsFormID);
+            }
+            break;
+
+        default: 
+            break;
+
+        }
+        return false;
+
+    case frmCloseEvent:
+        return false;
+
+    default: 
+        return false;
+    }
+}
+
+
+void HostKeysFormResize(FormPtr frmP, Int16 dh, Int16 dv)
+{
+    static Int16 height = -1;
+    PrvResizeTableAndScrollbar(frmP, dh, dv, 0, &height, 
+                               FrmGetObjectIndex(frmP, HostKeysFormKeyTableID),
+                               FrmGetObjectIndex(frmP, HostKeysFormKeyScrollbarID));
+
+    HostKeysUpdate();
+}
+
diff --git a/forms/hostkeysform.h b/forms/hostkeysform.h
new file mode 100644 (file)
index 0000000..f92a908
--- /dev/null
@@ -0,0 +1,33 @@
+/**********
+ * Copyright (c) 2003-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef HOSTKEYSFORM_H
+#define HOSTKEYSFORM_H
+
+#include "includes.h"
+
+Boolean HostKeysFormHandleEvent(EventPtr e) FORMS_SEGMENT;
+void HostKeysFormResize(FormPtr frmP, Int16 dh, Int16 dv) FORMS_SEGMENT;
+
+#endif
diff --git a/forms/kbdint0form.c b/forms/kbdint0form.c
new file mode 100644 (file)
index 0000000..0514619
--- /dev/null
@@ -0,0 +1,204 @@
+/**********
+ * Copyright (c) 2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "formutils.h"
+#include "data/prefs.h"
+#include "data/connectionlist.h"
+#include "rsrc/rsrc.h"
+#include "ssh/ssh.h"
+#include "forms/resize.h"
+
+#include "kbdint0form.h"
+
+
+static void KbdInt0SendResponses(Boolean ok) FORMS_SEGMENT;
+static void LoadKbdInt0Form(void) FORMS_SEGMENT;
+
+extern struct ssh_session_t *ss;
+
+
+// globals for communication between KbdInt0GetResponses 
+// and each form instantiation
+static char *KbdInt0Name;
+static char *KbdInt0Instructions;
+
+
+void KbdInt0GetResponses(char *name, char *instructions)
+{
+    kbdint_log(__PRETTY_FUNCTION__);
+
+    KbdInt0Name = name;
+    KbdInt0Instructions = instructions;
+
+    // set a default window title if no name was given
+    if (KbdInt0Name[0] == '\0') {
+        KbdInt0Name = "Notice";
+    }
+
+    // present instructions
+    FrmPopupForm(KbdInt0FormID);
+}
+
+static void KbdInt0SendResponses(Boolean ok)
+{
+    char *responses[1] = {"unused"};
+
+    kbdint_log(__PRETTY_FUNCTION__);
+    
+    // send responses to ssh (NULL means user cancel)
+    // For non-cancel, send any old non-NULL value.
+    ssh_use_kbdint(ss, ok ? responses : NULL);
+}
+
+
+// shorten form by delta pixels
+// move every control at and after firstID up; leave others alone
+static void ShortenForm(FormPtr frmP, UInt16 firstID, UInt16 delta)
+{
+    UInt16 id, index;
+    RectangleType bounds;
+    WinHandle winH;
+
+    kbdint_log(__PRETTY_FUNCTION__);
+
+    // move controls
+    for (id = firstID; id <= KbdInt0FormLastID; id++) {
+        PrvGetObjectBoundsByID(id, &bounds);
+        bounds.topLeft.y -= delta;
+        PrvSetObjectBoundsByID(id, &bounds);
+    }
+
+    // change form size and position
+    winH = WinGetWindowHandle(frmP);
+    WinGetBounds(winH, &bounds);
+    bounds.topLeft.y += delta;
+    bounds.extent.y -= delta;
+    WinSetBounds(winH, &bounds);
+}
+
+
+static void LoadKbdInt0Form(void)
+{
+    FormPtr frmP = FrmGetActiveForm();
+    MemHandle recordH;
+    char *hostname;
+    FieldPtr fieldP;
+    RectangleType bounds;
+    UInt16 height;
+
+    kbdint_log(__PRETTY_FUNCTION__);
+
+    // Set hostname (all prompts)
+    recordH = ConnectionListReadSelectedRecord(&hostname, NULL, NULL);
+    if (recordH  &&  hostname) {
+        PrvSetFieldToValueByID(KbdInt0FormHostFieldID, hostname);
+        MemHandleUnlock(recordH);
+    }
+
+    // Set form title (all prompts)
+    FrmSetTitle(frmP, KbdInt0Name);
+
+    // Set instructions (all prompts)
+    PrvSetFieldToValueByID(KbdInt0FormInstructionFieldID, KbdInt0Instructions);
+
+    // Adjust form height based on instructions length
+    fieldP = (FieldPtr)PrvGetObjectByID(KbdInt0FormInstructionFieldID);    
+    PrvGetObjectBoundsByID(KbdInt0FormInstructionFieldID, &bounds);
+    height = FldGetTextHeight(fieldP);
+    if (strlen(KbdInt0Instructions) == 0  ||  height == 0) {
+        // Hide scroll bar and instructions
+        PrvHideObjectByID(KbdInt0FormInstructionFieldID);
+        PrvHideObjectByID(KbdInt0FormInstructionScrollbarID);
+        ShortenForm(frmP, KbdInt0FormOKButtonID, bounds.extent.y + 4);
+    } else {
+        // Resize field and form and update scrollbar 
+        PrvSetObjectHeightByID(KbdInt0FormInstructionFieldID, height);
+        PrvSetObjectHeightByID(KbdInt0FormInstructionScrollbarID, height);
+        ShortenForm(frmP, KbdInt0FormOKButtonID, bounds.extent.y - height);
+        PrvUpdateScrollbarForField(KbdInt0FormInstructionFieldID, 
+                                   KbdInt0FormInstructionScrollbarID);
+    }
+}
+
+
+Boolean KbdInt0FormHandleEvent(EventPtr e)
+{
+    FormPtr frmP = FrmGetActiveForm();
+
+    if (ResizeHandleEvent(e)) return true;
+
+    kbdint_log(__PRETTY_FUNCTION__);
+
+    switch (e->eType) {
+    case frmOpenEvent:
+        LoadKbdInt0Form();
+        FrmDrawForm(frmP);
+        return true;
+        
+    case keyDownEvent:
+        if (!EvtKeydownIsVirtual(e)) {
+            unsigned char c = e->data.keyDown.chr;
+            if (c == '\n'  ||  c == '\r') {
+                // enter - OK button
+                KbdInt0SendResponses(true);
+                FrmReturnToForm(0);
+                return true;
+            }
+        }
+        return false;
+
+    case sclRepeatEvent:
+        if (e->data.sclRepeat.scrollBarID == 
+            KbdInt0FormInstructionScrollbarID)
+        {
+            PrvScrollField(KbdInt0FormInstructionFieldID, e);
+        }
+        return false;
+
+    case ctlSelectEvent:
+        switch (e->data.ctlSelect.controlID) {
+        case KbdInt0FormOKButtonID:
+            KbdInt0SendResponses(true);
+            FrmReturnToForm(0);
+            return true;
+
+        case KbdInt0FormCancelButtonID:
+            KbdInt0SendResponses(false);
+            FrmReturnToForm(0);
+            return true;
+
+        default:
+            return false;
+        }
+
+    case frmCloseEvent:
+        return false;
+
+    default:
+        return false;
+    }
+}
+
diff --git a/forms/kbdint0form.h b/forms/kbdint0form.h
new file mode 100644 (file)
index 0000000..fdaef0a
--- /dev/null
@@ -0,0 +1,36 @@
+/**********
+ * Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef KBDINT0FORM_H
+#define KBDINT0FORM_H
+
+#include "includes.h"
+
+struct prompt_t;
+
+Boolean KbdInt0FormHandleEvent(EventPtr e) FORMS_SEGMENT;
+
+void KbdInt0GetResponses(char *name, char *instructions) FORMS_SEGMENT;
+
+#endif
diff --git a/forms/kbdintform.c b/forms/kbdintform.c
new file mode 100644 (file)
index 0000000..21da617
--- /dev/null
@@ -0,0 +1,404 @@
+/**********
+ * Copyright (c) 2004-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "formutils.h"
+#include "data/prefs.h"
+#include "data/connectionlist.h"
+#include "rsrc/rsrc.h"
+#include "ssh/ssh.h"
+#include "forms/resize.h"
+
+#include "kbdintform.h"
+
+
+static void KbdIntSendResponses(Boolean ok) FORMS_SEGMENT;
+static void RetrieveResponse(void) FORMS_SEGMENT;
+static void ForgetResponse(void) FORMS_SEGMENT;
+static void SetResponseEcho(Boolean echo) FORMS_SEGMENT;
+static void LoadKbdIntForm(void) FORMS_SEGMENT;
+static void DoNext(void) FORMS_SEGMENT;
+static void DoBack(void) FORMS_SEGMENT;
+
+extern struct ssh_session_t *ss;
+
+
+// globals for communication between KbdIntGetResponses 
+// and each form instantiation
+static char *KbdIntName;
+static char *KbdIntInstructions;
+static prompt_t *KbdIntPrompts;
+static char **KbdIntResponses;
+static int KbdIntPromptCount;
+static int KbdIntCurrentPrompt;
+
+
+void KbdIntGetResponses(char *name, char *instructions, 
+                        prompt_t *prompts, int prompt_count)
+{
+    int i;
+
+    kbdint_log(__PRETTY_FUNCTION__);
+
+    KbdIntName = name;
+    KbdIntInstructions = instructions;
+    KbdIntPrompts = prompts;
+    KbdIntPromptCount = prompt_count;
+    KbdIntCurrentPrompt = 0;
+
+    // set a default window title if no name was given
+    if (KbdIntName[0] == '\0') {
+        KbdIntName = "Log In";
+    }
+
+    // prepare empty response list
+    KbdIntResponses = arena_malloc(prompt_count * sizeof(char *));
+    for (i = 0; i < prompt_count; i++) {
+        KbdIntResponses[i] = arena_strdup("");
+    }
+
+    // present first prompt form
+    FrmPopupForm(KbdIntFormID);
+}
+
+static void KbdIntSendResponses(Boolean ok)
+{
+    int i;
+
+    kbdint_log(__PRETTY_FUNCTION__);
+    
+    // send responses to ssh (NULL means user cancel)
+    ssh_use_kbdint(ss, ok ? KbdIntResponses : NULL);
+
+    // clean up
+    for (i = 0; i < KbdIntPromptCount; i++) {
+        arena_free(KbdIntResponses[i]);
+    }
+    arena_free(KbdIntResponses);
+}
+
+
+static void RetrieveResponse(void)
+{
+    FieldPtr responseFld = PrvGetObjectByID(KbdIntFormResponseFieldID);
+    MemHandle responseH;
+    char *response;
+
+    kbdint_log(__PRETTY_FUNCTION__);
+
+    FldReleaseFocus(responseFld);
+    FldCompactText(responseFld);
+    responseH = FldGetTextHandle(responseFld);
+    FldSetTextHandle(responseFld, NULL);
+
+    if (responseH) {
+        response = MemHandleLock(responseH);
+    } else {
+        response = "";
+    }
+
+    arena_free(KbdIntResponses[KbdIntCurrentPrompt]);
+    KbdIntResponses[KbdIntCurrentPrompt] = arena_strdup(response);
+
+    if (responseH) {
+        MemSet(response, MemHandleSize(responseH), 0);
+        MemHandleUnlock(responseH);
+        MemHandleFree(responseH);
+    }
+}
+
+
+static void ForgetResponse(void)
+{
+    FieldPtr responseFld = PrvGetObjectByID(KbdIntFormResponseFieldID);
+    MemHandle responseH;
+
+    kbdint_log(__PRETTY_FUNCTION__);
+
+    FldReleaseFocus(responseFld);
+    FldCompactText(responseFld);
+    responseH = FldGetTextHandle(responseFld);
+    FldSetTextHandle(responseFld, NULL);
+
+    if (responseH) {
+        MemSet(MemHandleLock(responseH), MemHandleSize(responseH), 0);
+        MemHandleUnlock(responseH);
+        MemHandleFree(responseH);
+    }
+}
+
+
+static void SetResponseEcho(Boolean echo)
+{
+    kbdint_log(__PRETTY_FUNCTION__);
+
+    PrvSetControlValue(KbdIntFormEchoCheckboxID, echo);
+    FldSetFont(PrvGetObjectByID(KbdIntFormResponseFieldID), 
+               echo ? stdFont : (FontID)PasswordFontID);
+}
+
+
+// shorten form by delta pixels
+// move every control at and after firstID up; leave others alone
+// fixme always moves Gsi
+static void ShortenForm(FormPtr frmP, UInt16 firstID, UInt16 delta)
+{
+    UInt16 id, index;
+    RectangleType bounds;
+    WinHandle winH;
+
+    kbdint_log(__PRETTY_FUNCTION__);
+
+    // move controls
+    for (id = firstID; id <= KbdIntFormLastID; id++) {
+        PrvGetObjectBoundsByID(id, &bounds);
+        bounds.topLeft.y -= delta;
+        PrvSetObjectBoundsByID(id, &bounds);
+    }
+
+    // change form size and position
+    winH = WinGetWindowHandle(frmP);
+    WinGetBounds(winH, &bounds);
+    bounds.topLeft.y += delta;
+    bounds.extent.y -= delta;
+    WinSetBounds(winH, &bounds);
+
+    // move Gsi (needs to be AFTER win change to prevent misdraw (fixme really?))
+    for (index = 0; index < FrmGetNumberOfObjects(frmP); index++) {
+        FormObjectKind type = FrmGetObjectType(frmP, index);
+        if (type == frmGraffitiStateObj) {
+            // PrvMoveGsi() here will cause misdraw!
+            Coord x, y;
+            FrmGetObjectPosition(frmP, index, &x, &y);
+            y -= delta;
+            FrmSetObjectPosition(frmP, index, x, y);
+            GsiSetLocation(x, y);
+            break;
+        }
+    }
+}
+
+
+static void LoadKbdIntForm(void)
+{
+    FormPtr frmP = FrmGetActiveForm();
+    MemHandle recordH;
+    char *hostname;
+    FieldPtr fieldP;
+    RectangleType bounds;
+    UInt16 height;
+
+    kbdint_log(__PRETTY_FUNCTION__);
+
+    // Set hostname (all prompts)
+    recordH = ConnectionListReadSelectedRecord(&hostname, NULL, NULL);
+    if (recordH  &&  hostname) {
+        PrvSetFieldToValueByID(KbdIntFormHostFieldID, hostname);
+        MemHandleUnlock(recordH);
+    }
+
+    // Set form title (all prompts)
+    FrmSetTitle(frmP, KbdIntName);
+
+    // Set instructions (all prompts)
+    PrvSetFieldToValueByID(KbdIntFormInstructionFieldID, KbdIntInstructions);
+
+    // Adjust form height based on instructions length
+    fieldP = (FieldPtr)PrvGetObjectByID(KbdIntFormInstructionFieldID);    
+    PrvGetObjectBoundsByID(KbdIntFormInstructionFieldID, &bounds);
+    height = FldGetTextHeight(fieldP);
+    if (strlen(KbdIntInstructions) == 0  ||  height == 0) {
+        // Hide scroll bar and instructions
+        PrvHideObjectByID(KbdIntFormInstructionFieldID);
+        PrvHideObjectByID(KbdIntFormInstructionScrollbarID);
+        ShortenForm(frmP, KbdIntFormPromptFieldID, bounds.extent.y + 4);
+    } else {
+        // Resize field and form and update scrollbar 
+        PrvSetObjectHeightByID(KbdIntFormInstructionFieldID, height);
+        PrvSetObjectHeightByID(KbdIntFormInstructionScrollbarID, height);
+        ShortenForm(frmP, KbdIntFormPromptFieldID, bounds.extent.y - height);
+        PrvUpdateScrollbarForField(KbdIntFormInstructionFieldID, 
+                                   KbdIntFormInstructionScrollbarID);
+    }
+
+    // Set prompt (all prompts)
+    PrvSetFieldToValueByID(KbdIntFormPromptFieldID, 
+                           KbdIntPrompts[KbdIntCurrentPrompt].msg);
+
+    // Set existing response field contents
+    PrvSetFieldToValueByID(KbdIntFormResponseFieldID, 
+                           KbdIntResponses[KbdIntCurrentPrompt]);
+
+    // Set focus to all of response field (all prompts)
+    PrvSetFocusByID(KbdIntFormResponseFieldID);
+    PrvFieldSelectAll(KbdIntFormResponseFieldID);
+
+    // Set echo (all prompts)
+    // If server prompt specifies non-echo, then set echoing to pref value.
+    // Otherwise, enable echoing unconditionally and hide the checkbox.
+    if (! KbdIntPrompts[KbdIntCurrentPrompt].echo) {
+        SetResponseEcho(PrefsGetInt(prefEchoPassword, 0));
+    } else {
+        // field's default font is echo
+        // fixme shorten form? would need to move GSI
+        PrvHideObjectByID(KbdIntFormEchoCheckboxID);
+    }
+
+    // Set prompt count field (multiple prompts only)
+    // Count field is "X of Y" for X current prompt and Y total prompts
+    if (KbdIntPromptCount > 1) {
+        char buf[30];
+        snprintf(buf, sizeof(buf), "%d of %d", 
+                 KbdIntCurrentPrompt+1, KbdIntPromptCount);
+        PrvSetFieldToValueByID(KbdIntFormProgressFieldID, buf);
+    }
+
+    // Set buttons (all prompts)
+    // Note that a single prompt can be both first and last.
+    if (KbdIntCurrentPrompt == 0) {
+        // First prompt - hide Back button
+        PrvHideObjectByID(KbdIntFormBackButtonID);
+    }
+    if (KbdIntCurrentPrompt == KbdIntPromptCount - 1) {
+        // Last prompt - "Next" becomes "OK"
+        PrvSetControlLabel(KbdIntFormNextButtonID, "OK");
+    }
+
+}
+
+
+static void DoNext(void) 
+{
+    kbdint_log(__PRETTY_FUNCTION__);
+
+    // Save this response
+    RetrieveResponse();
+
+    // Update current index
+    KbdIntCurrentPrompt++;
+
+    if (KbdIntCurrentPrompt >= KbdIntPromptCount) {
+        // All done. Send responses to ssh engine and clean up.
+        KbdIntSendResponses(true);
+        FrmReturnToForm(0);
+    }
+    else {
+        // Kill this form and display the next.
+        FrmReturnToForm(0);
+        FrmPopupForm(KbdIntFormID);
+    }
+}
+
+
+static void DoBack(void)
+{
+    kbdint_log(__PRETTY_FUNCTION__);
+
+    // Save this response
+    RetrieveResponse();
+
+    // Update current index
+    if (KbdIntCurrentPrompt == 0) fatal("bad kbdint index!");
+    KbdIntCurrentPrompt--;
+    
+    // Kill this form and display the next
+    FrmReturnToForm(0);
+    FrmPopupForm(KbdIntFormID);
+}
+
+
+Boolean KbdIntFormHandleEvent(EventPtr e)
+{
+    FormPtr frmP = FrmGetActiveForm();
+
+    if (ResizeHandleEvent(e)) return true;
+
+    kbdint_log(__PRETTY_FUNCTION__);
+
+    switch (e->eType) {
+    case frmOpenEvent:
+        LoadKbdIntForm();
+        FrmDrawForm(frmP);
+        return true;
+        
+    case keyDownEvent:
+        if (!EvtKeydownIsVirtual(e)) {
+            unsigned char c = e->data.keyDown.chr;
+            if (c == '\n'  ||  c == '\r') {
+                // enter in response - Next/OK button
+                // enter in nothing - Next/OK button
+                DoNext();
+                return true;
+            }
+        }
+        return false;
+
+    case sclRepeatEvent:
+        if (e->data.sclRepeat.scrollBarID == 
+            KbdIntFormInstructionScrollbarID)
+        {
+            PrvScrollField(KbdIntFormInstructionFieldID, e);
+        }
+        return false;
+
+    case ctlSelectEvent:
+        switch (e->data.ctlSelect.controlID) {
+        case KbdIntFormNextButtonID:
+            DoNext();
+            return true;
+
+        case KbdIntFormBackButtonID:
+            DoBack();
+            return true;
+
+        case KbdIntFormCancelButtonID:
+            KbdIntSendResponses(false);
+            FrmReturnToForm(0);
+            return true;
+
+        case KbdIntFormEchoCheckboxID:
+            // change response field echoing
+            PrefsPutInt(prefEchoPassword, e->data.ctlSelect.on);
+            SetResponseEcho(e->data.ctlSelect.on);
+            return true;
+
+        default:
+            return false;
+        }
+
+    case frmCloseEvent:
+        // clear entered response, if any
+        ForgetResponse();
+        return false;
+
+    case usrSetFocusEvent:
+        PrvReallySetFocus(frmP, e);
+        return true;
+
+    default:
+        return false;
+    }
+}
+
diff --git a/forms/kbdintform.h b/forms/kbdintform.h
new file mode 100644 (file)
index 0000000..24c0b1c
--- /dev/null
@@ -0,0 +1,36 @@
+/**********
+ * Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef KBDINTFORM_H
+#define KBDINTFORM_H
+
+#include "includes.h"
+
+struct prompt_t;
+
+Boolean KbdIntFormHandleEvent(EventPtr e) FORMS_SEGMENT;
+
+void KbdIntGetResponses(char *name, char *instructions, struct prompt_t *prompts, int prompt_count) FORMS_SEGMENT;
+
+#endif
diff --git a/forms/keyboardprefsform.c b/forms/keyboardprefsform.c
new file mode 100644 (file)
index 0000000..b1fd900
--- /dev/null
@@ -0,0 +1,116 @@
+/**********
+ * Copyright (c) 2004-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "formutils.h"
+#include "data/prefs.h"
+#include "ssh/ssh.h"
+#include "rsrc/rsrc.h"
+#include "forms/resize.h"
+
+#include "keyboardprefsform.h"
+
+
+static void LoadKeyboardPrefsForm(void) FORMS_SEGMENT;
+static void SaveKeyboardPrefsForm(void) FORMS_SEGMENT;
+
+static void LoadKeyboardPrefsForm(void)
+{
+    uint32_t value;
+
+    // backspace behavior
+    value = PrefsGetInt(prefBackspace, defaultBackspace);
+    PrvSetControlValue(KeyboardPrefsFormBackspaceDELCheckboxID, 
+                       value == backspaceDEL ? 1 : 0);
+    PrvSetControlValue(KeyboardPrefsFormBackspaceBSCheckboxID,  
+                       value == backspaceBS ? 1 : 0);
+
+    // backquote behavior
+    value = PrefsGetInt(prefBackquote, defaultBackquote);
+    PrvSetControlValue(KeyboardPrefsFormBackquoteNormalCheckboxID, 
+                       value == backquoteNormal ? 1 : 0);
+    PrvSetControlValue(KeyboardPrefsFormBackquoteESCCheckboxID,  
+                       value == backquoteESC ? 1 : 0);
+}
+
+
+static void SaveKeyboardPrefsForm(void)
+{
+    uint32_t value;
+
+    // backspace behavior
+    value = PrefsGetInt(prefBackspace, defaultBackspace);
+    if (PrvGetControlValue(KeyboardPrefsFormBackspaceDELCheckboxID) && value != backspaceDEL) {
+        PrefsPutInt(prefBackspace, backspaceDEL);
+    } else if (PrvGetControlValue(KeyboardPrefsFormBackspaceBSCheckboxID) && value != backspaceBS) {
+        PrefsPutInt(prefBackspace, backspaceBS);
+    }
+
+    // backquote behavior
+    value = PrefsGetInt(prefBackquote, defaultBackquote);
+    if (PrvGetControlValue(KeyboardPrefsFormBackquoteNormalCheckboxID) && value != backquoteNormal) {
+        PrefsPutInt(prefBackquote, backquoteNormal);
+    } else if (PrvGetControlValue(KeyboardPrefsFormBackquoteESCCheckboxID) && value != backquoteESC) {
+        PrefsPutInt(prefBackquote, backquoteESC);
+    }
+}
+
+
+Boolean KeyboardPrefsFormHandleEvent(EventPtr e)
+{
+    FormPtr frmP = FrmGetActiveForm();
+
+    if (ResizeHandleEvent(e)) return true;
+
+    switch (e->eType) {
+    case frmOpenEvent:
+        LoadKeyboardPrefsForm();
+        FrmDrawForm(frmP);
+        return true;
+
+    case ctlSelectEvent:
+        switch (e->data.ctlSelect.controlID) {
+        case KeyboardPrefsFormOKButtonID:
+            // save values; leave form
+            SaveKeyboardPrefsForm();
+            FrmReturnToForm(0);
+            return true;
+
+        case KeyboardPrefsFormCancelButtonID:
+            // DON'T save values; leave form
+            FrmReturnToForm(0);
+            return true;
+
+        default:
+            return false;
+        }
+
+    case frmCloseEvent:
+        return false;
+
+    default:
+        return false;
+    }
+}
+
diff --git a/forms/keyboardprefsform.h b/forms/keyboardprefsform.h
new file mode 100644 (file)
index 0000000..62e268b
--- /dev/null
@@ -0,0 +1,32 @@
+/**********
+ * Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef KEYBOARDPREFSFORM_H
+#define KEYBOARDPREFSFORM_H
+
+#include "includes.h"
+
+Boolean KeyboardPrefsFormHandleEvent(EventPtr e) FORMS_SEGMENT;
+
+#endif
diff --git a/forms/loginform.c b/forms/loginform.c
new file mode 100644 (file)
index 0000000..f92e70f
--- /dev/null
@@ -0,0 +1,134 @@
+/**********
+ * Copyright (c) 2003-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "formutils.h"
+#include "data/connectionlist.h"
+#include "rsrc/rsrc.h"
+#include "forms/resize.h"
+
+#include "loginform.h"
+
+
+static Boolean ValidateLoginForm(void) FORMS_SEGMENT;
+static Boolean SaveLoginForm(void) FORMS_SEGMENT;
+static void LoadEmptyLoginForm(void) FORMS_SEGMENT;
+
+
+static Boolean ValidateLoginForm(void)
+{
+    return true; // fixme
+}
+
+
+// returns FALSE if save failed for some reason
+// if save fails, caller shouldn't connect
+static Boolean SaveLoginForm(void)
+{
+    FieldPtr hostFld = PrvGetObjectByID(LoginFormHostFieldID);
+    FieldPtr portFld = PrvGetObjectByID(LoginFormPortFieldID);
+    FieldPtr userFld = PrvGetObjectByID(LoginFormUsernameFieldID);
+
+    if (FldDirty(hostFld)  ||  FldDirty(portFld)  ||  FldDirty(userFld)) {
+        return ConnectionListWriteSelectedRecord(hostFld, portFld, userFld);
+    } else {
+        return true;
+    }
+}
+
+
+static void LoadEmptyLoginForm(void)
+{
+    // set port field to default value; leave others empty
+    PrvSetFieldToValueByID(LoginFormPortFieldID, "22");
+    PrvSetFocusByID(LoginFormHostFieldID);
+}
+
+
+Boolean LoginFormHandleEvent(EventPtr e)
+{
+    FormPtr frmP = FrmGetActiveForm();
+
+    if (ResizeHandleEvent(e)) return true;
+
+    switch (e->eType) {
+    case frmOpenEvent: {
+        // "Connect" with nothing selected, or "New..."
+        LoadEmptyLoginForm();
+        FrmDrawForm(frmP);
+        return true;
+    }
+
+    case ctlSelectEvent:
+        switch (e->data.ctlSelect.controlID) {
+        case LoginFormConnectButtonID:
+            // make sure form data is good enough to use for a connection
+            if (!ValidateLoginForm()) break;
+            // Clear selection as late as possible
+            ConnectionListClearSelection();
+            if (SaveLoginForm()) {
+                // login info saved to ConnectionList selected record
+                // go to TerminalForm which will initiate connection
+                FrmReturnToForm(0);
+                FrmGotoForm(TerminalFormID);
+            } else {
+                // failed to save login info
+                // fixme
+                FrmReturnToForm(0);
+            }
+            break;
+
+        case LoginFormCancelButtonID:
+            // return to main form
+            FrmReturnToForm(0);
+            break;
+
+        case LoginFormSaveButtonID:
+            // save login info, return to main form
+            // Don't validate - let the user enter anything
+            ConnectionListClearSelection();
+            if (!SaveLoginForm()) {
+                // failed to save login info
+                // fixme
+            }
+            FrmReturnToForm(0);
+            break;
+
+        default:
+            break;
+        }
+
+        return true;
+
+    case frmCloseEvent:
+        return false;
+
+    case usrSetFocusEvent:
+        PrvReallySetFocus(frmP, e);
+        return true;
+
+    default: 
+        return false;
+    }
+}
diff --git a/forms/loginform.h b/forms/loginform.h
new file mode 100644 (file)
index 0000000..dc41b03
--- /dev/null
@@ -0,0 +1,32 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef LOGINFORM_H
+#define LOGINFORM_H
+
+#include "includes.h"
+
+Boolean LoginFormHandleEvent(EventPtr e) FORMS_SEGMENT;
+
+#endif
diff --git a/forms/mainform.c b/forms/mainform.c
new file mode 100644 (file)
index 0000000..09b3ab0
--- /dev/null
@@ -0,0 +1,123 @@
+/**********
+ * Copyright (c) 2003-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "about.h"
+#include "formutils.h"
+#include "forms/resize.h"
+#include "data/connectionlist.h"
+#include "rsrc/rsrc.h"
+
+#include "mainform.h"
+
+
+
+
+Boolean MainFormHandleEvent(EventPtr e)
+{
+    FormPtr frmP = FrmGetActiveForm();
+
+    if (ResizeHandleEvent(e)) return true;
+    if (ConnectionListHandleEvent(e)) return true;
+
+    switch (e->eType) {
+    case frmOpenEvent:
+        ConnectionListUpdate();
+        FrmDrawForm(frmP);
+        return true;
+
+    case menuEvent:
+        switch (e->data.menu.itemID) {
+        case MenuConnect:
+            if (ConnectionListSelectedIndex() == noRecord) {
+                FrmPopupForm(LoginFormID);
+            } else {
+                FrmGotoForm(TerminalFormID);
+            }
+            return true;
+        case MenuHostKeys:
+            FrmPopupForm(HostKeysFormID);
+            return true;
+        case MenuAboutPalmSSH:
+            FrmPopupForm(AboutFormID);
+            return true;
+        case MenuCredits:
+            FrmPopupForm(CreditsFormID);
+            return true;
+        case MenuDisplaySettings:
+            FrmPopupForm(DisplayPrefsFormID);
+            return true;
+        case MenuConnectionSettings:
+            FrmPopupForm(ConnectionPrefsFormID);
+            return true;
+        case MenuKeyboardSettings:
+            FrmPopupForm(KeyboardPrefsFormID);
+            return true;
+        case MenuPublicKeys:
+            FrmPopupForm(PublicKeysFormID);
+            return true;
+        default:
+            return false;
+        }
+
+    case ctlSelectEvent:
+        switch (e->data.ctlSelect.controlID) {
+        case MainConnectButtonID:
+            if (ConnectionListSelectedIndex() == noRecord) {
+                FrmPopupForm(LoginFormID);
+            } else {
+                FrmGotoForm(TerminalFormID);
+            }
+            break;
+
+        case MainNewButtonID:
+            FrmPopupForm(LoginFormID);
+            break;
+
+        case MainDetailsButtonID:
+            if (ConnectionListSelectedIndex() != noRecord) {
+                FrmPopupForm(DetailsFormID);
+            }
+            break;
+        }
+        return false;
+
+    case frmCloseEvent:
+        return false;
+
+    default: 
+        return false;
+    }
+}
+
+
+void MainFormResize(FormPtr frmP, Int16 dh, Int16 dv)
+{
+    static Int16 height = -1;
+    PrvResizeTableAndScrollbar(frmP, dh, dv, 0, &height, 
+                               FrmGetObjectIndex(frmP, MainConnectionTableID), 
+                               FrmGetObjectIndex(frmP, MainConnectionScrollbarID));
+
+    ConnectionListUpdate();
+}
diff --git a/forms/mainform.h b/forms/mainform.h
new file mode 100644 (file)
index 0000000..fa273b0
--- /dev/null
@@ -0,0 +1,33 @@
+/**********
+ * Copyright (c) 2003-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef MAINFORM_H
+#define MAINFORM_H
+
+#include "includes.h"
+
+Boolean MainFormHandleEvent(EventPtr e) FORMS_SEGMENT;
+void MainFormResize(FormPtr frmP, Int16 dh, Int16 dv) FORMS_SEGMENT;
+
+#endif
diff --git a/forms/memoform.c b/forms/memoform.c
new file mode 100644 (file)
index 0000000..800797d
--- /dev/null
@@ -0,0 +1,172 @@
+/**********
+ * Copyright (c) 2004-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "ctype.h"
+#include "formutils.h"
+#include "forms/passphraseform.h"
+#include "forms/resize.h"
+#include "data/memolist.h"
+#include "data/publickeys.h"
+#include "rsrc/rsrc.h"
+#include "ssh/keyimport.h"
+
+#include "memoform.h"
+
+
+static Boolean ImportKeyFromMemo(void) FORMS_SEGMENT;
+
+
+static Boolean ImportKeyFromMemo(void) 
+{
+    Boolean ok = true;
+    Boolean encrypted;
+    char *memoP, *memoEnd;
+    char comment[81];
+    uint16_t commentLen;
+    char *lineEnd, *lineEndR, *lineEndN;
+    char *passphrase = NULL;
+    Key *key = NULL;
+    MemHandle memoH = MemoListQuerySelectedRecord();
+    if (!memoH) return false;
+
+    memoP = MemHandleLock(memoH);
+    memoEnd = memoP + MemPtrSize(memoP);
+
+    // first line (up to 80 chars) is comment
+    // UNLESS it looks like a key instead
+    if (0 == strncmp(memoP, "-----BEGIN", 10)) {
+        // no comment
+        lineEnd = memoP;
+        strcpy(comment, "unnamed key");
+        commentLen = strlen("unnamed key");
+    } else {
+        lineEnd = memoEnd;
+        lineEndR = strchr(memoP, '\r');
+        lineEndN = strchr(memoP, '\n');
+        if (lineEndR && lineEndR < lineEnd) lineEnd = lineEndR;
+        if (lineEndN && lineEndN < lineEnd) lineEnd = lineEndN;
+        commentLen = MIN(sizeof(comment)-1, lineEnd - memoP);
+        memcpy(comment, memoP, commentLen);
+        comment[commentLen] = '\0';
+        while (isspace(*lineEnd)) lineEnd++; // skip any whitespace before key data
+    }
+
+    encrypted = openssh_encrypted(lineEnd, memoEnd - lineEnd);
+
+    if (encrypted) {
+        passphrase = GetPassphrase(comment);
+        // empty passphrase is returned as empty string
+        // user cancel is returned as NULL;
+        ok = (passphrase != NULL);
+    }
+
+    if (ok) {
+        key = openssh_read(lineEnd, memoEnd - lineEnd, passphrase);
+        ok = (key != NULL);
+        if (!ok) {
+            FrmCustomAlert(AlertFormID, "Incorrect passphrase, or incorrectly formatted memo", " ", " "); // fixme better diagnostics
+        }
+    }
+    if (ok) {
+        ok = SaveImportedPublicKey(encrypted, comment, commentLen, key, 
+                                   lineEnd, memoEnd - lineEnd);
+        if (!ok) {
+            FrmCustomAlert(AlertFormID, "Couldn't save key record", " ", " ");
+        }
+    }
+
+    if (ok) {
+        // fixme
+        FrmCustomAlert(AlertFormID, "Successfully imported key '", comment, "'.");
+    }
+
+    if (key) key_free(key);
+    if (passphrase) arena_free(passphrase);
+
+    MemHandleUnlock(memoH);
+
+    return ok;
+}
+
+
+Boolean MemoFormHandleEvent(EventPtr e)
+{
+    static int inited = 0;
+
+    FormPtr frmP = FrmGetActiveForm();
+
+    if (ResizeHandleEvent(e)) return true;
+    if (MemoListHandleEvent(e)) return true;
+
+    switch (e->eType) {
+    case frmOpenEvent:
+        if (!inited) {
+            MemoListInit(); // allowed to fail == no memos
+            inited = 1;
+        }
+        MemoListUpdate();
+        FrmDrawForm(frmP);
+        return true;
+
+    case ctlSelectEvent:
+        switch (e->data.ctlSelect.controlID) {
+
+        case MemoFormCancelButtonID:
+            FrmReturnToForm(0);
+            break;
+
+        case MemoFormImportButtonID:
+            if (MemoListSelectedIndex() != noRecord) {
+                if (ImportKeyFromMemo()) {
+                    // successfully got a key - kill this form
+                    FrmReturnToForm(0);
+                }
+            }
+            break;
+
+        default: 
+            break;
+
+        }
+        return false;
+
+    case frmCloseEvent:
+        return false;
+
+    default: 
+        return false;
+    }
+}
+
+
+void MemoFormResize(FormPtr frmP, Int16 dh, Int16 dv)
+{
+    static Int16 height = -1;
+    PrvResizeTableAndScrollbar(frmP, dh, dv, 0, &height, 
+                               FrmGetObjectIndex(frmP, MemoFormTableID),
+                               FrmGetObjectIndex(frmP, MemoFormScrollbarID));
+
+    MemoListUpdate();
+}
diff --git a/forms/memoform.h b/forms/memoform.h
new file mode 100644 (file)
index 0000000..c722645
--- /dev/null
@@ -0,0 +1,33 @@
+/**********
+ * Copyright (c) 2004-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef MEMOFORM_H
+#define MEMOFORM_H
+
+#include "includes.h"
+
+Boolean MemoFormHandleEvent(EventPtr e) FORMS_SEGMENT;
+void MemoFormResize(FormPtr frmP, Int16 dh, Int16 dv) FORMS_SEGMENT;
+
+#endif
diff --git a/forms/passphraseform.c b/forms/passphraseform.c
new file mode 100644 (file)
index 0000000..ba54b4d
--- /dev/null
@@ -0,0 +1,199 @@
+/**********
+ * Copyright (c) 2004-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "formutils.h"
+#include "data/connectionlist.h"
+#include "data/prefs.h"
+#include "rsrc/rsrc.h"
+#include "ssh/ssh.h"
+#include "forms/resize.h"
+
+#include "passphraseform.h"
+
+static char *PassphraseFormKeyName = ""; // in
+static char *PassphraseFormPassphrase = NULL; // out - must be freed elsewhere
+
+
+static void RetrievePassphrase(void) FORMS_SEGMENT;
+static void ForgetPassphrase(void) FORMS_SEGMENT;
+static void SetPassphraseEcho(Boolean echo) FORMS_SEGMENT;
+static Boolean LoadPassphraseForm(void) FORMS_SEGMENT;
+
+extern struct ssh_session_t *ss;
+
+
+static void RetrievePassphrase(void)
+{
+    FieldPtr passphraseFld = PrvGetObjectByID(PassphraseFormPassphraseFieldID);
+    MemHandle passphraseH;
+    char *passphrase;
+
+    FldReleaseFocus(passphraseFld);
+    FldCompactText(passphraseFld);
+    passphraseH = FldGetTextHandle(passphraseFld);
+    FldSetTextHandle(passphraseFld, NULL);
+
+    if (passphraseH) {
+        passphrase = MemHandleLock(passphraseH);
+    } else {
+        passphrase = "";
+    }
+
+    PassphraseFormPassphrase = arena_strdup(passphrase);
+
+    if (passphraseH) {
+        MemSet(passphrase, MemHandleSize(passphraseH), 0);
+        MemHandleUnlock(passphraseH);
+        MemHandleFree(passphraseH);
+    }
+}
+
+
+static void ForgetPassphrase(void)
+{
+    FieldPtr passphraseFld = PrvGetObjectByID(PassphraseFormPassphraseFieldID);
+    MemHandle passphraseH;
+
+    FldReleaseFocus(passphraseFld);
+    FldCompactText(passphraseFld);
+    passphraseH = FldGetTextHandle(passphraseFld);
+    FldSetTextHandle(passphraseFld, NULL);
+
+    if (passphraseH) {
+        MemSet(MemHandleLock(passphraseH), MemHandleSize(passphraseH), 0);
+        MemHandleUnlock(passphraseH);
+        MemHandleFree(passphraseH);
+    }
+}
+
+
+static void SetPassphraseEcho(Boolean echo)
+{
+    PrvSetControlValue(PassphraseFormEchoCheckboxID, echo);
+    FldSetFont(PrvGetObjectByID(PassphraseFormPassphraseFieldID), 
+               echo ? stdFont : (FontID)PasswordFontID);
+}
+
+
+static Boolean LoadPassphraseForm(void)
+{
+    Boolean ok = true;
+    char *message;
+    char *msgStart = "Enter passphrase for key '";
+    char *msgEnd = "':";
+
+    message = arena_malloc(strlen(msgStart) + strlen(msgEnd) + 
+                           strlen(PassphraseFormKeyName) + 1);
+    strcpy(message, msgStart);
+    strncat(message, PassphraseFormKeyName, 80);
+    strcat(message, msgEnd);
+
+    if (ok) ok = PrvSetFieldToValueByID(PassphraseFormMessageFieldID, message);
+    arena_free(message);
+    if (!ok) complain("bad 1");
+
+    if (ok) PrvSetFocusByID(PassphraseFormPassphraseFieldID);
+
+    if (ok) SetPassphraseEcho(PrefsGetInt(prefEchoPassword, 0));
+
+    return ok;
+}
+
+
+Boolean PassphraseFormHandleEvent(EventPtr e)
+{
+    FormPtr frmP = FrmGetActiveForm();
+
+    if (ResizeHandleEvent(e)) return true;
+
+    switch (e->eType) {
+    case frmOpenEvent:
+        LoadPassphraseForm();
+        FrmDrawForm(frmP);
+        return true;
+
+    case ctlSelectEvent:
+        switch (e->data.ctlSelect.controlID) {
+        case PassphraseFormOKButtonID:
+            // stash passphrase in global
+            RetrievePassphrase();
+            // return FALSE so FrmDoDialog will return
+            return false;
+
+        case PassphraseFormCancelButtonID:
+            // return FALSE so FrmDoDialog will return
+            return false;
+
+        case PassphraseFormEchoCheckboxID:
+            // change password field echoing
+            PrefsPutInt(prefEchoPassword, e->data.ctlSelect.on);
+            SetPassphraseEcho(e->data.ctlSelect.on);
+            return true;
+
+        default:
+            return false;
+        }
+
+    case frmCloseEvent:
+        // clear entered passphrase, if any
+        ForgetPassphrase();
+        return false;
+
+    case usrSetFocusEvent:
+        PrvReallySetFocus(frmP, e);
+        return true;
+
+    default:
+        return false;
+    }
+}
+
+
+char *GetPassphrase(char *comment) 
+{
+    FormPtr frm;
+    char *result;
+    EventType event;
+
+    PassphraseFormKeyName = comment;
+
+    frm = FrmInitForm(PassphraseFormID);
+    FrmSetEventHandler(frm, PassphraseFormHandleEvent);
+
+    // send frmOpenEvent
+    event.eType = frmOpenEvent;
+    event.data.frmLoad.formID = PassphraseFormID;
+    EvtAddEventToQueue(&event);
+
+    FrmDoDialog(frm);
+    FrmDeleteForm(frm);
+
+    // result will be NULL on cancel and "" on empty passphrase
+    result = PassphraseFormPassphrase;
+    PassphraseFormKeyName = NULL;
+    PassphraseFormPassphrase = NULL;
+
+    return result;
+}
diff --git a/forms/passphraseform.h b/forms/passphraseform.h
new file mode 100644 (file)
index 0000000..f67bd5f
--- /dev/null
@@ -0,0 +1,33 @@
+/**********
+ * Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef PASSPHRASEFORM_H
+#define PASSPHRASEFORM_H
+
+#include "includes.h"
+
+char *GetPassphrase(char *comment) FORMS_SEGMENT;
+Boolean PassphraseFormHandleEvent(EventPtr e) FORMS_SEGMENT;
+
+#endif
diff --git a/forms/passwordform.c b/forms/passwordform.c
new file mode 100644 (file)
index 0000000..b6b3ee9
--- /dev/null
@@ -0,0 +1,243 @@
+/**********
+ * Copyright (c) 2003-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "formutils.h"
+#include "data/connectionlist.h"
+#include "data/prefs.h"
+#include "rsrc/rsrc.h"
+#include "ssh/ssh.h"
+#include "forms/resize.h"
+
+#include "passwordform.h"
+
+
+static Boolean RetrieveUsernameAndPassword(void) FORMS_SEGMENT;
+static void ForgetPassword(void) FORMS_SEGMENT;
+static void SetPasswordEcho(Boolean echo) FORMS_SEGMENT;
+static Boolean LoadPasswordForm(void) FORMS_SEGMENT;
+
+extern struct ssh_session_t *ss;
+
+
+static Boolean RetrieveUsernameAndPassword(void)
+{
+    FieldPtr usernameFld = PrvGetObjectByID(PasswordFormUsernameFieldID);
+    FieldPtr passwordFld = PrvGetObjectByID(PasswordFormPasswordFieldID);
+    MemHandle usernameH;
+    MemHandle passwordH;
+    char *username;
+    char *password;
+
+    FldReleaseFocus(usernameFld);
+    FldCompactText(usernameFld);
+    usernameH = FldGetTextHandle(usernameFld);
+    FldSetTextHandle(usernameFld, NULL);
+
+    FldReleaseFocus(passwordFld);
+    FldCompactText(passwordFld);
+    passwordH = FldGetTextHandle(passwordFld);
+    FldSetTextHandle(passwordFld, NULL);
+
+    if (usernameH) {
+        username = MemHandleLock(usernameH);
+    } else {
+        username = "";
+    }
+
+    if (passwordH) {
+        password = MemHandleLock(passwordH);
+    } else {
+        password = "";
+    }
+
+    ssh_use_password(ss, username, password);
+
+    if (usernameH) {
+        MemHandleUnlock(usernameH);
+        MemHandleFree(usernameH);
+    }
+
+    if (passwordH) {
+        MemSet(password, MemHandleSize(passwordH), 0);
+        MemHandleUnlock(passwordH);
+        MemHandleFree(passwordH);
+    }
+
+    return true;
+}
+
+
+static void ForgetPassword(void)
+{
+    FieldPtr passwordFld = PrvGetObjectByID(PasswordFormPasswordFieldID);
+    MemHandle passwordH;
+
+    FldReleaseFocus(passwordFld);
+    FldCompactText(passwordFld);
+    passwordH = FldGetTextHandle(passwordFld);
+    FldSetTextHandle(passwordFld, NULL);
+
+    if (passwordH) {
+        MemSet(MemHandleLock(passwordH), MemHandleSize(passwordH), 0);
+        MemHandleUnlock(passwordH);
+        MemHandleFree(passwordH);
+    }
+}
+
+
+static void SetPasswordEcho(Boolean echo)
+{
+    PrvSetControlValue(PasswordFormEchoCheckboxID, echo);
+    FldSetFont(PrvGetObjectByID(PasswordFormPasswordFieldID), 
+               echo ? stdFont : (FontID)PasswordFontID);
+}
+
+
+static Boolean LoadPasswordForm(void)
+{
+    MemHandle recordH;
+    Boolean ok = true;
+    char *hostname;
+    char *username;
+    char *portname;
+
+    recordH=ConnectionListReadSelectedRecord(&hostname, &portname, &username);
+    if (!recordH) return false;
+
+    if (ok) ok = PrvSetFieldToValueByID(PasswordFormHostFieldID, hostname);
+    if (ok) ok = PrvSetFieldToValueByID(PasswordFormUsernameFieldID, username);
+
+    if (ok) {
+        if (StrLen(username) == 0) {
+            // missing username - set caret to username
+            PrvSetFocusByID(PasswordFormUsernameFieldID);
+        } else {
+            // username ok - set caret to password
+            PrvSetFocusByID(PasswordFormPasswordFieldID);
+        }
+    }
+
+    if (ok) SetPasswordEcho(PrefsGetInt(prefEchoPassword, 0));
+
+    MemHandleUnlock(recordH);
+
+    return ok;
+}
+
+
+static void DoOK(void) 
+{
+    // send username and password to connection
+    if (RetrieveUsernameAndPassword()) {
+        // return to terminal form
+        FrmReturnToForm(0);
+    } else {
+        // password extraction failed
+        // close connection and return to terminal form
+        ssh_close(ss);
+        FrmReturnToForm(0);
+    }
+}
+
+
+Boolean PasswordFormHandleEvent(EventPtr e)
+{
+    FormPtr frmP = FrmGetActiveForm();
+
+    if (ResizeHandleEvent(e)) return true;
+
+    switch (e->eType) {
+    case frmOpenEvent:
+        if (!LoadPasswordForm()) {
+            // load failed - go back to terminal form
+            FrmReturnToForm(0);
+        } else {
+            FrmDrawForm(frmP);
+        }
+        return true;
+        
+    case keyDownEvent:
+        if (!EvtKeydownIsVirtual(e)) {
+            unsigned char c = e->data.keyDown.chr;
+            if (c == '\n'  ||  c == '\r') {
+                // enter in username - switch to password
+                // enter in password - OK button
+                // enter in neither - OK button
+                UInt16 focusID;
+                UInt16 focusIndex = FrmGetFocus(FrmGetActiveForm());
+                if (focusIndex == noFocus) {
+                    DoOK();
+                    return true;
+                } 
+                focusID = FrmGetObjectId(FrmGetActiveForm(), focusIndex);
+                if (focusID == PasswordFormUsernameFieldID) {
+                    PrvSetFocusByID(PasswordFormPasswordFieldID);
+                    PrvFieldSelectAll(PasswordFormPasswordFieldID);
+                    return true;
+                } else if (focusID == PasswordFormPasswordFieldID) {
+                    DoOK();
+                    return true;
+                }
+            }
+        }
+        return false;
+
+    case ctlSelectEvent:
+        switch (e->data.ctlSelect.controlID) {
+        case PasswordFormOKButtonID:
+            DoOK();
+            return true;
+
+        case PasswordFormCancelButtonID:
+            // close connection, return to terminal form
+            ssh_close(ss);
+            FrmReturnToForm(0);
+            return true;
+
+        case PasswordFormEchoCheckboxID:
+            // change password field echoing
+            PrefsPutInt(prefEchoPassword, e->data.ctlSelect.on);
+            SetPasswordEcho(e->data.ctlSelect.on);
+            return true;
+
+        default:
+            return false;
+        }
+
+    case frmCloseEvent:
+        // fixme this doesn't get called with FrmReturnToForm()
+        // clear entered password, if any
+        ForgetPassword();
+        return false;
+
+    case usrSetFocusEvent:
+        PrvReallySetFocus(frmP, e);
+        return true;
+
+    default:
+        return false;
+    }
+}
+
diff --git a/forms/passwordform.h b/forms/passwordform.h
new file mode 100644 (file)
index 0000000..e113480
--- /dev/null
@@ -0,0 +1,32 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef PASSWORDFORM_H
+#define PASSWORDFORM_H
+
+#include "includes.h"
+
+Boolean PasswordFormHandleEvent(EventPtr e) FORMS_SEGMENT;
+
+#endif
diff --git a/forms/publickeychoiceform.c b/forms/publickeychoiceform.c
new file mode 100644 (file)
index 0000000..30f76b4
--- /dev/null
@@ -0,0 +1,323 @@
+/**********
+ * Copyright (c) 2004-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "formutils.h"
+#include "data/connectionlist.h"
+#include "data/publickeys.h"
+#include "data/prefs.h"
+#include "rsrc/rsrc.h"
+#include "ssh/ssh.h"
+#include "forms/resize.h"
+
+#include "publickeychoiceform.h"
+
+
+static Boolean RetrieveUsernameAndPassphrase(void) FORMS_SEGMENT;
+static void ForgetPassphrase(void) FORMS_SEGMENT;
+static void SetPassphraseEcho(Boolean echo) FORMS_SEGMENT;
+static Boolean LoadPublicKeyChoiceForm(void) FORMS_SEGMENT;
+
+extern struct ssh_session_t *ss;
+
+queue_t *PublicKeyChoiceKeys = NULL;
+
+static char **key_names = NULL;
+static MemHandle *key_handles = NULL;
+static uint16_t key_count = 0;
+
+
+static Boolean RetrieveUsernameAndPassphrase(void)
+{
+    // fixme retrieve popup choice too
+    FieldPtr usernameFld = PrvGetObjectByID(PublicKeyChoiceFormUsernameFieldID);
+    FieldPtr passphraseFld = PrvGetObjectByID(PublicKeyChoiceFormPassphraseFieldID);
+    MemHandle usernameH;
+    MemHandle passphraseH;
+    char *username;
+    char *passphrase;
+    Boolean ok;
+    int keyIndex;
+
+    FldReleaseFocus(usernameFld);
+    FldCompactText(usernameFld);
+    usernameH = FldGetTextHandle(usernameFld);
+
+    FldReleaseFocus(passphraseFld);
+    FldCompactText(passphraseFld);
+    passphraseH = FldGetTextHandle(passphraseFld);
+
+    if (usernameH) {
+        username = MemHandleLock(usernameH);
+    } else {
+        username = "";
+    }
+
+    if (passphraseH) {
+        passphrase = MemHandleLock(passphraseH);
+    } else {
+        passphrase = "";
+    }
+
+    keyIndex = LstGetSelection(PrvGetObjectByID(PublicKeyChoiceFormKeyListID));
+    if (keyIndex == noListSelection) {
+        complain("no selection");
+        ok = false;
+    } else {
+        ok = ssh_use_passphrase(ss, username, passphrase, key_handles[keyIndex]);
+    }
+
+    if (usernameH) MemHandleUnlock(usernameH);
+    if (passphraseH) MemHandleUnlock(passphraseH);
+
+    if (!ok) {
+        // password wrong - try again
+        // leave username field alone and clear passphrase field
+        PrvSetFieldToValue(passphraseFld, "");
+        FldEraseField(passphraseFld);
+        FldDrawField(passphraseFld);
+        PrvSetFocusByID(PublicKeyChoiceFormPassphraseFieldID);
+    } else {
+        // password ok - clean up field contents
+        if (usernameH) {
+            FldSetTextHandle(usernameFld, NULL);
+            MemHandleFree(usernameH);
+        }
+
+        if (passphraseH) {
+            FldSetTextHandle(passphraseFld, NULL);
+            MemSet(MemHandleLock(passphraseH), MemHandleSize(passphraseH), 0);
+            MemHandleUnlock(passphraseH);
+            MemHandleFree(passphraseH);
+        }
+    }
+
+    return ok;
+}
+
+
+static void ForgetPassphrase(void)
+{
+    FieldPtr passphraseFld = PrvGetObjectByID(PublicKeyChoiceFormPassphraseFieldID);
+    MemHandle passphraseH;
+
+    FldReleaseFocus(passphraseFld);
+    FldCompactText(passphraseFld);
+    passphraseH = FldGetTextHandle(passphraseFld);
+    FldSetTextHandle(passphraseFld, NULL);
+
+    if (passphraseH) {
+        MemSet(MemHandleLock(passphraseH), MemHandleSize(passphraseH), 0);
+        MemHandleUnlock(passphraseH);
+        MemHandleFree(passphraseH);
+    }
+}
+
+
+static void SetPassphraseEcho(Boolean echo)
+{
+    PrvSetControlValue(PublicKeyChoiceFormEchoCheckboxID, echo);
+    FldSetFont(PrvGetObjectByID(PublicKeyChoiceFormPassphraseFieldID), 
+               echo ? stdFont : (FontID)PasswordFontID);
+}
+
+
+static Boolean LoadPublicKeyChoiceForm(void)
+{
+    MemHandle recordH;
+    Boolean ok = true;
+    char *hostname;
+    char *username;
+    char *portname;
+
+    recordH=ConnectionListReadSelectedRecord(&hostname, &portname, &username);
+    if (!recordH) return false;
+
+    if (ok) ok = PrvSetFieldToValueByID(PublicKeyChoiceFormHostFieldID, hostname);
+    if (ok) ok = PrvSetFieldToValueByID(PublicKeyChoiceFormUsernameFieldID, username);
+
+    if (ok) {
+        if (StrLen(username) == 0) {
+            // missing username - set caret to username
+            PrvSetFocusByID(PublicKeyChoiceFormUsernameFieldID);
+        } else {
+            // username ok - set caret to passphrase
+            PrvSetFocusByID(PublicKeyChoiceFormPassphraseFieldID);
+        }
+    }
+
+    {
+        // populate public key list
+        ListPtr lst;
+        uint16_t i, j;
+        queue_t *q = PublicKeyChoiceKeys;
+
+        // get all pubkey names and handles
+        key_count = queue_count(q);
+        key_names = arena_malloc(key_count * sizeof(char *));
+        key_handles = arena_malloc(key_count * sizeof(MemHandle));
+        for (i = 0; i < key_count; i++) {
+            key_handles[i] = queue_peek(q, i);
+            key_names[i] = NameForPublicKey(key_handles[i]);
+        }
+
+        // sort keys by name to type-select works (bubble sort)
+        for (i = 0; i < key_count; i++) {
+            for (j = i+1; j < key_count; j++) {
+                if (strcmp(key_names[i], key_names[j]) > 0) {
+                    char *tmp_name = key_names[i];
+                    MemHandle tmp_handle = key_handles[i];
+                    key_names[i] = key_names[j];
+                    key_handles[i] = key_handles[j];
+                    key_names[j] = tmp_name;
+                    key_handles[j] = tmp_handle;
+                }
+            }
+        }
+
+        lst = PrvGetObjectByID(PublicKeyChoiceFormKeyListID);
+        LstSetListChoices(lst, key_names, key_count);
+        LstSetHeight(lst, key_count);
+
+        // fixme select a previously-good key for this connection using prefs
+        
+        LstSetSelection(lst, 0);
+        PrvSetControlLabel(PublicKeyChoiceFormKeyTriggerID, key_names[0]);
+    }
+
+    if (ok) SetPassphraseEcho(PrefsGetInt(prefEchoPassword, 0));
+
+    MemHandleUnlock(recordH);
+
+    return ok;
+}
+
+
+static void DoOK(void)
+{
+    // send username and passphrase to connection
+    if (RetrieveUsernameAndPassphrase()) {
+        FrmReturnToForm(0);
+    } else {
+        // passphrase was wrong (probably)
+        FrmCustomAlert(AlertFormID, "Incorrect passphrase.", " ", " ");
+    }
+}
+
+
+Boolean PublicKeyChoiceFormHandleEvent(EventPtr e)
+{
+    FormPtr frmP = FrmGetActiveForm();
+
+    if (ResizeHandleEvent(e)) return true;
+
+    switch (e->eType) {
+    case frmOpenEvent:
+        if (!LoadPublicKeyChoiceForm()) {
+            // load failed - go back to terminal form
+            FrmReturnToForm(0);
+        } else {
+            FrmDrawForm(frmP);
+        }
+        return true;
+
+    case keyDownEvent:
+        if (!EvtKeydownIsVirtual(e)) {
+            unsigned char c = e->data.keyDown.chr;
+            if (c == '\n'  ||  c == '\r') {
+                // enter in username - switch to password
+                // enter in password - OK button
+                // enter in neither - OK button
+                UInt16 focusID;
+                UInt16 focusIndex = FrmGetFocus(FrmGetActiveForm());
+                if (focusIndex == noFocus) {
+                    DoOK();
+                    return true;
+                } 
+                focusID = FrmGetObjectId(FrmGetActiveForm(), focusIndex);
+                if (focusID == PublicKeyChoiceFormUsernameFieldID) {
+                    PrvSetFocusByID(PublicKeyChoiceFormPassphraseFieldID);
+                    PrvFieldSelectAll(PublicKeyChoiceFormPassphraseFieldID);
+                    return true;
+                } else if (focusID == PublicKeyChoiceFormPassphraseFieldID) {
+                    DoOK();
+                    return true;
+                }
+            }
+        }
+        return false;
+
+    case ctlSelectEvent:
+        switch (e->data.ctlSelect.controlID) {
+        case PublicKeyChoiceFormOKButtonID:
+            DoOK();
+            return true;
+
+        case PublicKeyChoiceFormCancelButtonID:
+            // skip further pubkey auth (continue to password, probably)
+            FrmReturnToForm(0);
+            ssh_use_passphrase(ss, NULL, NULL, NULL); // this is user cancel
+            return true;
+
+        case PublicKeyChoiceFormEchoCheckboxID:
+            // change passphrase field echoing
+            PrefsPutInt(prefEchoPassword, e->data.ctlSelect.on);
+            SetPassphraseEcho(e->data.ctlSelect.on);
+            return true;
+
+        default:
+            return false;
+        }
+
+    case frmCloseEvent:
+        // clear entered passphrase, if any
+        ForgetPassphrase();
+        // free key names
+        if (key_names) {
+            int i;
+            LstSetListChoices(PrvGetObjectByID(PublicKeyChoiceFormKeyListID), 
+                          NULL, 0);
+            PrvSetControlLabel(PublicKeyChoiceFormKeyTriggerID, "");
+            for (i = 0; i < key_count; i++) {
+                arena_free(key_names[i]);
+            }
+            arena_free(key_names);
+            key_names = NULL;
+            key_count = NULL;
+        }
+        if (key_handles) {
+            arena_free(key_handles);
+            key_handles = NULL;
+        }
+        return false;
+
+    case usrSetFocusEvent:
+        PrvReallySetFocus(frmP, e);
+        return true;
+
+    default:
+        return false;
+    }
+}
+
diff --git a/forms/publickeychoiceform.h b/forms/publickeychoiceform.h
new file mode 100644 (file)
index 0000000..6561f18
--- /dev/null
@@ -0,0 +1,34 @@
+/**********
+ * Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef PUBLICKEYCHOICEFORM_H
+#define PUBLICKEYCHOICEFORM_H
+
+#include "includes.h"
+
+Boolean PublicKeyChoiceFormHandleEvent(EventPtr e) FORMS_SEGMENT;
+
+extern queue_t *PublicKeyChoiceKeys;
+
+#endif
diff --git a/forms/publickeydetailsform.c b/forms/publickeydetailsform.c
new file mode 100644 (file)
index 0000000..b088de9
--- /dev/null
@@ -0,0 +1,198 @@
+/**********
+ * Copyright (c) 2004-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "formutils.h"
+#include "data/publickeys.h"
+#include "rsrc/rsrc.h"
+#include "ssh/openssh/key.h"
+#include "ssh/openssh/uuencode.h"
+#include "forms/resize.h"
+
+#include "publickeydetailsform.h"
+
+
+static Boolean LoadPublicKeyDetailsForm(void) FORMS_SEGMENT;
+static Boolean SavePublicKeyDetailsForm(void) FORMS_SEGMENT;
+
+
+static Boolean LoadPublicKeyDetailsForm(void)
+{
+    Boolean ok = true;
+    MemHandle recordH;
+    Boolean encrypted;
+    char *comment;
+    uint8_t *pubkey;
+    uint16_t pubkeylen;
+    uint8_t *privkey;
+    uint16_t privkeylen;
+    Key *key;
+
+    recordH = PublicKeysQuerySelectedRecord(&encrypted, &comment, 
+                                            &pubkey, &pubkeylen, 
+                                            &privkey, &privkeylen);
+    if (!recordH) return false;
+
+    if (ok) ok = PrvSetFieldToValueByID(PublicKeyDetailsFormCommentFieldID, comment);
+    
+    if (ok) ok = ((key = key_from_blob(pubkey, pubkeylen)) != NULL);
+    if (ok) {
+        char *encrypted_msg = " (encrypted)";
+        char *nonencrypted_msg = " (not encrypted)";
+        char *buf = arena_malloc(strlen(key_type(key)) + strlen(nonencrypted_msg) + 1);
+        strcpy(buf, key_type(key));
+        strcat(buf, encrypted ? encrypted_msg : nonencrypted_msg);
+        ok = PrvSetFieldToValueByID(PublicKeyDetailsFormKeyTypeFieldID, buf);
+        arena_free(buf);
+    }
+    if (ok) {
+        // uuencode(blob) is what OpenSSH uses for public key files
+        uint8_t *uubuf = xmalloc(2*pubkeylen);
+        int uulen = uuencode(pubkey, pubkeylen, uubuf, 2*pubkeylen);
+        if (uulen > 0) {
+            ok = PrvSetFieldToValueByID(PublicKeyDetailsFormKeyFieldID, uubuf);
+        }
+        xfree(uubuf);
+    }
+
+    PrvUpdateScrollbarForField(PublicKeyDetailsFormKeyFieldID, 
+                               PublicKeyDetailsFormKeyScrollbarID);
+
+    MemHandleUnlock(recordH);
+
+    return ok;
+}
+
+
+static Boolean SavePublicKeyDetailsForm(void) 
+{
+    Boolean ok = false;
+    MemHandle recordH;
+    Boolean encrypted;
+    char *comment;
+    uint8_t *pubkey;
+    uint16_t pubkeylen;
+    uint8_t *privkey;
+    uint16_t privkeylen;
+    char *newComment;
+    uint8_t *newpubkey;
+    uint8_t *newprivkey;
+    FieldPtr commentField;
+    MemHandle textH;
+    uint16_t len;
+
+    recordH = PublicKeysQuerySelectedRecord(&encrypted, &comment, 
+                                            &pubkey, &pubkeylen, 
+                                            &privkey, &privkeylen);
+    if (!recordH) return false;
+
+    commentField = PrvGetObjectByID(PublicKeyDetailsFormCommentFieldID);
+    if (! FldDirty(commentField)) {
+        // nothing to do - success
+        return true;
+    }
+
+    // retrieve new comment
+    len = FldGetTextLength(commentField);
+    newComment = arena_malloc(1+len);
+    textH = FldGetTextHandle(commentField);
+    memcpy(newComment, MemHandleLock(textH), len);
+    MemHandleUnlock(textH);
+    newComment[len] = '\0';
+
+    // duplicate old key data
+    newpubkey = arena_malloc(pubkeylen);
+    memcpy(newpubkey, pubkey, pubkeylen);
+
+    newprivkey = arena_malloc(privkeylen);
+    memcpy(newprivkey, privkey, privkeylen);
+
+    // write new record
+    MemHandleUnlock(recordH);
+    ok = WritePublicKeyRecord(encrypted, newComment, 
+                              newpubkey, pubkeylen, 
+                              newprivkey, privkeylen);
+    
+    arena_free(newComment);
+    arena_free(newpubkey);
+    arena_free(newprivkey);
+    
+    return true;
+}
+
+
+Boolean PublicKeyDetailsFormHandleEvent(EventPtr e)
+{
+    FormPtr frmP = FrmGetActiveForm();
+
+    if (ResizeHandleEvent(e)) return true;
+
+    switch (e->eType) {
+    case frmOpenEvent: {
+        LoadPublicKeyDetailsForm();
+        FrmDrawForm(frmP);
+        return true;
+    }
+
+    case sclRepeatEvent:
+        if (e->data.sclRepeat.scrollBarID == 
+            PublicKeyDetailsFormKeyScrollbarID)
+        {
+            PrvScrollField(PublicKeyDetailsFormKeyFieldID, e);
+        }
+        return false;
+
+    case ctlSelectEvent:
+        switch (e->data.ctlSelect.controlID) {
+        case PublicKeyDetailsFormOKButtonID:
+            if (!SavePublicKeyDetailsForm()) {
+                // fixme complain?
+            }
+            FrmReturnToForm(0);
+            break;
+
+        case PublicKeyDetailsFormCancelButtonID:
+            FrmReturnToForm(0);
+            break;
+
+        case PublicKeyDetailsFormDeleteButtonID:
+            if (0 == FrmAlert(DeletePublicKeyAlertID)) {
+                PublicKeysDeleteSelectedRecord();
+                FrmReturnToForm(0);
+            }
+            break;
+
+        default:
+            break;
+        }
+
+        return true;
+
+    case frmCloseEvent:
+        return false;
+
+    default: 
+        return false;
+    }
+}
diff --git a/forms/publickeydetailsform.h b/forms/publickeydetailsform.h
new file mode 100644 (file)
index 0000000..bab0484
--- /dev/null
@@ -0,0 +1,32 @@
+/**********
+ * Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef PUBLICKEYDETAILSFORM_H
+#define PUBLICKEYDETAILSFORM_H
+
+#include "includes.h"
+
+Boolean PublicKeyDetailsFormHandleEvent(EventPtr e) FORMS_SEGMENT;
+
+#endif
diff --git a/forms/publickeysform.c b/forms/publickeysform.c
new file mode 100644 (file)
index 0000000..eab10a0
--- /dev/null
@@ -0,0 +1,87 @@
+/**********
+ * Copyright (c) 2004-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "formutils.h"
+#include "forms/resize.h"
+#include "data/publickeys.h"
+#include "rsrc/rsrc.h"
+
+#include "publickeysform.h"
+
+
+Boolean PublicKeysFormHandleEvent(EventPtr e)
+{
+    FormPtr frmP = FrmGetActiveForm();
+
+    if (ResizeHandleEvent(e)) return true;
+    if (PublicKeysHandleEvent(e)) return true;
+
+    switch (e->eType) {
+    case frmOpenEvent:
+        PublicKeysUpdate();
+        FrmDrawForm(frmP);
+        return true;
+
+    case ctlSelectEvent:
+        switch (e->data.ctlSelect.controlID) {
+
+        case PublicKeysFormOKButtonID:
+            FrmReturnToForm(0);
+            break;
+
+        case PublicKeysFormImportButtonID:
+            FrmPopupForm(MemoFormID);
+            break;
+
+        case PublicKeysFormDetailsButtonID:
+            if (PublicKeysSelectedIndex() != noRecord) {
+                FrmPopupForm(PublicKeyDetailsFormID);
+            }
+            break;
+
+        default: 
+            break;
+
+        }
+        return false;
+
+    case frmCloseEvent:
+        return false;
+
+    default: 
+        return false;
+    }
+}
+
+
+void PublicKeysFormResize(FormPtr frmP, Int16 dh, Int16 dv)
+{
+    static Int16 height = -1;
+    PrvResizeTableAndScrollbar(frmP, dh, dv, 0, &height, 
+                               FrmGetObjectIndex(frmP, PublicKeysFormKeyTableID),
+                               FrmGetObjectIndex(frmP, PublicKeysFormKeyScrollbarID));
+
+    PublicKeysUpdate();
+}
diff --git a/forms/publickeysform.h b/forms/publickeysform.h
new file mode 100644 (file)
index 0000000..5f862d0
--- /dev/null
@@ -0,0 +1,33 @@
+/**********
+ * Copyright (c) 2004-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef PUBLICKEYSFORM_H
+#define PUBLICKEYSFORM_H
+
+#include "includes.h"
+
+Boolean PublicKeysFormHandleEvent(EventPtr e) FORMS_SEGMENT;
+void PublicKeysFormResize(FormPtr frmP, Int16 dh, Int16 dv) FORMS_SEGMENT;
+
+#endif
diff --git a/forms/resize.c b/forms/resize.c
new file mode 100644 (file)
index 0000000..e53c333
--- /dev/null
@@ -0,0 +1,932 @@
+/* $Id: resize.c,v 1.1 2005/05/15 09:06:04 admin Exp $ */
+/*******************************************************************************
+    Copyright (c) 2004, Alexander R. Pruss
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification,
+    are permitted provided that the following conditions are met:
+
+        Redistributions of source code must retain the above copyright notice, this
+        list of conditions and the following disclaimer.
+
+        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.
+
+        Neither the name of the PalmResize Project nor the names of its
+        contributors may be used to endorse or promote products derived from this
+        software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER 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.
+*******************************************************************************/
+
+#include <PalmOS.h>
+#include <LstGlue.h>
+#include <PalmOSGlue.h>
+//#include "util.h"
+#include "DIA.h"
+#ifdef SUPPORT_DIA_HANDERA
+#include <Vga.h>
+#endif
+
+#include "includes.h"
+#include "rsrc/rsrc.h"
+
+static void DebugInfo(const char *format, ...)
+{
+    /*    va_list args;
+    char buf[500];
+    int len;
+
+    len = snprintf(buf, sizeof(buf), "%lu ", TimGetTicks());
+
+    va_start(args, format);
+    vsnprintf(buf+len, sizeof(buf)-len, format, args);
+    va_end(args);
+
+    ClipboardAppendItem(clipboardText, buf, StrLen(buf));
+    */
+}
+
+        
+typedef struct {
+    UInt16    formID;
+    FormType* formPtr;
+    UInt16    index;
+    UInt16    flags;
+    DIAFormEntryType* entry;
+} ResizeTemporaryData;
+
+
+static DIAFormEntryType* formList = NULL;
+static DIAStateType*     bins;
+static UInt16            numBins;
+static UInt16            formCount = 0;
+static ResizeTemporaryData active;
+static Boolean           haveWinDisplayChangedEvent = false;
+
+
+
+RESIZE_SECTION static UInt16 StandardExtent( void )
+{
+#ifdef SUPPORT_DIA_HANDERA
+    if ( GetDIAHardware() == DIA_HARDWARE_HANDERA )
+        return 240;
+    else
+#endif
+        return 160;
+}
+
+
+
+/* Update form, but only once */
+RESIZE_SECTION static void UniqueUpdateForm( UInt16 formID, UInt16 code )
+{
+    EventType e;
+    MemSet( &e, sizeof(EventType), 0 );
+    e.eType                     = frmUpdateEvent;
+    e.data.frmUpdate.formID     = formID;
+    e.data.frmUpdate.updateCode = code;
+    EvtAddUniqueEventToQueue( &e, 0, true );
+    DebugInfo("Queuing frmUpdateForm");
+}
+
+
+
+/* Same as FrmGetObjectIndex() but works with GSI_OBJECT_ID, too */
+RESIZE_SECTION static UInt16 MyFrmGetObjectIndex( FormPtr formPtr, UInt16 id )
+{
+    UInt16 i;
+    if ( id != GSI_OBJECT_ID )
+        return FrmGetObjectIndex( formPtr, id );
+    for ( i = FrmGetNumberOfObjects( formPtr ) - 1 ; 0 < i ; i -- ) {
+        if ( FrmGetObjectType( formPtr, i ) == frmGraffitiStateObj ) {
+            return i;
+        }
+    }
+    return 0;
+}
+
+
+
+RESIZE_SECTION static void WinGlueGetBounds( WinHandle winH, RectangleType* rect )
+{
+    Err     err;
+    UInt32  version;
+    err = FtrGet( sysFtrCreator, sysFtrNumROMVersion, &version );
+    if ( err == errNone && 0x04003000 <= version ) {
+        WinGetBounds( winH, rect );
+    }
+    else {
+        WinHandle oldH;
+        oldH = WinSetDrawWindow( winH );
+        WinGetDrawWindowBounds( rect );
+        WinSetDrawWindow( oldH );
+    }
+}
+
+
+
+RESIZE_SECTION static void SafeFrmGetObjectBounds
+    (
+    const FormType* formPtr,
+    UInt16 objectIndex,
+    RectangleType* rect
+    )
+{
+    WinHandle oldWin;
+
+    oldWin = WinSetDrawWindow( FrmGetWindowHandle( formPtr ) );
+
+    FrmGetObjectBounds( formPtr, objectIndex, rect );
+
+    if ( NULL != oldWin )
+        WinSetDrawWindow( oldWin );
+}
+
+
+
+RESIZE_SECTION static void SafeFrmSetObjectBounds
+    (
+    FormType* formPtr,
+    UInt16 objectIndex,
+    RectangleType* rect
+    )
+{
+    WinHandle oldWin;
+
+    oldWin = WinSetDrawWindow( FrmGetWindowHandle( formPtr ) );
+
+    FrmSetObjectBounds( formPtr, objectIndex, rect );
+
+    if ( NULL != oldWin )
+        WinSetDrawWindow( oldWin );
+}
+
+
+
+RESIZE_SECTION static void AddForm( UInt16 indexInList, MemHandle handle, UInt16 formID )
+{
+    UInt16         numObjects;
+    DIAConfigType* config;
+
+    formList[ indexInList ].configHandle = handle;
+    if ( handle == NULL ) {
+        return;
+    }
+
+    config          = ( DIAConfigType* )MemHandleLock( handle );
+    numObjects      = ( ( config->sizeInWords + 1 ) * sizeof( UInt16 ) -
+                        sizeof( DIAConfigType ) ) /
+                          sizeof( DIAConfigEntryType );
+
+    formList[ indexInList ].formID         = formID;
+    formList[ indexInList ].config         = config;
+    formList[ indexInList ].numObjects     = numObjects;
+    formList[ indexInList ].open           = false;
+    formList[ indexInList ].callback       = NULL;
+
+    if ( config->flags & DIA_FORM_USE_BIN &&
+         numBins < 1 + config->bin )
+        numBins = 1 + config->bin;
+}
+
+
+
+/* This sets up the original bounds array as needed */
+RESIZE_SECTION static void InitialSetupForm( UInt16 indexInList ) 
+{
+    RectangleType* originalBounds;
+    FormType*      formPtr;
+    UInt16         numObjects;
+    UInt16         i;
+
+    numObjects = formList[ indexInList ].numObjects;
+    if ( numObjects == 0 )
+        return;
+    if ( formList[ indexInList ].originalBounds != NULL )
+        return;
+    formPtr = FrmGetFormPtr( formList[ indexInList ].formID );
+    if ( formPtr == NULL )
+        return;
+
+    originalBounds = ( RectangleType* )SafeMemPtrNew( numObjects * 
+                                           sizeof( RectangleType ) );
+    formList[ indexInList ].originalBounds = originalBounds;
+
+    /* First object is the form itself */
+    WinGlueGetBounds( FrmGetWindowHandle( formPtr ), &( originalBounds[ 0 ] ) );
+
+    /* Now on to the other objects */
+    for ( i = 1 ; i < numObjects ; i++ ) {
+         UInt16 objectIndex;
+         objectIndex = MyFrmGetObjectIndex( formPtr,
+                     formList[ indexInList ].config->objectList[ i ].objectID );
+         SafeFrmGetObjectBounds( formPtr, objectIndex, &( originalBounds[ i ] ) );
+    }
+}
+
+
+
+/* Adjust one coordinate */
+RESIZE_SECTION static Coord Adjust
+    (
+    Coord value,            /* old value to adjust */
+    Coord oldObjectExtent,  /* old extent if relevant */
+    Coord newObjectExtent,  /* already adjusted extent if relevant */
+    Coord oldExtent,        /* old form/screen extent */
+    Coord newExtent,        /* new form/screen extent */
+    UInt16 shiftedFlag      /* adjustment flag, shifted down as needed */
+    )
+{
+    Coord delta;
+    
+    delta = newExtent - oldExtent;
+
+    switch ( shiftedFlag ) {
+        case DIA_X_FIX >> DIA_SHIFT_X:
+            return value;
+        case DIA_X_RATIO >> DIA_SHIFT_X:
+            return value * ( Int32 )newExtent / oldExtent;
+        case DIA_X_RIGHT >> DIA_SHIFT_X:
+            return newExtent - ( oldExtent - value - oldObjectExtent ) - newObjectExtent;
+        case DIA_X_PLUS_DW >> DIA_SHIFT_X:
+            return value + delta;
+        case DIA_X_PLUS_1_2_DW >> DIA_SHIFT_X:
+            return value + delta / 2;
+        case DIA_X_PLUS_1_3_DW >> DIA_SHIFT_X:
+            return value + delta / 3;
+        case DIA_X_PLUS_2_3_DW >> DIA_SHIFT_X:
+            return value + 2 * delta / 3;
+        case DIA_X_PLUS_1_4_DW >> DIA_SHIFT_X:
+            return value + delta / 4;
+        case DIA_X_PLUS_3_4_DW >> DIA_SHIFT_X:
+            return value + 3 * delta / 4;
+        default: /* should not happen */
+            return value;
+    }
+}
+
+
+
+/* Get new bounds for an object, adjusted for DIA */
+RESIZE_SECTION static void GetNewBounds( UInt16 displayExtentX, UInt16 displayExtentY,
+    UInt16 stdFormExtentX, UInt16 stdFormExtentY,
+    RectangleType* oldBounds, RectangleType* newBounds,
+    DIAConfigEntryType* configEntry )
+{
+    UInt16 flags;
+    flags = configEntry->flags;
+
+    if ( flags & DIA_MASK_W ) {
+        newBounds->extent.x  = Adjust( oldBounds->extent.x, 0, 0, 
+                                   stdFormExtentX,
+                                   displayExtentX,
+                                   ( flags & DIA_MASK_W ) >> DIA_SHIFT_W );
+    }
+    if ( flags & DIA_MASK_H ) {
+        newBounds->extent.y  = Adjust( oldBounds->extent.y, 0, 0,
+                                   stdFormExtentY,
+                                   displayExtentY,
+                                   ( flags & DIA_MASK_H ) >> DIA_SHIFT_H );
+    }
+    newBounds->topLeft.x = Adjust( oldBounds->topLeft.x, oldBounds->extent.x,
+                               newBounds->extent.x,
+                               stdFormExtentX, displayExtentX,
+                               ( flags & DIA_MASK_X ) >> DIA_SHIFT_X );
+    newBounds->topLeft.y = Adjust( oldBounds->topLeft.y, oldBounds->extent.y,
+                               newBounds->extent.y,
+                               stdFormExtentY, displayExtentY,
+                               ( flags & DIA_MASK_Y ) >> DIA_SHIFT_Y );
+}
+
+
+
+/* This compares two rectangles.  If sonyDoubleSecond is set and the first
+   bounds are exactly double the size of the first and DIA hardware is
+   DIA_HARDWARE_SONY1, then they also match. */
+RESIZE_SECTION static Boolean SameBounds( RectangleType* a, RectangleType* b,
+    Boolean sonyDoubleSecond )
+{
+    Boolean compare;
+    compare = ( a->extent.y == b->extent.y && a->extent.x == b->extent.x &&
+                a->topLeft.y == b->topLeft.y && a->topLeft.x == b->topLeft.x );
+#ifdef SUPPORT_DIA_SONY
+    if ( ! compare && GetDIAHardware() == DIA_HARDWARE_SONY1 ) {
+        return a->extent.y == 2 * b->extent.y &&
+               a->extent.x == 2 * b->extent.x &&
+               a->topLeft.y == 2 * b->topLeft.y &&
+               a->topLeft.x == 2 * b->topLeft.x;
+    }
+#endif
+    return compare;
+}
+
+
+
+/* Returns true if there is moving done */
+RESIZE_SECTION static Boolean MoveObjectsInForm( UInt16 indexInList ) 
+{
+    Coord     extentX;
+    Coord     extentY;
+    UInt16    i;
+    UInt16    focus;
+    FormType* formPtr;
+    DIAFormEntryType* entry;
+    Int16 dw, dh;
+
+    RectangleType  newBounds;
+    RectangleType  curBounds;
+    
+    entry = &( formList[ indexInList ] );
+
+    formPtr = FrmGetFormPtr( entry->formID );
+    if ( formPtr == NULL )
+        return false;
+    InitialSetupForm( indexInList );
+    WinGetDisplayExtent( &extentX, &extentY );
+
+    /* First object is the form itself */
+    WinGlueGetBounds( FrmGetWindowHandle( formPtr ), &curBounds );
+    newBounds = curBounds;
+    GetNewBounds( extentX, extentY, StandardExtent(), StandardExtent(),
+         &( formList[ indexInList ].originalBounds[ 0 ] ),
+         &newBounds, &( entry->config->objectList[ 0 ] ) );
+
+/* { Char ss[55]; StrPrintF(ss, " %d x %d ", extentX, extentY ); DebugInfo(ss); DebugInfo("abc"); } DebugInfo("def"); */
+
+    if ( ( SameBounds( &curBounds, &newBounds, true ) ||
+           ( formList[ indexInList ].open &&
+           SameBounds( &newBounds, &( formList[ indexInList ].lastBounds ), false ) ) ) &&
+           extentX == entry->lastExtentX && extentY == entry->lastExtentY ) {
+        DebugInfo( "skipping resize" );
+        return false;
+    }
+
+    dw = newBounds.extent.x - curBounds.extent.x;
+    dh = newBounds.extent.y - curBounds.extent.y;
+
+    if ( GetDIAHardware() == DIA_HARDWARE_SONY1 || 
+         GetDIAHardware() == DIA_HARDWARE_HANDERA ) {
+         /* Sony OS4 and Handera work differently from everybody else */
+        FrmEraseForm( formPtr );
+    }
+
+    entry->lastBounds  = newBounds;
+    entry->lastExtentX = extentX;
+    entry->lastExtentY = extentY;
+    WinSetBounds( FrmGetWindowHandle(formPtr), &newBounds );
+
+    /* The rest is resized relative to the form itself */
+    extentX = newBounds.extent.x;
+    extentY = newBounds.extent.y;
+    focus   = FrmGetFocus( formPtr );
+
+    for ( i = 1 ; i < entry->numObjects ; i++ ) {
+         UInt16  objectIndex;
+
+         objectIndex = MyFrmGetObjectIndex( formPtr,
+                     entry->config->objectList[ i ].objectID );
+         SafeFrmGetObjectBounds( formPtr, objectIndex, &curBounds );
+         newBounds = curBounds;
+         GetNewBounds( extentX, extentY,
+             entry->originalBounds[ 0 ].extent.x,
+             entry->originalBounds[ 0 ].extent.y,
+             &( entry->originalBounds[ i ] ),
+             &newBounds, &( entry->config->objectList[ i ] ) );
+
+         if ( ! SameBounds( &curBounds, &newBounds, false ) ) {
+             SafeFrmSetObjectBounds( formPtr, objectIndex, &newBounds );
+             
+             switch ( FrmGetObjectType( formPtr, objectIndex ) ) {
+                 case frmFieldObj:
+    /*             case frmScrollBarObj: */
+                 {
+                     FieldType* field;
+                     UInt16     insPt;
+
+                     field   = ( FieldType* ) FrmGetObjectPtr( formPtr, objectIndex );
+
+                     if ( entry->config->objectList[ i ].flags & DIA_H_GRANULAR ) {
+                         FontID oldFont;
+                         Coord  newHeight;
+
+                         oldFont   = FntSetFont( FldGetFont( field ) );
+
+                         newHeight = newBounds.extent.y / FntLineHeight() *
+                                         FntLineHeight();
+                                         
+                         FntSetFont( oldFont );
+
+                         if ( 0 < newHeight ) {
+                             newBounds.extent.y = newHeight;
+                             SafeFrmSetObjectBounds( formPtr, objectIndex, &newBounds );
+                         }
+                     }
+                     insPt   = FldGetInsPtPosition( field );
+                     FldRecalculateField( field, true );
+                     FldSetInsPtPosition( field, insPt );
+                     FldSendChangeNotification( field );
+                     break;
+                 }
+                 case frmListObj:
+                     if ( entry->config->objectList[ i ].flags & DIA_H_GRANULAR ) {
+                         ListType* list;
+                         FontID oldFont;
+                         Coord  newHeight;
+
+                         list   = ( ListType* ) FrmGetObjectPtr( formPtr, objectIndex );
+
+                         oldFont   = FntSetFont( LstGlueGetFont( list ) );
+
+                         newHeight = newBounds.extent.y / FntLineHeight() *
+                                         FntLineHeight();
+
+                         FntSetFont( oldFont );
+
+                         if ( 0 < newHeight ) {
+                             newBounds.extent.y = newHeight;
+                             SafeFrmSetObjectBounds( formPtr, objectIndex, &newBounds );
+                         }
+                     }
+                     break;
+
+                 default:
+                     break;
+             }
+         }
+    }
+
+    if ( formList[ indexInList ].callback ) {
+        (*formList[ indexInList ].callback)(formPtr, dw, dh);
+    }
+
+    if ( FrmGetFocus( formPtr ) != focus )
+        FrmSetFocus( formPtr, focus );
+
+    return true;
+}
+
+
+
+void InitializeResizeSupport( UInt16 formMapId )
+{
+    MemHandle     indexHandle;
+    DIAIndexType* index;
+    UInt16        i;
+
+    if ( formList != NULL ) {
+        return;
+    }
+    indexHandle = DmGetResource( WORD_LIST_TYPE, formMapId );
+    if ( indexHandle == NULL ) {
+        return;
+    }
+
+    if ( DIA_HARDWARE_NONE == InitializeDIA() ) {
+        return;
+    }
+
+    index     = ( DIAIndexType* )MemHandleLock( indexHandle );
+    numBins   = 0;
+    formCount = index->count * sizeof( UInt16 ) /
+                    sizeof( DIAIndexEntryType );
+
+    if ( formCount == 0 ) {
+        numBins = 0;
+        return;
+    }
+
+    formList  = ( DIAFormEntryType* ) SafeMemPtrNew( formCount * 
+                                          sizeof( DIAFormEntryType ) );
+    MemSet( formList, formCount * sizeof( DIAFormEntryType ), 0 );
+
+    for ( i = 0 ; i < formCount ; i++ ) {
+         AddForm( i, DmGetResource( WORD_LIST_TYPE, index->mapList[ i ].to ),
+             index->mapList[ i ].from );
+    }
+
+    MemHandleUnlock( indexHandle );
+    DmReleaseResource( indexHandle );
+
+    if ( 0 < numBins ) {
+        bins = ( DIAStateType* ) SafeMemPtrNew( numBins * 
+                                     sizeof( DIAStateType ) );
+        for ( i = 0 ; i < numBins ; i++ )
+             bins[ i ] = DIA_STATE_UNDEFINED;
+    }
+}
+
+
+
+
+void TerminateResizeSupport( void )
+{
+     UInt16  i;
+
+     if ( formList == NULL )
+         return;
+     TerminateDIA();
+     for ( i = 0 ; i < formCount ; i++ ) {
+          if ( NULL != formList[ i ].configHandle ) {
+              MemHandleUnlock( formList[ i ].configHandle );
+              DmReleaseResource( formList[ i ].configHandle );
+              if ( formList[ i ].originalBounds != NULL )
+                  SafeMemPtrFree( formList[ i ].originalBounds );
+          }
+     }
+     SafeMemPtrFree( formList );
+     formCount = 0;
+     if ( 0 < numBins ) {
+         SafeMemPtrFree( bins );
+     }
+}
+
+
+
+
+void LoadResizePrefs( UInt32 appID, UInt16 prefID )
+{
+    UInt16 size;
+
+    size = 0;
+
+    if ( formList == NULL || numBins == 0 ||
+         noPreferenceFound ==
+             PrefGetAppPreferences( appID, prefID, NULL, &size, true ) ) {
+        return;
+    }
+
+    if ( numBins * sizeof( DIAStateType ) < size ) {
+        size = numBins * sizeof( DIAStateType );
+    }
+
+    PrefGetAppPreferences( appID, prefID, bins, &size, true );
+}
+
+
+
+void SaveResizePrefs( UInt32 appID, UInt16 prefID, Int16 version )
+{
+    if ( formList == NULL || numBins == 0 )
+        return;
+
+    PrefSetAppPreferences( appID, prefID, version, bins,
+        numBins * sizeof( DIAStateType ), true );
+}
+
+
+
+RESIZE_SECTION static UInt16 GetFormIndex( UInt16 formID ) 
+{
+    UInt16 i;
+
+    if ( formList == NULL )
+        return 0;
+
+    for ( i = 0 ; i < formCount ; i++ )
+        if ( formList[ i ].formID == formID )
+            break;
+
+    return i;
+}
+
+
+
+void SetResizePolicy( UInt16 formID )
+{
+    if ( GetFormIndex( formID ) < formCount ) {
+        SetCustomDIAPolicy( formID );
+    }
+}
+
+
+void SetResizeCallback( UInt16 formID, DIAResizeCallback fn )
+{
+    UInt16 i;
+    i = GetFormIndex( formID );
+    if ( i < formCount ) {
+        formList[ i ].callback = fn;
+    }
+}
+
+
+
+RESIZE_SECTION static Boolean GetFormInfo( void ) 
+{
+    active.formID  = FrmGetActiveFormID();
+    active.formPtr = FrmGetActiveForm();
+    active.index   = GetFormIndex( active.formID );
+
+    if ( active.index < formCount ) {
+        active.entry = &( formList[ active.index ] );
+        active.flags = active.entry->config->flags;
+        return true;
+    }
+    else {
+        return false;
+    }
+}
+
+
+
+
+
+RESIZE_SECTION static Boolean PrepareForm( void ) 
+{
+    if ( active.index == formCount ) {
+        SetDIAState( DIA_STATE_MAX );
+        SetDIAAllowResize( false );
+        return false;
+    }
+
+    return MoveObjectsInForm( active.index );
+}
+
+
+
+RESIZE_SECTION static void SaveDIAState( void ) 
+{
+    if ( active.index == formCount )
+        return;
+
+    if ( active.entry->config->flags & DIA_FORM_USE_BIN ) {
+        bins[ active.entry->config->bin ] = GetDIAState();
+    }
+}
+
+
+
+
+RESIZE_SECTION static Boolean FormStartup( void )
+{
+    DIAStateType newState;
+    Boolean   big;
+    Boolean   allowBig;
+    Boolean   changed;
+    Boolean   allowResize;
+
+    if ( active.index == formCount ) {
+        SetDIAState( DIA_STATE_MAX );
+        SetDIAAllowResize( false );
+        SetDIAConstraints( FrmGetWindowHandle( active.formPtr ), false, false );
+        return false;
+    }
+
+    newState = GetDIAState();
+
+    if ( ( active.flags & DIA_FORM_USE_BIN ) &&
+         ( bins[ active.entry->config->bin ] != DIA_STATE_UNDEFINED ) ) {
+        newState = bins[ active.entry->config->bin ];
+/*        if ( newState == DIA_STATE_MIN ) DebugInfo("bin = min");
+        if ( newState == DIA_STATE_MAX ) DebugInfo("bin = max"); */
+    }
+    else if ( ! ( active.flags & DIA_FORM_KEEP_LAST ) ) {
+        newState = active.entry->config->preferredState;
+    }
+
+    if ( active.flags & DIA_FORM_NO_RESIZE ) {
+        allowResize = false;
+        allowBig = false;
+    }
+    else {
+        allowResize = true;
+        allowBig = true;
+    }
+
+    big      = ( newState == DIA_STATE_MIN || newState == DIA_STATE_NO_STATUS_BAR );
+    allowBig = allowBig || big;
+
+    SetDIAConstraints( FrmGetWindowHandle( active.formPtr ), allowBig, allowBig );
+
+    SetDIAState( newState );
+
+    SetDIAAllowResize( allowResize );
+
+    changed = PrepareForm();
+
+/*    if ( changed ) DebugInfo("Changed in FormStartup"); */
+
+    SaveDIAState();
+
+    return changed;
+}
+
+
+RESIZE_SECTION static void ForceRedrawAll( void )
+{
+    UInt16 i;
+    for ( i = 0 ; i < formCount ; i++ ) {
+        if ( formList[ i ].open )
+            formList[ i ].forceRedraw = true;
+    }
+}
+
+
+
+Boolean ResizeHandleFrmOpenEvent( void )
+{
+    GetFormInfo();
+#ifdef SUPPORT_DIA_HANDERA
+    if ( GetDIAHardware() == DIA_HARDWARE_HANDERA &&
+         ( active.index == formCount || ! ( active.flags & DIA_FORM_HANDERA ) )
+       ) {
+        VgaFormModify( active.formPtr, vgaFormModify160To240 );
+    }
+#endif
+    if ( active.index < formCount ) {
+        MemSet( &( active.entry->lastBounds ), sizeof( RectangleType ), 0 );
+        active.entry->lastExtentX = -1;
+        active.entry->lastExtentY = -1;
+        active.entry->forceRedraw = false;
+    }
+    DebugInfo("FrmOpen");
+    PushCoordinateSystemToStandard();
+    FormStartup();
+    if ( active.index < formCount ) {
+        active.entry->open = true;
+    }
+    PopCoordinateSystem();
+    haveWinDisplayChangedEvent = false;
+    return true;
+}
+
+
+
+Boolean ResizeHandleFrmCloseEvent( void )
+{
+    if ( GetFormInfo() ) {
+        DebugInfo("FrmClose");
+        active.entry->open        = false;
+        active.entry->forceRedraw = false;
+        SaveDIAState();
+    }
+    return true;
+}
+
+
+
+Boolean ResizeHandleWinDisplayChangedEvent( void )
+{
+    haveWinDisplayChangedEvent = false;
+    if ( ! GetFormInfo() )
+        return true;
+
+    PushCoordinateSystemToStandard();
+
+    DebugInfo("WinDisplayChanged");
+    if ( PrepareForm() || active.entry->forceRedraw ) {
+        UniqueUpdateForm( active.formID, frmRedrawUpdateCode );
+        active.entry->forceRedraw = false;
+    }
+    SaveDIAState();
+
+    PopCoordinateSystem();
+
+    return true;
+}
+
+
+
+Boolean ResizeHandleWinExitEvent( void )
+{
+    DebugInfo("WinExit");
+
+    return true;
+}
+
+
+
+Boolean ResizeHandleFrmRedrawUpdateCode( void )
+{
+    GetFormInfo();
+    DebugInfo("FrmUpdate");
+    if ( active.index < formCount )
+        active.entry->forceRedraw = false;
+    return true;
+}
+
+
+
+Boolean ResizeHandleWinEnterEvent( void )
+{
+    GetFormInfo();
+    DebugInfo("WinEnter");
+    if ( active.index == formCount ) {
+        return true;
+    }
+
+    PushCoordinateSystemToStandard();
+
+    /* If the last form we have record of being in is this one, then
+       we may have missed what happened on a form. */
+
+    if ( active.entry->open && ( FormStartup() ||
+         active.entry->forceRedraw ) )
+       {
+        EventType e;
+        DebugInfo("WinEnter: Possibly missed winDisplayChangedEvent");
+        MemSet( &e, sizeof( EventType ), 0 );
+        e.eType = winDisplayChangedEvent;
+        EvtAddUniqueEventToQueue( &e, 0, true );
+        DebugInfo("Queuing display change");
+        active.entry->forceRedraw = true;
+    }
+
+    PopCoordinateSystem();
+
+    return true;
+}
+
+
+
+
+void SetHaveWinDisplayChangedEvent( Boolean value )
+{
+    DebugInfo("SetHaveWinDisplayChangedEvent()");
+    haveWinDisplayChangedEvent = value;
+    ForceRedrawAll();
+}
+
+
+
+
+void ResizeRefreshCurrentForm( void )
+{
+    GetFormInfo();
+    if ( active.index == formCount )
+        return;
+
+    PushCoordinateSystemToStandard();
+
+    FormStartup();
+    SaveDIAState();
+    UniqueUpdateForm( active.formID, frmRedrawUpdateCode );
+
+    PopCoordinateSystem();
+}
+
+
+
+
+Boolean ResizeHandleEvent( EventType* event )
+{
+    Boolean handled = false;
+    ResizeTemporaryData old;
+
+    switch ( event->eType ) {
+        case nilEvent:
+            return false;
+        case frmOpenEvent: {
+            old = active;
+            ResizeHandleFrmOpenEvent();
+            active = old;
+            break;
+        }
+        case frmCloseEvent: {
+            old = active;
+            ResizeHandleFrmCloseEvent();
+            active = old;
+            break;
+        }
+        case winEnterEvent: {
+            old = active;
+            ResizeHandleWinEnterEvent();
+            active = old;
+            break;
+        }
+        case winExitEvent: {
+            old = active;
+            ResizeHandleWinExitEvent();
+            active = old;
+            break;
+        }
+        case winDisplayChangedEvent: {
+            old = active;
+            ResizeHandleWinDisplayChangedEvent();
+            active = old;
+            break;
+        }
+        case frmUpdateEvent:
+            if ( event->data.frmUpdate.updateCode == frmRedrawUpdateCode ) {
+                old = active;
+                ResizeHandleFrmRedrawUpdateCode();
+                active = old;
+            }
+            break;
+        default:
+            break;
+    }
+
+    return handled;
+}
+
diff --git a/forms/resize.h b/forms/resize.h
new file mode 100644 (file)
index 0000000..ac2e1ed
--- /dev/null
@@ -0,0 +1,147 @@
+/* $Id: resize.h,v 1.1 2005/05/15 09:06:04 admin Exp $ */
+/*******************************************************************************
+    Copyright (c) 2004, Alexander R. Pruss
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification,
+    are permitted provided that the following conditions are met:
+
+        Redistributions of source code must retain the above copyright notice, this
+        list of conditions and the following disclaimer.
+
+        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.
+
+        Neither the name of the PalmResize Project nor the names of its
+        contributors may be used to endorse or promote products derived from this
+        software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER 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.
+*******************************************************************************/
+
+#ifndef PLUCKER_RESIZE_H
+#define PLUCKER_RESIZE_H
+
+//#include "viewer.h"
+#include <PalmOS.h>
+
+// GrP
+#include "includes.h"
+#define SUPPORT_DIA
+#define SUPPORT_DIA_SONY
+#define SafeMemPtrNew(s) arena_malloc(s)
+#define SafeMemPtrFree(p) arena_free(p)
+
+#if ! defined( SUPPORT_DIA ) && defined( HAVE_SILKSCREEN )
+# define SUPPORT_DIA
+#endif
+
+#if ! defined( SUPPORT_DIA_SONY ) && defined( HAVE_SONY_SDK )
+# define SUPPORT_DIA_SONY
+#endif
+
+#if ! defined( SUPPORT_DIA_HANDERA ) && defined( HAVE_HANDERA_SDK )
+# define SUPPORT_DIA_HANDERA
+#endif
+
+#ifndef winDisplayChangedEvent
+# define winDisplayChangedEvent 0x4101
+#else
+# define HAVE_PALM_DIA_SDK
+#endif
+
+#include "resizeconsts.h"
+
+#define WORD_LIST_TYPE 'wrdl'
+
+typedef void (*DIAResizeCallback)(FormPtr frmP, Int16 dw, Int16 dh);
+
+typedef struct {
+    UInt16 objectID;
+    UInt16 flags;
+    UInt16 reserved;
+} DIAConfigEntryType;
+
+typedef UInt8 DIAStateType;
+
+typedef struct {
+    UInt16             sizeInWords;
+    UInt16             flags;
+    UInt16             bin;
+    UInt16             preferredState;
+    DIAConfigEntryType objectList[0];
+} DIAConfigType;
+
+typedef struct {
+    UInt16 from;
+    UInt16 to;
+} DIAIndexEntryType;
+
+typedef struct {
+    UInt16 count;
+    DIAIndexEntryType mapList[ 0 ];
+} DIAIndexType;
+
+typedef struct {
+    UInt16         formID;
+    UInt16         numObjects;
+    Boolean        open;
+    MemHandle      configHandle;
+    Coord          lastExtentX;
+    Coord          lastExtentY;
+    RectangleType  lastBounds;
+    Boolean        forceRedraw;
+    DIAConfigType* config;
+    RectangleType* originalBounds;
+    DIAResizeCallback callback;
+} DIAFormEntryType;
+
+#ifdef SUPPORT_DIA
+extern void InitializeResizeSupport( UInt16 formMapId ) RESIZE_SECTION;
+extern void TerminateResizeSupport( void ) RESIZE_SECTION;
+extern void SetResizePolicy( UInt16 formID ) RESIZE_SECTION;
+extern void SetResizeCallback( UInt16 formID, DIAResizeCallback fn ) RESIZE_SECTION;
+extern Boolean ResizeHandleFrmOpenEvent( void ) RESIZE_SECTION;
+extern Boolean ResizeHandleFrmCloseEvent( void ) RESIZE_SECTION;
+extern Boolean ResizeHandleWinDisplayChangedEvent( void ) RESIZE_SECTION;
+extern Boolean ResizeHandleWinExitEvent( void ) RESIZE_SECTION;
+extern Boolean ResizeHandleWinEnterEvent( void ) RESIZE_SECTION;
+extern Boolean ResizeHandleFrmRedrawUpdateCode( void ) RESIZE_SECTION;
+extern void LoadResizePrefs( UInt32 appID, UInt16 prefID ) RESIZE_SECTION;
+extern void SaveResizePrefs( UInt32 appID, UInt16 prefID, Int16 version )
+    RESIZE_SECTION;
+extern void ResizeRefreshCurrentForm( void ) RESIZE_SECTION;
+extern void SetHaveWinDisplayChangedEvent( Boolean value ) RESIZE_SECTION;
+extern Boolean ResizeHandleEvent( EventType* event ) RESIZE_SECTION;
+#else
+
+#define HandleResizeNotification( x )
+#define InitializeResizeSupport( x )
+#define TerminateResizeSupport()
+#define SetResizePolicy( x )
+#define SetResizeCallback( x )
+#define ResizeHandleFrmOpenEvent()  true
+#define ResizeHandleFrmCloseEvent() true
+#define ResizeHandleWinDisplayChangedEvent() true
+#define ResizeHandleWinExitEvent()  true
+#define ResizeHandleWinEnterEvent() true
+#define LoadResizePrefs( a, b )
+#define SaveResizePrefs( a, b, c )
+#define ResizeRefreshCurrentForm()
+#define SetHaveWinDisplayChangedEvent( x )
+#define ResizeHandleFrmRedrawUpdateCode() true
+#define ResizeHandleEvent( e ) false
+
+#endif
+
+#endif /* _ARP_RESIZE_H */
diff --git a/forms/resizeconsts.h b/forms/resizeconsts.h
new file mode 100644 (file)
index 0000000..079af84
--- /dev/null
@@ -0,0 +1,116 @@
+/* $Id: resizeconsts.h,v 1.1 2005/05/15 09:06:04 admin Exp $ */\r
+/*******************************************************************************\r
+    Copyright (c) 2004, Alexander R. Pruss\r
+    All rights reserved.\r
+\r
+    Redistribution and use in source and binary forms, with or without modification,\r
+    are permitted provided that the following conditions are met:\r
+\r
+        Redistributions of source code must retain the above copyright notice, this\r
+        list of conditions and the following disclaimer.\r
+\r
+        Redistributions in binary form must reproduce the above copyright notice, this\r
+        list of conditions and the following disclaimer in the documentation and/or\r
+        other materials provided with the distribution.\r
+\r
+        Neither the name of the PalmResize Project nor the names of its\r
+        contributors may be used to endorse or promote products derived from this\r
+        software without specific prior written permission.\r
+\r
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\r
+    ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\r
+    ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*******************************************************************************/\r
+\r
+/* Object attribute flags */\r
+\r
+#define DIA_MASK_X   15 /* 0x000F */\r
+#define DIA_MASK_Y   240 /* 0x00F0 */\r
+#define DIA_MASK_W   1792 /* 0x0700 */\r
+#define DIA_MASK_H   28672 /* 0x7000 */\r
+\r
+#define DIA_SHIFT_X   0\r
+#define DIA_SHIFT_Y   4\r
+#define DIA_SHIFT_W   8\r
+#define DIA_SHIFT_H  12\r
+\r
+#define DIA_X_FIX    0 /* 0x0000 */\r
+#define DIA_Y_FIX    0 /* 0x0000 */\r
+#define DIA_W_FIX    0 /* 0x0000 */\r
+#define DIA_H_FIX    0 /* 0x0000 */\r
+\r
+#define DIA_X_RATIO  7 /* 0x0007 */\r
+#define DIA_Y_RATIO  112 /* 0x0070 */\r
+#define DIA_W_RATIO  1792 /* 0x0700 */\r
+#define DIA_H_RATIO  28672 /* 0x7000 */\r
+\r
+#define DIA_X_RIGHT  8 /* 0x0008 */\r
+#define DIA_Y_BOTTOM 128 /* 0x0080 */\r
+\r
+#define DIA_X_PLUS_DW 1 /* 0x0001 */\r
+#define DIA_Y_PLUS_DH 16 /* 0x0010 */\r
+#define DIA_W_PLUS_DW 256 /* 0x0100 */\r
+#define DIA_H_PLUS_DH 4096 /* 0x1000 */\r
+\r
+#define DIA_X_PLUS_1_2_DW 2 /* 0x0002 */\r
+#define DIA_Y_PLUS_1_2_DH 32 /* 0x0020 */\r
+#define DIA_W_PLUS_1_2_DW 512 /* 0x0200 */\r
+#define DIA_H_PLUS_1_2_DH 8192 /* 0x2000 */\r
+\r
+#define DIA_X_PLUS_1_3_DW 3 /* 0x0003 */\r
+#define DIA_Y_PLUS_1_3_DH 48 /* 0x0030 */\r
+#define DIA_W_PLUS_1_3_DW 768 /* 0x0300 */\r
+#define DIA_H_PLUS_1_3_DH 12288 /* 0x3000 */\r
+\r
+#define DIA_X_PLUS_2_3_DW 4 /* 0x0004 */\r
+#define DIA_Y_PLUS_2_3_DH 64 /* 0x0040 */\r
+#define DIA_W_PLUS_2_3_DW 1024 /* 0x0400 */\r
+#define DIA_H_PLUS_2_3_DH 16384 /* 0x4000 */\r
+\r
+#define DIA_X_PLUS_1_4_DW 5 /* 0x0005 */\r
+#define DIA_Y_PLUS_1_4_DH 80 /* 0x0050 */\r
+#define DIA_W_PLUS_1_4_DW 1280 /* 0x0500 */\r
+#define DIA_H_PLUS_1_4_DH 20480 /* 0x5000 */\r
+\r
+#define DIA_X_PLUS_3_4_DW 6 /* 0x0006 */\r
+#define DIA_Y_PLUS_3_4_DH 96 /* 0x0060 */\r
+#define DIA_W_PLUS_3_4_DW 1536 /* 0x0600 */\r
+#define DIA_H_PLUS_3_4_DH 24576 /* 0x6000 */\r
+\r
+#define DIA_H_GRANULAR  32768 /* 0x8000 */\r
+\r
+/* Form attribute flags */\r
+\r
+/* Try to keep the same DIA state as in previous form */\r
+#define DIA_FORM_KEEP_LAST         1\r
+/* Keep the same DIA state as previous form using the same bin */\r
+/* If DIA_FORM_KEEP_LAST and DIA_FORM_USE_BIN are both set, then\r
+   we keep last DIA state to get the initial DIA state for the bin\r
+   the first time a form from that bin is used. */\r
+#define DIA_FORM_USE_BIN           2\r
+/* Disable DIA state change */\r
+#define DIA_FORM_NO_RESIZE         4\r
+/* Handera-specific form */\r
+#define DIA_FORM_HANDERA           8\r
+\r
+\r
+#define STD_EXTENT_X        160\r
+#define STD_EXTENT_Y        160\r
+\r
+#define MAX_EXTENT_X        4096\r
+#define MAX_EXTENT_Y        4096\r
+\r
+#define DIA_STATE_MAX        0\r
+#define DIA_STATE_MIN        1\r
+#define DIA_STATE_NO_STATUS_BAR  2\r
+#define DIA_STATE_UNDEFINED   255\r
+\r
+/* No actual objects are allowed to use these--they are used within resize config info */\r
+#define GSI_OBJECT_ID   65280 /* 0xFF00 */\r
diff --git a/forms/terminalform.c b/forms/terminalform.c
new file mode 100644 (file)
index 0000000..db0b281
--- /dev/null
@@ -0,0 +1,1908 @@
+/**********
+ * Copyright (c) 2003-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "about.h"
+#include "formutils.h"
+#include "data/connectionlist.h"
+#include "data/prefs.h"
+#include "rsrc/rsrc.h"
+#include "ssh/ssh.h"
+#include "forms/resize.h"
+#include "forms/DIA.h"
+#include <PalmChars.h>
+#include "SonyChars.h"
+
+#include "terminalform.h"
+
+
+// DO NOT renumber any of these! They are stored in preferences.
+typedef enum {
+    topAll = -1, // initial state - everything visible
+    topNone = 0,
+    topABC, 
+    top123, 
+    topIntl,
+    topEtc 
+} top_pane_t;
+
+// DO NOT renumber any of these! They are stored in preferences.
+typedef enum {
+    bottomAll = -1, // initial state - everything visible
+    bottomMini = 0,
+    bottomFull, 
+    bottomCust, 
+    bottomNone
+} bottom_pane_t;
+
+// DO NOT renumber any of these! They are stored in preferences.
+typedef enum {
+    rightNone = -1, // initial state - everything visible
+    rightScroll = 0,
+    rightArrows
+} right_pane_t;
+
+typedef enum {
+    caseUpper,
+    caseLower, 
+    caseCaps
+} case_t;
+
+typedef enum {
+    keyboardNone = 0, 
+    keyboardMini, 
+    keyboardFullNone, 
+    keyboardFullABC, 
+    keyboardFull123, 
+    keyboardFullIntl, 
+    keyboardFullEtc
+} keyboard_t;
+
+static keyboard_t Keyboard;
+
+static int TerminalWindowActive = 0;
+
+static int deviceTreo6x0 = 0;
+
+extern struct ssh_session_t *ss;
+extern UInt16 NetLibCount;
+
+
+static Boolean OpenNetLib(void) FORMS_SEGMENT;
+static Boolean StartConnection(void) FORMS_SEGMENT;
+
+static void GetVT100Bounds(RectangleType *bounds) FORMS_SEGMENT;
+static void SetVT100Bounds(RectangleType bounds) FORMS_SEGMENT;
+static void ShowTitleBar(void) FORMS_SEGMENT;
+static void HideTitleBar(void) FORMS_SEGMENT;
+static void SetTitleBar(int show) FORMS_SEGMENT;
+static Boolean StatusBarShown(void) FORMS_SEGMENT;
+static void SetStatusBar(Boolean show) FORMS_SEGMENT;
+static void SetKeyboardHeight(Coord newHeight) FORMS_SEGMENT;
+
+static void SetBigShiftKey(void) FORMS_SEGMENT;
+static void SetSmallShiftKey(void) FORMS_SEGMENT;
+static void SetABCCase(case_t newcase) FORMS_SEGMENT;
+
+static void ShowBottomModifierKeys(Boolean show) FORMS_SEGMENT;
+static void ShowBottomABCKeys(Boolean show) FORMS_SEGMENT;
+static void ShowBottomArrowKeys(Boolean show) FORMS_SEGMENT;
+static void ShowBottomScrollKeys(Boolean show) FORMS_SEGMENT;
+static void ConstructNoneKeyboard(void) FORMS_SEGMENT;
+static void DestructNoneKeyboard(void) FORMS_SEGMENT;
+static void ConstructMiniKeyboard(void) FORMS_SEGMENT;
+static void DestructMiniKeyboard(void) FORMS_SEGMENT;
+static void ConstructFullNoneKeyboard(void) FORMS_SEGMENT;
+static void DestructFullNoneKeyboard(void) FORMS_SEGMENT;
+static void ConstructFullABCKeyboard(void) FORMS_SEGMENT;
+static void DestructFullABCKeyboard(void) FORMS_SEGMENT;
+static void ConstructFull123Keyboard(void) FORMS_SEGMENT;
+static void DestructFull123Keyboard(void) FORMS_SEGMENT;
+static void ConstructFullIntlKeyboard(void) FORMS_SEGMENT;
+static void DestructFullIntlKeyboard(void) FORMS_SEGMENT;
+static void ConstructFullEtcKeyboard(void) FORMS_SEGMENT;
+static void DestructFullEtcKeyboard(void) FORMS_SEGMENT;
+static void ConstructKeyboard(keyboard_t newKeyboard) FORMS_SEGMENT;
+static void DestructKeyboard(keyboard_t oldKeyboard) FORMS_SEGMENT;
+static void SetKeyboard(keyboard_t newKeyboard) FORMS_SEGMENT;
+
+static unsigned char control_character(unsigned char c) FORMS_SEGMENT;
+static Boolean CtrlPressed(void) FORMS_SEGMENT;
+static Boolean MetaPressed(void) FORMS_SEGMENT;
+static void CtrlPress(Boolean down, Boolean lockDown) FORMS_SEGMENT;
+static void MetaPress(Boolean down, Boolean lockDown) FORMS_SEGMENT;
+static void ShiftPress(Boolean down, Boolean lockDown) FORMS_SEGMENT;
+static void SendModifiedKey(unsigned char c) FORMS_SEGMENT;
+static void ClearModifiers(void) FORMS_SEGMENT;
+static void SendUpArrowKey(void) FORMS_SEGMENT;
+static void SendDownArrowKey(void) FORMS_SEGMENT;
+static void SendRightArrowKey(void) FORMS_SEGMENT;
+static void SendLeftArrowKey(void) FORMS_SEGMENT;
+static void SendFKey(UInt16 id) FORMS_SEGMENT;
+static void SendScrollpadKey(UInt16 id) FORMS_SEGMENT;
+static void SendEscapeKey(void) FORMS_SEGMENT;
+static char Backspace(void) FORMS_SEGMENT;
+static char Backquote(void) FORMS_SEGMENT;
+static Boolean HandleCtlSelectEvent(EventPtr e) FORMS_SEGMENT;
+static void TrackDrag(EventPtr e) FORMS_SEGMENT;
+static void SetScrollBar(FormPtr frmP, SetScrollBarEventType *se) FORMS_SEGMENT;
+static void CheckDevice(void) FORMS_SEGMENT;
+static Boolean VT100EventHandler(struct FormGadgetTypeInCallback *gadget, UInt16 cmd, void *paramP) FORMS_SEGMENT;
+static Boolean HandleCtlRepeatEvent(EventPtr e) FORMS_SEGMENT;
+Boolean RefreshNetLib(void); // fixme NOT forms segment (used elsewhere w/o prototype)
+
+static Boolean OpenNetLib(void)
+{
+    Err err;
+    UInt16 badIF = 0;
+
+    if (NetLibCount == 0) {
+        err = NetLibOpen(AppNetRefnum, &badIF);
+        if (err  &&  err != netErrAlreadyOpen) {
+            NetworkError("Could not open network library.", err);
+            return false;
+        } else if (badIF) {
+            NetworkError("Could not open network interface.", badIF);
+            return false;
+        } else {
+            NetLibCount++;
+        }
+    }
+
+    return RefreshNetLib();
+}
+
+
+Boolean RefreshNetLib(void)
+{
+    Err err;
+    Boolean allUp;
+    UInt16 badIF = 0;
+
+    // reconnect if necessary
+    err = NetLibConnectionRefresh(AppNetRefnum, true, &allUp, &badIF);
+    if (err) {
+        NetworkError("Could not open network interface.", err);
+        return false;
+    } else if (!allUp) {
+        NetworkError("Could not open network interface.", badIF);
+        return false;
+    } else {
+        return true;
+    }
+}
+
+
+static Boolean StartConnection(void)
+{
+    MemHandle recordH;
+    char *hostname;
+    char *portname;
+    char *username;
+    char *displayname;
+    FieldPtr displayField;
+    int port;
+    int result;
+    RectangleType bounds;
+
+    ss = NULL;
+
+    recordH=ConnectionListReadSelectedRecord(&hostname, &portname, &username);
+    if (!recordH) return false;
+
+    port = StrAToI(portname);
+    if (port == 0) port = 22;
+
+    displayField = PrvGetObjectByID(TerminalHostFieldID);
+    displayname = MemPtrNew(1+StrLen(username)+StrLen("@")+StrLen(hostname));
+    if (!displayname) {
+        PrvSetFieldToValue(displayField, hostname);
+    } else {
+        StrCopy(displayname, username);
+        StrCat(displayname, "@");
+        StrCat(displayname, hostname);
+        PrvSetFieldToValue(displayField, displayname);
+        MemPtrFree(displayname);
+    }
+
+    // draw now in case of error during connection
+    FrmDrawForm(FrmGetActiveForm());
+
+    if (!OpenNetLib()) goto done;
+
+    PrvGetObjectBoundsByID(TerminalTextGadgetID, &bounds);
+    ss = ssh_create(username, bounds);
+    result = ssh_open(ss, hostname, port);
+    if (result < 0) {
+        ssh_free(ss);
+        ss = NULL;
+    }
+
+ done:
+    MemHandleUnlock(recordH);
+        
+    return (ss != NULL);
+}
+
+static void GetVT100Bounds(RectangleType *bounds)
+{
+    PrvGetObjectBoundsByID(TerminalTextGadgetID, bounds);
+}
+
+static void SetVT100Bounds(RectangleType bounds)
+{
+    PrvSetObjectBoundsByID(TerminalTextGadgetID, &bounds);
+    WinEraseRectangle(&bounds, 0);
+    if (ss) ssh_set_bounds(ss, bounds);
+}
+
+static Coord KeyboardHeight = 0;
+
+static Boolean inputShown = true;
+static Boolean titleShown = true;
+static int titleShift = 0; // distance vt100 moved when title bar was hidden
+
+static void ShowTitleBar(void)
+{
+    RectangleType bounds;
+    if (titleShown) return;
+
+    // grow vt100 to top of screen
+    GetVT100Bounds(&bounds);
+    bounds.extent.y -= titleShift;
+    bounds.topLeft.y = titleShift;
+    SetVT100Bounds(bounds);
+
+    // show hostname field
+    PrvShowObjectByID(TerminalHostFieldID);
+
+    // hide close box
+    PrvHideObjectByID(TerminalCloseBoxButtonID);
+
+    // set pref
+    titleShown = 1;
+    PrefsPutInt(prefHideTitleBar, 0);
+}
+
+
+static void HideTitleBar(void)
+{
+    RectangleType bounds;
+    if (!titleShown) return;
+
+    // hide hostname field
+    PrvHideObjectByID(TerminalHostFieldID);
+
+    // show close box
+    PrvShowObjectByID(TerminalCloseBoxButtonID);
+
+    // grow vt100 to top of screen
+    GetVT100Bounds(&bounds);
+    titleShift = bounds.topLeft.y;
+    bounds.extent.y += titleShift;
+    bounds.topLeft.y = 0;
+    SetVT100Bounds(bounds);
+
+    // set pref
+    titleShown = 0;
+    PrefsPutInt(prefHideTitleBar, 1);
+}
+
+
+static void SetTitleBar(int show)
+{
+    if (show) ShowTitleBar();
+    else HideTitleBar();
+}
+
+
+static Boolean StatusBarShown(void)
+{
+    return GetDIAState() != DIA_STATE_NO_STATUS_BAR;
+}
+
+
+static void SetStatusBar(Boolean show)
+{
+    if (show  &&  GetDIAState() == DIA_STATE_NO_STATUS_BAR) {        
+        SetDIAState(DIA_STATE_MIN);
+    } else if (!show) {
+        SetDIAState(DIA_STATE_NO_STATUS_BAR);
+    }
+}
+
+
+#define NoKeyboardHeight 0
+#define MiniKeyboardHeight 25 
+#define FullKeyboardHeight (25+48)
+
+static void SetKeyboardHeight(Coord newHeight)
+{
+    RectangleType bounds;
+
+    if (KeyboardHeight != newHeight) {
+        // Adjust VT100 gadget for new height
+        GetVT100Bounds(&bounds);
+        bounds.extent.y += KeyboardHeight;
+        KeyboardHeight = newHeight;
+        bounds.extent.y -= KeyboardHeight;
+        SetVT100Bounds(bounds);
+    }
+}
+
+
+// intl and ABC use a wider shift key than etc.
+static void SetBigShiftKey(void)
+{
+    RectangleType bounds;
+    PrvGetObjectBoundsByID(TerminalTABCShiftButtonID, &bounds);
+    bounds.extent.x = 29;
+    PrvSetObjectBoundsByID(TerminalTABCShiftButtonID, &bounds);
+}
+
+
+static void SetSmallShiftKey(void)
+{
+    RectangleType bounds;
+    PrvGetObjectBoundsByID(TerminalTABCShiftButtonID, &bounds);
+    bounds.extent.x = 21;
+    PrvSetObjectBoundsByID(TerminalTABCShiftButtonID, &bounds);
+}
+
+
+static void SetABCCase(case_t newcase)
+{
+    static case_t oldcase = -1;
+    Boolean caps = 0, shift = 0;
+
+    if (newcase == oldcase) return;
+    oldcase = newcase;
+
+    if (newcase == caseUpper) shift = 1;
+    else if (newcase == caseCaps) caps = 1;
+
+    GrfSetState(caps, 0, shift);
+    GsiSetShiftState(caps ? glfCapsLock : 0, shift ? 4 : 0);
+    // value 4 should be gsiShiftUpper but isn't, or something
+
+    DestructKeyboard(Keyboard);
+    ConstructKeyboard(Keyboard);
+}
+
+
+static void ShowBottomModifierKeys(Boolean show)
+{
+    PrvSetObjectVisibilityByID(TerminalCtrlButtonID, show);
+    PrvSetObjectVisibilityByID(TerminalMetaButtonID, show);
+}
+
+
+static void ShowBottomABCKeys(Boolean show)
+{
+    PrvSetObjectVisibilityByID(TerminalBFullABCButtonID, show);
+    PrvSetObjectVisibilityByID(TerminalBFull123ButtonID, show);
+    PrvSetObjectVisibilityByID(TerminalBFullIntlButtonID, show);
+    PrvSetObjectVisibilityByID(TerminalBFullEtcButtonID, show);
+}
+
+
+static void ShowBottomArrowKeys(Boolean show)
+{
+    PrvSetObjectVisibilityByID(TerminalBFullUpButtonID, show);
+    PrvSetObjectVisibilityByID(TerminalBFullDownButtonID, show);
+    PrvSetObjectVisibilityByID(TerminalBFullLeftButtonID, show);
+    PrvSetObjectVisibilityByID(TerminalBFullRightButtonID, show);
+}
+
+
+static void ShowBottomScrollKeys(Boolean show)
+{
+    PrvSetObjectVisibilityByID(TerminalRScrollLineUpButtonID, show);
+    PrvSetObjectVisibilityByID(TerminalRScrollLineDownButtonID, show);
+    PrvSetObjectVisibilityByID(TerminalRScrollPageUpButtonID, show);
+    PrvSetObjectVisibilityByID(TerminalRScrollPageDownButtonID, show);
+}
+
+
+static void ShowGsi(Boolean show)
+{
+    UInt16 index;
+    FormPtr frmP;
+
+    GsiEnable(false);
+    frmP = FrmGetActiveForm();
+    for (index = 0; index < FrmGetNumberOfObjects(frmP); index++) {
+        FormObjectKind type = FrmGetObjectType(frmP, index);
+        if (type == frmGraffitiStateObj) {
+            Coord x, y;
+            FrmGetObjectPosition(frmP, index, &x, &y);
+            if (!show  &&  x < 10000) x += 10000;
+            else if (show  &&  x >= 10000) x -= 10000;
+            FrmSetObjectPosition(frmP, index, x, y);
+            GsiSetLocation(x, y);
+            if (show) FrmShowObject(frmP, index);
+            else FrmHideObject(frmP, index);
+        }
+    }
+    if (show) GsiEnable(true);
+}
+
+
+static void ConstructNoneKeyboard(void)
+{
+    PrefsPutInt(prefTopPane, topNone);
+    PrefsPutInt(prefBottomPane, bottomNone);
+
+    SetKeyboardHeight(NoKeyboardHeight);
+
+    // nothing to show
+
+    // hide Graffiti State Indicator
+    ShowGsi(false);
+}
+
+
+static void DestructNoneKeyboard(void)
+{
+    // nothing to hide
+
+    // show Graffiti State Indicator
+    ShowGsi(true);
+}
+
+
+static void ConstructMiniKeyboard(void)
+{
+    int i;
+    int count;
+
+    PrefsPutInt(prefTopPane, topNone);
+    PrefsPutInt(prefBottomPane, bottomMini);
+
+    SetKeyboardHeight(MiniKeyboardHeight);
+
+    // T|C:          hardware has no '&'
+    // Treo 600/650: hardware has no '_' but does have '&'
+    if (deviceTreo6x0) {
+        PrvSetControlLabel(TerminalBTCAmpersandButtonID, "_");
+    }
+
+    ShowBottomModifierKeys(true);
+    ShowBottomScrollKeys(true);
+
+    PrvShowObjectByID(TerminalBTCButtonsBitmapID);
+    count = TerminalBTCLastButtonID - TerminalBTCFirstButtonID + 1;
+    for (i = 0; i < count; i++) {
+        PrvShowObjectByID(TerminalBTCFirstButtonID + i);
+    }
+}
+
+
+static void DestructMiniKeyboard(void)
+{
+    int i;
+    int count;
+
+    ShowBottomModifierKeys(false);
+    ShowBottomScrollKeys(false);
+
+    PrvHideObjectByID(TerminalBTCButtonsBitmapID);
+    count = TerminalBTCLastButtonID - TerminalBTCFirstButtonID + 1;
+    for (i = 0; i < count; i++) {
+        PrvHideObjectByID(TerminalBTCFirstButtonID + i);
+    }
+}
+
+
+static void ConstructFullNoneKeyboard(void)
+{
+    PrefsPutInt(prefTopPane, topNone);
+    PrefsPutInt(prefBottomPane, bottomFull);
+
+    SetKeyboardHeight(MiniKeyboardHeight);
+
+    ShowBottomModifierKeys(true);
+    ShowBottomABCKeys(true);
+    ShowBottomArrowKeys(true);
+    ShowBottomScrollKeys(true);
+
+    PrvSetControlValue(TerminalBFullABCButtonID, 0);
+    PrvSetControlValue(TerminalBFull123ButtonID, 0);
+    PrvSetControlValue(TerminalBFullIntlButtonID, 0);
+    PrvSetControlValue(TerminalBFullEtcButtonID, 0);
+}
+
+
+static void DestructFullNoneKeyboard(void)
+{
+    ShowBottomModifierKeys(false);
+    ShowBottomABCKeys(false);
+    ShowBottomArrowKeys(false);
+    ShowBottomScrollKeys(false);    
+}
+
+
+static void ConstructFullABCKeyboard(void)
+{
+    int i;
+    int start, end;
+    Boolean caps, num, autoshift;
+    UInt16 shift;
+
+    PrefsPutInt(prefTopPane, topABC);
+    PrefsPutInt(prefBottomPane, bottomFull);
+
+    SetKeyboardHeight(FullKeyboardHeight);
+
+    ShowBottomModifierKeys(true);
+    ShowBottomABCKeys(true);
+    ShowBottomArrowKeys(true);
+    ShowBottomScrollKeys(true);
+
+    PrvSetControlValue(TerminalBFullABCButtonID, 1);
+    PrvSetControlValue(TerminalBFull123ButtonID, 0);
+    PrvSetControlValue(TerminalBFullIntlButtonID, 0);
+    PrvSetControlValue(TerminalBFullEtcButtonID, 0);
+
+    // show bitmap and buttons
+    PrvShowObjectByID(TerminalTABCButtonsBitmapID);
+    // choose caps based on Graffiti shift state
+    GrfGetState(&caps, &num, &shift, &autoshift);
+    if (caps) {
+        start = TerminalTABCFirstCapscaseButtonID;
+        end = TerminalTABCLastCapscaseButtonID;
+        PrvSetControlValue(TerminalTABCCapsButtonID, 1);
+        PrvSetControlValue(TerminalTABCShiftButtonID, 0);
+    } else if (shift) {
+        start = TerminalTABCFirstUppercaseButtonID;
+        end = TerminalTABCLastUppercaseButtonID;
+        PrvSetControlValue(TerminalTABCCapsButtonID, 0);
+        PrvSetControlValue(TerminalTABCShiftButtonID, 1);
+    } else {
+        start = TerminalTABCFirstLowercaseButtonID;
+        end = TerminalTABCLastLowercaseButtonID;
+        PrvSetControlValue(TerminalTABCCapsButtonID, 0);
+        PrvSetControlValue(TerminalTABCShiftButtonID, 0);
+    }
+    for (i = start; i <= end; i++) {
+        PrvShowObjectByID(i);
+    }
+    PrvShowObjectByID(TerminalTABCTabButtonID);
+    PrvShowObjectByID(TerminalTABCSpaceButtonID);
+    PrvShowObjectByID(TerminalTABCBackspaceButtonID);
+    PrvShowObjectByID(TerminalTABCReturnButtonID);
+    PrvShowObjectByID(TerminalTABCCapsButtonID);
+    PrvShowObjectByID(TerminalTABCShiftButtonID);
+    SetBigShiftKey();    
+}
+
+
+static void DestructFullABCKeyboard(void)
+{
+    int i;
+    int count;
+
+    ShowBottomModifierKeys(false);
+    ShowBottomABCKeys(false);
+    ShowBottomArrowKeys(false);
+    ShowBottomScrollKeys(false);    
+
+    // hide bitmap and buttons
+    count = TerminalTABCLastButtonID - TerminalTABCFirstButtonID + 1;
+    for (i = 0; i < count; i++) {
+        PrvHideObjectByID(TerminalTABCFirstButtonID + i);
+    }
+    PrvHideObjectByID(TerminalTABCTabButtonID);
+    PrvHideObjectByID(TerminalTABCSpaceButtonID);
+    PrvHideObjectByID(TerminalTABCBackspaceButtonID);
+    PrvHideObjectByID(TerminalTABCReturnButtonID);
+    PrvHideObjectByID(TerminalTABCCapsButtonID);
+    PrvHideObjectByID(TerminalTABCShiftButtonID);
+    PrvHideObjectByID(TerminalTABCButtonsBitmapID);
+}
+
+
+static void ConstructFull123Keyboard(void)
+{
+    int i;
+    int count;
+
+    PrefsPutInt(prefTopPane, top123);
+    PrefsPutInt(prefBottomPane, bottomFull);
+
+    SetKeyboardHeight(FullKeyboardHeight);
+
+    ShowBottomModifierKeys(true);
+    ShowBottomABCKeys(true);
+    ShowBottomArrowKeys(true);
+    ShowBottomScrollKeys(true);
+
+    PrvSetControlValue(TerminalBFullABCButtonID, 0);
+    PrvSetControlValue(TerminalBFull123ButtonID, 1);
+    PrvSetControlValue(TerminalBFullIntlButtonID, 0);
+    PrvSetControlValue(TerminalBFullEtcButtonID, 0);
+
+    // show bitmap and buttons
+    PrvShowObjectByID(TerminalT123ButtonsBitmapID);
+    count = TerminalT123LastButtonID - TerminalT123FirstButtonID + 1;
+    for (i = 0; i < count; i++) {
+        PrvShowObjectByID(TerminalT123FirstButtonID + i);
+    }
+    PrvShowObjectByID(TerminalT123TabButtonID);
+    PrvShowObjectByID(TerminalT123SpaceButtonID);
+    PrvShowObjectByID(TerminalT123BackspaceButtonID);
+    PrvShowObjectByID(TerminalT123ReturnButtonID);
+}
+
+
+static void DestructFull123Keyboard(void)
+{
+    int i;
+    int count;
+
+    ShowBottomModifierKeys(false);
+    ShowBottomABCKeys(false);
+    ShowBottomArrowKeys(false);
+    ShowBottomScrollKeys(false);    
+
+    // hide bitmap and buttons
+    count = TerminalT123LastButtonID - TerminalT123FirstButtonID + 1;
+    for (i = 0; i < count; i++) {
+        PrvHideObjectByID(TerminalT123FirstButtonID + i);
+    }
+    PrvHideObjectByID(TerminalT123TabButtonID);
+    PrvHideObjectByID(TerminalT123SpaceButtonID);
+    PrvHideObjectByID(TerminalT123BackspaceButtonID);
+    PrvHideObjectByID(TerminalT123ReturnButtonID);
+    PrvHideObjectByID(TerminalT123ButtonsBitmapID);
+}
+
+
+static void ConstructFullIntlKeyboard(void)
+{
+    int i;
+    int start, end;
+    Boolean caps, num, autoshift;
+    UInt16 shift;
+
+    PrefsPutInt(prefTopPane, topIntl);
+    PrefsPutInt(prefBottomPane, bottomFull);
+
+    SetKeyboardHeight(FullKeyboardHeight);
+
+    ShowBottomModifierKeys(true);
+    ShowBottomABCKeys(true);
+    ShowBottomArrowKeys(true);
+    ShowBottomScrollKeys(true);
+
+    PrvSetControlValue(TerminalBFullABCButtonID, 0);
+    PrvSetControlValue(TerminalBFull123ButtonID, 0);
+    PrvSetControlValue(TerminalBFullIntlButtonID, 1);
+    PrvSetControlValue(TerminalBFullEtcButtonID, 0);
+
+    // show bitmap and buttons
+    PrvShowObjectByID(TerminalTIntlButtonsBitmapID);
+    // choose caps based on Graffiti shift state
+    GrfGetState(&caps, &num, &shift, &autoshift);
+    if (caps) {
+        start = TerminalTIntlFirstUppercaseButtonID;
+        end = TerminalTIntlLastUppercaseButtonID;
+        PrvSetControlValue(TerminalTIntlCapsButtonID, 1);
+        PrvSetControlValue(TerminalTIntlShiftButtonID, 0);
+    } else if (shift) {
+        start = TerminalTIntlFirstUppercaseButtonID;
+        end = TerminalTIntlLastUppercaseButtonID;
+        PrvSetControlValue(TerminalTIntlCapsButtonID, 0);
+        PrvSetControlValue(TerminalTIntlShiftButtonID, 1);
+    } else {
+        start = TerminalTIntlFirstLowercaseButtonID;
+        end = TerminalTIntlLastLowercaseButtonID;
+        PrvSetControlValue(TerminalTIntlCapsButtonID, 0);
+        PrvSetControlValue(TerminalTIntlShiftButtonID, 0);
+    }
+    for (i = start; i <= end; i++) {
+        PrvShowObjectByID(i);
+    }
+    PrvShowObjectByID(TerminalTIntlTabButtonID);
+    PrvShowObjectByID(TerminalTIntlSpaceButtonID);
+    PrvShowObjectByID(TerminalTIntlBackspaceButtonID);
+    PrvShowObjectByID(TerminalTIntlReturnButtonID);
+    PrvShowObjectByID(TerminalTIntlCapsButtonID);
+    PrvShowObjectByID(TerminalTIntlShiftButtonID);
+    SetBigShiftKey();
+}
+
+
+static void DestructFullIntlKeyboard(void)
+{
+    int i;
+    int count;
+
+    ShowBottomModifierKeys(false);
+    ShowBottomABCKeys(false);
+    ShowBottomArrowKeys(false);
+    ShowBottomScrollKeys(false);    
+
+    // hide bitmap and buttons
+    count = TerminalTIntlLastButtonID - TerminalTIntlFirstButtonID + 1;
+    for (i = 0; i < count; i++) {
+        PrvHideObjectByID(TerminalTIntlFirstButtonID + i);
+    }
+    PrvHideObjectByID(TerminalTIntlTabButtonID);
+    PrvHideObjectByID(TerminalTIntlSpaceButtonID);
+    PrvHideObjectByID(TerminalTIntlBackspaceButtonID);
+    PrvHideObjectByID(TerminalTIntlReturnButtonID);
+    PrvHideObjectByID(TerminalTIntlCapsButtonID);
+    PrvHideObjectByID(TerminalTIntlShiftButtonID);
+    PrvHideObjectByID(TerminalTIntlButtonsBitmapID);
+}
+
+
+static void ConstructFullEtcKeyboard(void)
+{
+    int i;
+    int start, end;
+    int start2, end2;
+    Boolean caps, num, autoshift;
+    UInt16 shift;
+
+    PrefsPutInt(prefTopPane, topEtc);
+    PrefsPutInt(prefBottomPane, bottomFull);
+
+    SetKeyboardHeight(FullKeyboardHeight);
+
+    ShowBottomModifierKeys(true);
+    ShowBottomABCKeys(true);
+    ShowBottomArrowKeys(true);
+    ShowBottomScrollKeys(true);
+
+    PrvSetControlValue(TerminalBFullABCButtonID, 0);
+    PrvSetControlValue(TerminalBFull123ButtonID, 0);
+    PrvSetControlValue(TerminalBFullIntlButtonID, 0);
+    PrvSetControlValue(TerminalBFullEtcButtonID, 1);
+
+    // show bitmap and buttons
+    PrvShowObjectByID(TerminalTEtcButtonsBitmapID);
+    // choose caps based on Graffiti shift state
+    GrfGetState(&caps, &num, &shift, &autoshift);
+    if (caps) {
+        // no caps in etc, just shift
+        start = TerminalTEtcFirstUppercaseLatin1ButtonID;
+        end = TerminalTEtcLastUppercaseLatin1ButtonID;
+        start2 = TerminalTEtcFirstUppercaseFKeyButtonID;
+        end2 = TerminalTEtcLastUppercaseFKeyButtonID;
+        PrvSetControlValue(TerminalTABCCapsButtonID, 0);
+        PrvSetControlValue(TerminalTEtcShiftButtonID, 1);
+    } else if (shift) {
+        start = TerminalTEtcFirstUppercaseLatin1ButtonID;
+        end = TerminalTEtcLastUppercaseLatin1ButtonID;
+        start2 = TerminalTEtcFirstUppercaseFKeyButtonID;
+        end2 = TerminalTEtcLastUppercaseFKeyButtonID;
+        PrvSetControlValue(TerminalTABCCapsButtonID, 0);
+        PrvSetControlValue(TerminalTEtcShiftButtonID, 1);
+    } else {
+        start = TerminalTEtcFirstLowercaseLatin1ButtonID;
+        end = TerminalTEtcLastLowercaseLatin1ButtonID;
+        start2 = TerminalTEtcFirstLowercaseFKeyButtonID;
+        end2 = TerminalTEtcLastLowercaseFKeyButtonID;
+        PrvSetControlValue(TerminalTABCCapsButtonID, 0);
+        PrvSetControlValue(TerminalTEtcShiftButtonID, 0);
+    }
+    for (i = start; i <= end; i++) {
+        PrvShowObjectByID(i);
+    }
+    for (i = start2; i <= end2; i++) {
+        PrvShowObjectByID(i);
+    }
+    PrvShowObjectByID(TerminalTEtcInsButtonID);
+    PrvShowObjectByID(TerminalTEtcDelButtonID);
+    PrvShowObjectByID(TerminalTEtcHomeButtonID);
+    PrvShowObjectByID(TerminalTEtcEndButtonID);
+    PrvShowObjectByID(TerminalTEtcPgUpButtonID);
+    PrvShowObjectByID(TerminalTEtcPgDnButtonID);
+    PrvShowObjectByID(TerminalTEtcShiftButtonID);
+    SetSmallShiftKey();
+}
+
+
+static void DestructFullEtcKeyboard(void)
+{
+    int i;
+    int count;
+
+    ShowBottomModifierKeys(false);
+    ShowBottomABCKeys(false);
+    ShowBottomArrowKeys(false);
+    ShowBottomScrollKeys(false);    
+
+    // hide bitmap and buttons
+    count = TerminalTEtcLastButtonID - TerminalTEtcFirstButtonID + 1;
+    for (i = 0; i < count; i++) {
+        PrvHideObjectByID(TerminalTEtcFirstButtonID + i);
+    }
+    PrvHideObjectByID(TerminalTEtcInsButtonID);
+    PrvHideObjectByID(TerminalTEtcDelButtonID);
+    PrvHideObjectByID(TerminalTEtcHomeButtonID);
+    PrvHideObjectByID(TerminalTEtcEndButtonID);
+    PrvHideObjectByID(TerminalTEtcPgUpButtonID);
+    PrvHideObjectByID(TerminalTEtcPgDnButtonID);
+    PrvHideObjectByID(TerminalTEtcShiftButtonID);
+    PrvHideObjectByID(TerminalTEtcButtonsBitmapID);
+}
+
+
+static void ConstructKeyboard(keyboard_t newKeyboard)
+{
+    switch (newKeyboard) {
+    case keyboardNone:     ConstructNoneKeyboard();     break;
+    case keyboardMini:     ConstructMiniKeyboard();     break;
+    case keyboardFullNone: ConstructFullNoneKeyboard(); break;
+    case keyboardFullABC:  ConstructFullABCKeyboard();  break;
+    case keyboardFull123:  ConstructFull123Keyboard();  break;
+    case keyboardFullIntl: ConstructFullIntlKeyboard(); break;
+    case keyboardFullEtc:  ConstructFullEtcKeyboard();  break;
+    default:               ConstructFullNoneKeyboard(); break;
+    }
+}
+
+
+static void DestructKeyboard(keyboard_t oldKeyboard)
+{
+    switch (oldKeyboard) {
+    case keyboardNone:     DestructNoneKeyboard();     break;
+    case keyboardMini:     DestructMiniKeyboard();     break;
+    case keyboardFullNone: DestructFullNoneKeyboard(); break;
+    case keyboardFullABC:  DestructFullABCKeyboard();  break;
+    case keyboardFull123:  DestructFull123Keyboard();  break;
+    case keyboardFullIntl: DestructFullIntlKeyboard(); break;
+    case keyboardFullEtc:  DestructFullEtcKeyboard();  break;
+    default:               DestructFullNoneKeyboard(); break;
+    }
+}
+
+static void SetKeyboard(keyboard_t newKeyboard)
+{
+    if (Keyboard == newKeyboard) return;  // nothing to do
+
+    if (Keyboard != (keyboard_t)-1) DestructKeyboard(Keyboard);
+    Keyboard = newKeyboard;
+    ConstructKeyboard(Keyboard);
+    FrmDrawForm(FrmGetActiveForm());
+}
+
+
+
+static unsigned char control_character(unsigned char c)
+{
+    if (c == ' '  ||  c == '@') return '\0';        // C-space, C-@
+    if (c >= 'a'  &&  c <= 'z') return c - 'a' + 1; // C-a .. C-z
+    if (c >= 'A'  &&  c <= 'Z') return c - 'A' + 1; // C-A .. C-Z
+    if (c >= '['  &&  c <= '_') return c - 'A' + 1; // C-[ .. C-_
+    if (c >= '{'  &&  c <= '}') return c - 'a' + 1; // C-{ .. C-} (no C-~)
+    return c;
+}
+
+// ctrl or shift locked down (i.e. don't release after sending a key)
+static Boolean ctrlLocked = 0;
+static Boolean shiftLocked = 0;
+
+static Boolean jogPressed = 0;
+static Boolean jogPressedCtrl = 0;
+static Boolean jogPressedMeta = 0;
+static Boolean keyPressedDuringJogPress = 0;
+static Boolean jogMovedDuringJogPress = 0;
+
+
+static Boolean CtrlPressed(void)
+{
+    return PrvGetControlValue(TerminalCtrlButtonID);
+}
+
+static Boolean MetaPressed(void)
+{
+    // nothing here yet
+    return 0;
+}
+
+static void CtrlPress(Boolean down, Boolean lockDown)
+{
+    PrvSetControlValue(TerminalCtrlButtonID, down);
+    if (down) ctrlLocked = lockDown;
+    else ctrlLocked = 0;
+}
+
+static void ShiftPress(Boolean down, Boolean lockDown)
+{
+    if (PrvObjectVisibleByID(TerminalTABCShiftButtonID)) {
+        PrvSetControlValue(TerminalTABCShiftButtonID, down);
+        SetABCCase(down ? caseUpper : caseLower);
+    }
+    if (down) shiftLocked = lockDown;
+    else shiftLocked = 0;
+}
+
+static void MetaPress(Boolean down, Boolean lockDown)
+{
+    // nothing here yet
+}
+
+static void SendModifiedKey(unsigned char c)
+{
+    Boolean ctrlPressed = CtrlPressed();
+
+    if (ctrlPressed) {
+        c = control_character(c);
+    }
+
+    ClearModifiers();
+    if (jogPressed) keyPressedDuringJogPress = true;
+    ssh_key(ss, c);
+}
+
+
+static void ClearModifiers(void)
+{
+    if (!ctrlLocked) CtrlPress(0, 0);
+    if (!shiftLocked && !PrvGetControlValue(TerminalTABCCapsButtonID)) {
+        ShiftPress(0, 0);
+    }
+}
+
+
+static void SendUpArrowKey(void)
+{
+    ClearModifiers();
+    if (ssh_app_cursor_keys(ss)) 
+        ssh_keys(ss, "\eOA", 3);
+    else 
+        ssh_keys(ss, "\e[A", 3);
+}
+
+static void SendDownArrowKey(void)
+{
+    ClearModifiers();
+    if (ssh_app_cursor_keys(ss)) 
+        ssh_keys(ss, "\eOB", 3);
+    else 
+        ssh_keys(ss, "\e[B", 3);
+}
+
+static void SendRightArrowKey(void)
+{
+    ClearModifiers();
+    if (ssh_app_cursor_keys(ss)) 
+        ssh_keys(ss, "\eOC", 3);
+    else 
+        ssh_keys(ss, "\e[C", 3);
+}
+
+static void SendLeftArrowKey(void)
+{
+    ClearModifiers();
+    if (ssh_app_cursor_keys(ss)) 
+        ssh_keys(ss, "\eOD", 3);
+    else 
+        ssh_keys(ss, "\e[D", 3);
+}
+
+
+static void SendFKey(UInt16 id)
+{
+    char buf[6];
+    char i = (char)(id - TerminalTEtcFirstFKeyButtonID + 1);
+    // i is 1..20
+
+    // fixme other fkey modes would go here
+    // this implementation is PuTTY's "default" mode
+
+    // F5 => ESC [ 15 ~  ..  F20 => ESC [ 34 ~
+    // but there are gaps in the middle
+    switch (i) {
+    case 1:  i = 11; break;
+    case 2:  i = 12; break;
+    case 3:  i = 13; break;
+    case 4:  i = 14; break;
+    case 5:  i = 15; break;
+        
+    case 6:  i = 17; break;
+    case 7:  i = 18; break;
+    case 8:  i = 19; break;
+    case 9:  i = 20; break;
+    case 10: i = 21; break;
+        
+    case 11: i = 23; break;
+    case 12: i = 24; break;
+    case 13: i = 25; break;
+    case 14: i = 26; break;
+        
+    case 15: i = 28; break;
+    case 16: i = 29; break;
+        
+    case 17: i = 31; break;
+    case 18: i = 32; break;
+    case 19: i = 33; break;
+    case 20: i = 34; break;
+    }
+    snprintf(buf, sizeof(buf), "\e[%d~", i);
+
+    ClearModifiers();
+    ssh_keys(ss, buf, strlen(buf));
+}
+
+
+static void SendScrollpadKey(UInt16 id)
+{
+    char buf[5];
+    // unaffected by application mode
+    snprintf(buf, sizeof(buf), "\e[%d~", id - TerminalTEtcHomeButtonID + 1);
+    ClearModifiers();
+    ssh_keys(ss, buf, strlen(buf));
+}
+
+
+static void SendEscapeKey(void)
+{
+    ssh_key(ss, '\e');
+}
+
+
+static char Backspace(void)
+{
+    if (PrefsGetInt(prefBackspace, defaultBackspace) == backspaceBS) {
+        return 8;    // ascii BS
+    } else {
+        return 127;  // ascii DEL
+    }
+}
+
+
+static char Backquote(void)
+{
+    if (PrefsGetInt(prefBackquote, defaultBackquote) == backquoteESC) {
+        return '\e';    // ascii ESC
+    } else {
+        return '`';
+    }
+}
+
+
+static Boolean HandleCtlSelectEvent(EventPtr e)
+{
+    UInt16 id = e->data.ctlSelect.controlID;
+
+    // Check for self-labeled controls
+    if ((id >= TerminalBTCFirstButtonID  && id <= TerminalBTCLastButtonID)   ||
+        (id >= TerminalTABCFirstButtonID && id <= TerminalTABCLastButtonID)  ||
+        (id >= TerminalT123FirstButtonID && id <= TerminalT123LastButtonID)  ||
+        (id >= TerminalTIntlFirstButtonID && id <= TerminalTIntlLastButtonID)||
+        (id >= TerminalTEtcFirstLatin1ButtonID && 
+         id <= TerminalTEtcLastLatin1ButtonID))
+    {
+        const char *text = CtlGetLabel(e->data.ctlSelect.pControl);
+        if (text && text[0]) SendModifiedKey(text[0]);
+        return false;
+    }
+
+    // Check for FKeys
+    if ((id >= TerminalTEtcFirstFKeyButtonID && 
+         id <= TerminalTEtcLastFKeyButtonID))
+    {
+        SendFKey(id);
+        return false;
+    }
+
+    switch (id) {
+    case TerminalCtrlButtonID:
+        // nothing to do
+        return false;
+
+    case TerminalMetaButtonID:
+        // send esc immediately
+        ClearModifiers();
+        SendEscapeKey();
+        return false;
+
+    case TerminalTEtcInsButtonID:
+    case TerminalTEtcDelButtonID:
+    case TerminalTEtcHomeButtonID:
+    case TerminalTEtcEndButtonID:
+    case TerminalTEtcPgUpButtonID:
+    case TerminalTEtcPgDnButtonID:
+        SendScrollpadKey(id);
+        return false;
+
+    case TerminalTABCTabButtonID:
+    case TerminalT123TabButtonID:
+        SendModifiedKey('\t');
+        return false;
+
+    case TerminalTABCSpaceButtonID:
+    case TerminalT123SpaceButtonID:
+        SendModifiedKey(' ');
+        return false;
+
+    case TerminalTABCBackspaceButtonID:
+    case TerminalT123BackspaceButtonID:
+        SendModifiedKey(Backspace());
+        return false;
+
+    case TerminalTABCReturnButtonID:
+    case TerminalT123ReturnButtonID:
+        SendModifiedKey(13); // CR not LF
+        return false;
+
+    case TerminalTABCShiftButtonID:
+        if (PrvGetControlValue(TerminalTABCShiftButtonID)) {
+            SetABCCase(caseUpper);
+        } else {
+            SetABCCase(caseLower);
+        }
+        return false;
+
+    case TerminalTABCCapsButtonID:
+        if (PrvGetControlValue(TerminalTABCCapsButtonID)) {
+            SetABCCase(caseCaps);
+        } else {
+            SetABCCase(caseLower);
+        }
+        return false;
+
+    case TerminalBFullABCButtonID:
+        if (PrvGetControlValue(TerminalBFullABCButtonID)) {
+            SetKeyboard(keyboardFullABC);
+        } else {
+            SetKeyboard(keyboardFullNone);
+        }
+        return false;
+
+    case TerminalBFull123ButtonID:
+        if (PrvGetControlValue(TerminalBFull123ButtonID)) {
+            SetKeyboard(keyboardFull123);
+        } else {
+            SetKeyboard(keyboardFullNone);
+        }
+        return false;
+
+    case TerminalBFullIntlButtonID:
+        if (PrvGetControlValue(TerminalBFullIntlButtonID)) {
+            SetKeyboard(keyboardFullIntl);
+        } else {
+            SetKeyboard(keyboardFullNone);
+        }
+        return false;
+
+    case TerminalBFullEtcButtonID:
+        if (PrvGetControlValue(TerminalBFullEtcButtonID)) {
+            SetKeyboard(keyboardFullEtc);
+        } else {
+            SetKeyboard(keyboardFullNone);
+        }
+        return false;
+
+    case TerminalCloseBoxButtonID:
+        SetTitleBar(!titleShown);
+        FrmDrawForm(FrmGetActiveForm());
+        return false;
+
+    default:
+        return false;
+    }
+}
+
+
+static void TrackDrag(EventPtr e)
+{
+    Boolean moved = 0;
+    Boolean stillDown;
+    Coord x, y;
+    static RectangleType slopRect = {{0, 0}, {0, 0}};
+    static int clickCount = 0;
+    static UInt32 lastClickTime = 0;
+    UInt32 now;
+
+    // fixme drag stops all network events
+
+    x = e->screenX;
+    y = e->screenY;
+
+    // See whether this click counts as a multi-click
+    now = TimGetTicks();
+    if (RctPtInRectangle(x, y, &slopRect)  &&  
+        now - lastClickTime < SysTicksPerSecond() / 3)
+    {
+        clickCount++;
+        // keep same slop rect
+    } else {
+        clickCount = 1;
+        slopRect.topLeft.x = x - 1;
+        slopRect.topLeft.y = y - 1;
+        slopRect.extent.x = 3;
+        slopRect.extent.y = 3;
+    }
+    lastClickTime = now;
+
+    // click
+    ssh_click(ss, x, y, clickCount);
+    ssh_click(ss, x, y, -1);
+
+    while (true) {
+        SysTaskDelay(SysTicksPerSecond() / 30); // don't spin too fast
+        PenGetPoint(&x, &y, &stillDown);
+        if (!stillDown) break;
+
+        if (!moved) moved = !RctPtInRectangle(x, y, &slopRect);
+        if (moved) {
+            // drag
+            ssh_click(ss, x, y, -1);
+        }
+    }
+
+    // release
+    ssh_click(ss, x, y, 0);
+}
+
+
+static void SetScrollBar(FormPtr frmP, SetScrollBarEventType *se)
+{
+    int total = se->data.sbar.total;
+    int start = se->data.sbar.start;
+    int page = se->data.sbar.page;
+    Boolean newEnabled;
+    Boolean oldEnabled;
+    
+    // enable or disable up arrows
+    newEnabled = (start != 0);
+    oldEnabled = PrvGetControlEnabled(TerminalRScrollLineUpButtonID);
+    if (newEnabled != oldEnabled) {
+        PrvSetControlEnabled(TerminalRScrollLineUpButtonID, newEnabled);
+        PrvSetControlEnabled(TerminalRScrollPageUpButtonID, newEnabled);
+        if (newEnabled) {
+            PrvSetControlGraphics(TerminalRScrollLineUpButtonID, TerminalRScrollLineUpBitmapID, NULL);
+            PrvSetControlGraphics(TerminalRScrollPageUpButtonID, TerminalRScrollPageUpBitmapID, NULL);
+        } else {
+            PrvSetControlGraphics(TerminalRScrollLineUpButtonID, TerminalRScrollLineUpDisabledBitmapID, NULL);
+            PrvSetControlGraphics(TerminalRScrollPageUpButtonID, TerminalRScrollPageUpDisabledBitmapID, NULL);
+        }
+    }
+
+    // enable or disable down arrows
+    newEnabled = (total > start + page);
+    oldEnabled = PrvGetControlEnabled(TerminalRScrollLineDownButtonID);
+    if (newEnabled != oldEnabled) {
+        PrvSetControlEnabled(TerminalRScrollLineDownButtonID, newEnabled);
+        PrvSetControlEnabled(TerminalRScrollPageDownButtonID, newEnabled);
+        if (newEnabled) {
+            PrvSetControlGraphics(TerminalRScrollLineDownButtonID, TerminalRScrollLineDownBitmapID, 0);
+            PrvSetControlGraphics(TerminalRScrollPageDownButtonID, TerminalRScrollPageDownBitmapID, 0);
+        } else {
+            PrvSetControlGraphics(TerminalRScrollLineDownButtonID, TerminalRScrollLineDownDisabledBitmapID, 0);
+            PrvSetControlGraphics(TerminalRScrollPageDownButtonID, TerminalRScrollPageDownDisabledBitmapID, 0);
+        }
+    }
+}
+
+
+static void CheckDevice(void)
+{
+    UInt32 deviceID;
+    UInt32 companyID;
+    UInt32 version;
+
+    static Boolean deviceChecked = false;
+
+    if (deviceChecked) return;
+
+
+    // Look for Treo 600 and 650 (for keyboard tweaks)
+    if (FtrGet(sysFtrCreator, sysFtrNumOEMDeviceID, &deviceID) == 0  &&
+        FtrGet(sysFtrCreator, sysFtrNumOEMCompanyID, &companyID) == 0)
+    {
+        deviceTreo6x0 = (companyID == 'hspr'  &&  
+                         (deviceID == 'H101' || deviceID == 'H102'));
+    }
+        
+    deviceChecked = true;
+}
+
+
+static Boolean VT100EventHandler(struct FormGadgetTypeInCallback *gadget, 
+                                 UInt16 cmd, void *paramP)
+{
+    Boolean handled = false; 
+
+    switch (cmd) { 
+    case formGadgetDrawCmd: 
+        // Sent to active gadgets any time form is  
+        // drawn or redrawn. 
+        if (ss) {
+            ssh_activate(ss);
+            ssh_update(ss);
+        }
+        
+        gadget->attr.visible = true;
+        handled = true; 
+        break; 
+
+    case formGadgetHandleEventCmd: {
+        EventPtr e = (EventPtr)paramP;
+        // Sent when form receives a gadget event.  
+        // paramP points to EventType structure.  
+        if (e->eType == frmGadgetEnterEvent) { 
+            // penDown in gadget's bounds.  
+            UInt16 index;
+            FormPtr frmP = FrmGetActiveForm();
+            if ((index = FrmGetFocus(frmP)) != noFocus) {
+                // selection in vt100 disables selection in real fields
+                // fixme this might fail if there were a focused table
+                FldSetSelection((FieldPtr)FrmGetObjectPtr(frmP, index), 0, 0);
+                FrmSetFocus(frmP, noFocus);
+            }
+            TrackDrag(e);
+            handled = true; 
+        } else if (e->eType == frmGadgetMiscEvent) { 
+            // This event is sent by your application 
+            // when it needs to send info to the gadget 
+        } 
+        break; 
+    }
+
+    case formGadgetDeleteCmd:  
+        // Perform any cleanup prior to deletion. 
+        break; 
+
+    case formGadgetEraseCmd:  
+        // FrmHideObject takes care of this if you  
+        // return false.  
+        handled = false;
+        break; 
+
+    default:
+        handled = false;
+        break;
+    } 
+
+    return handled; 
+} 
+
+
+static Boolean HandleCtlRepeatEvent(EventPtr e)
+{
+    switch (e->data.ctlSelect.controlID) {
+    case TerminalRScrollPageUpButtonID:
+        if (ss) ssh_scroll(ss, -(ssh_visible_height(ss)-1));
+        return false;
+
+    case TerminalRScrollPageDownButtonID:
+        if (ss) ssh_scroll(ss, ssh_visible_height(ss)-1);
+        return false;
+        
+    case TerminalRScrollLineUpButtonID:
+        if (ss) ssh_scroll(ss, -1);
+        return false;
+        
+    case TerminalRScrollLineDownButtonID:
+        if (ss) ssh_scroll(ss, 1);
+        return false;
+
+        // fixme these repeating buttons don't work as smoothly as the 5-way
+    case TerminalBFullUpButtonID:
+        // case TerminalRArrowsUpButtonID:
+        SendUpArrowKey();
+        return false;
+
+    case TerminalBFullDownButtonID:
+        // case TerminalRArrowsDownButtonID:
+        SendDownArrowKey();
+        return false;
+
+    case TerminalBFullLeftButtonID:
+        // case TerminalRArrowsLeftButtonID:
+        SendLeftArrowKey();
+        return false;
+
+    case TerminalBFullRightButtonID:
+        // case TerminalRArrowsRightButtonID:
+        SendRightArrowKey();
+        return false;
+
+    default: 
+        return false;
+    }
+}
+
+
+Boolean TerminalFormHandleEvent(EventPtr e)
+{
+    FormPtr frmP = FrmGetActiveForm();
+
+    if (ResizeHandleEvent(e)) return true;
+
+    switch (e->eType) {
+    case frmOpenEvent:
+        // reset display states to default
+        Keyboard = -1;  // updated by first SetKeyboard()
+        KeyboardHeight = NoKeyboardHeight;
+        inputShown = true;
+        titleShown = true;
+        ctrlLocked = 0;
+        shiftLocked = 0;
+        jogPressed = 0;
+        jogPressedCtrl = 0;
+        jogPressedMeta = 0;
+        keyPressedDuringJogPress = 0;
+        jogMovedDuringJogPress = 0;
+
+        // check for device-specific hacks and features
+        CheckDevice();
+
+        // set up virtual graffiti support and initial keyboard state
+        FrmSetGadgetHandler(FrmGetActiveForm(), 
+                            PrvGetObjectIndexByID(TerminalTextGadgetID), 
+                            VT100EventHandler);
+        SetTitleBar(! PrefsGetInt(prefHideTitleBar, 0));
+
+        {
+            int top = PrefsGetInt(prefTopPane, topNone);
+            int bot = PrefsGetInt(prefBottomPane, bottomFull);
+            if (bot != bottomFull) {
+                switch (bot) {
+                case bottomNone: SetKeyboard(keyboardNone); break;
+                case bottomMini: SetKeyboard(keyboardMini); break;
+                default:         SetKeyboard(keyboardFullNone); break;
+                }
+            } else {
+                switch (top) {
+                case topNone:    SetKeyboard(keyboardFullNone); break;
+                case topABC:     SetKeyboard(keyboardFullABC);  break;
+                case top123:     SetKeyboard(keyboardFull123);  break;
+                case topIntl:    SetKeyboard(keyboardFullIntl); break;
+                case topEtc:     SetKeyboard(keyboardFullEtc);  break;
+                }
+            }
+            // SetKeyboard() draws the form.
+        }
+
+        FrmDrawForm(FrmGetActiveForm());
+        StartConnection();
+        return true;
+
+    case menuEvent:
+        switch (e->data.menu.itemID) {
+        case MenuDisconnect:
+            FrmGotoForm(MainFormID);
+            return true;
+        case MenuAboutPalmSSH:
+            FrmPopupForm(AboutFormID);
+            return true;
+        case MenuCredits:
+            FrmPopupForm(CreditsFormID);
+            return true;
+        case MenuDisplaySettings:
+            FrmPopupForm(DisplayPrefsFormID);
+            return true;
+        case MenuKeyboardSettings:
+            FrmPopupForm(KeyboardPrefsFormID);
+            return true;
+        case MenuCtrl:
+            if (CtrlPressed()) CtrlPress(0, 0);
+            else CtrlPress(1, 0);
+            return true;
+        case MenuEsc:
+            ClearModifiers();
+            SendEscapeKey();
+            return true;
+        case sysEditMenuUndoCmd:
+            // no undo in vt100 - send to fields
+            return false;
+        case sysEditMenuCutCmd:
+            // no cut in vt100 - copy will do
+            // FALL-THROUGH to copy
+        case sysEditMenuCopyCmd:
+            if (FrmGetFocus(FrmGetActiveForm()) == noFocus) {
+                ssh_copy(ss);
+                // don't send to other fields
+                return true; 
+            } else {
+                return false;
+            }
+        case sysEditMenuPasteCmd:
+            if (FrmGetFocus(FrmGetActiveForm()) == noFocus) {
+                ssh_paste(ss);
+                // don't send to other fields
+                return true;
+            } else {
+                // let real fields handle it
+                return false;
+            }
+        case sysEditMenuKeyboardCmd:
+            if (Keyboard != keyboardFullABC) {
+                SetKeyboard(keyboardFullABC);
+            } else {
+                SetKeyboard(keyboardFullNone);
+            }
+            return true;
+        case sysEditMenuGraffitiCmd:
+            SysGraffitiReferenceDialog(referenceDefault);
+            return true;
+        case MenuTCKeyboard:  // "Mini Keyboard"
+            SetKeyboard(keyboardMini);
+            return true;
+        case MenuNoKeyboard:
+            SetKeyboard(keyboardNone);
+            return true;
+        case MenuToggleTitle:
+            SetTitleBar(!titleShown);
+            FrmDrawForm(FrmGetActiveForm());
+            return true;
+        case MenuToggleStatusBar:
+            SetStatusBar(!StatusBarShown());
+            return true;
+
+        default:
+            return false;
+        }
+
+    case menuCmdBarOpenEvent: {
+        UInt16 len;
+        // fixme buttons get added in wrong order if hostname field has 
+        // a selection (need to override default field buttons)
+        // add "paste" button if there is clipboard content
+        if (ClipboardGetItem(clipboardText, &len)) {
+            MenuCmdBarAddButton(menuCmdBarOnLeft, BarPasteBitmap, menuCmdBarResultMenuItem, sysEditMenuPasteCmd, NULL);
+        }
+        // add "copy" button if there is a terminal selection
+        if (ssh_selection_exists(ss)) {
+            MenuCmdBarAddButton(menuCmdBarOnLeft, BarCopyBitmap, menuCmdBarResultMenuItem, sysEditMenuCopyCmd, NULL);
+        }
+        return false;
+    }
+
+    case frmCloseEvent:
+        if (ss) {
+            ssh_close(ss);
+            ssh_free(ss);
+            ss = NULL;
+        }
+        return false;
+
+    case fldEnterEvent:
+        // selection in real field disables selection in vt100
+        if (ss) {
+            ssh_deselect(ss);
+        }
+        return false;
+
+    case ctlRepeatEvent:
+        return HandleCtlRepeatEvent(e);
+        
+    case ctlSelectEvent:
+        return HandleCtlSelectEvent(e);
+
+    case keyDownEvent: {
+        WChar chr = e->data.keyDown.chr;
+
+        if (!EvtKeydownIsVirtual(e)) {
+            unsigned char c = (unsigned char)chr;
+            
+            // send CR rather than LF
+            if (c == 10) c = 13;
+            // remap DEL or BS based on backspace configuration
+            if (c == 8  ||  c == 127) c = Backspace();
+            // remap ` based on backquote configuration
+            if (c == '`') c = Backquote();
+
+            // send arrow key control codes rather than ASCII values
+            if (c == 28)      SendLeftArrowKey();
+            else if (c == 29) SendRightArrowKey();
+            else if (c == 30) SendUpArrowKey();
+            else if (c == 31) SendDownArrowKey();
+
+            // handle ctrl modifier on external keyboard
+            else if (e->data.keyDown.modifiers & controlKeyMask) SendModifiedKey(control_character(c));
+
+            else SendModifiedKey(c);
+
+            return true;
+        } 
+
+        // Treo 600/650 5-way hack: translate PageUp/Down into RockerUp/Down
+        if (deviceTreo6x0  &&  chr == vchrPageUp) {
+            chr = vchrRockerUp;
+        }
+        if (deviceTreo6x0  &&  chr == vchrPageDown) {
+            chr = vchrRockerDown;
+        }
+
+
+        // Handle interesting vchrs
+
+        if (chr == vchrKeyboard  ||  chr == vchrKeyboardAlpha)
+        {
+            if (Keyboard != keyboardFullABC) {
+                SetKeyboard(keyboardFullABC);
+            } else {
+                SetKeyboard(keyboardFullNone);
+            }
+            return true;
+        }
+        else if (chr == vchrKeyboardNumeric)
+        {
+            if (Keyboard != keyboardFull123) {
+                SetKeyboard(keyboardFull123);
+            } else {
+                SetKeyboard(keyboardFullNone);
+            }
+            return true;
+        }
+        else if (chr == 0x51d)
+        {
+            // Tungsten|C fn-space (usually runs sys keyboard in symbol pane)
+            // Here cycle among full(123) and T|C and none
+            if (Keyboard == keyboardMini) {
+                SetKeyboard(keyboardFull123);
+            } else if (Keyboard == keyboardNone) {
+                SetKeyboard(keyboardMini); 
+            } else {
+                SetKeyboard(keyboardNone);
+            }
+            return true;
+        }
+        else if (chr == vchrThumbWheelUp  ||  chr == vchrJogUp) {
+            // scroll up (fixme how far?)
+            if (ss) ssh_scroll(ss, -1);
+            return true;
+        }
+        else if (chr == vchrThumbWheelDown  ||  chr == vchrJogDown) {
+            // scroll down (fixme how far?)
+            if (ss) ssh_scroll(ss, +1);
+            return true;
+        }
+        else if (chr == vchrJogPushedUp) {
+            // scroll up
+            if (ss) ssh_scroll(ss, -(ssh_visible_height(ss)-1));
+            if (CtrlPressed()) CtrlPress(0, 0); // set in JogPush
+            if (MetaPressed()) MetaPress(0, 0);
+            jogMovedDuringJogPress = 1;
+            return true;
+        }
+        else if (chr == vchrJogPushedDown) {
+            // scroll down (fixme how far?)
+            if (ss) ssh_scroll(ss, ssh_visible_height(ss)-1);
+            if (CtrlPressed()) CtrlPress(0, 0); // set in JogPush
+            if (MetaPressed()) MetaPress(0, 0);
+            jogMovedDuringJogPress = 1;
+            return true;
+        }
+        else if (NavSelectPressed(e)  ||  
+                 chr == vchrRockerCenter  ||  
+                 chr == vchrThumbWheelPush)
+        {
+            // Palm 5-way / thumb wheel push == once for ctrl, twice for esc
+            int ctrlWasPressed = CtrlPressed();
+            if (ctrlWasPressed) {
+                // clear ctrl and send esc
+                ClearModifiers();
+                SendEscapeKey();
+            } else {
+                CtrlPress(1, 0);
+            }
+            return true;
+        }
+        else if (chr == vchrJogPress) 
+        {
+            // jog wheel push = ctrl/esc and page scroll
+            jogPressed = 1;
+            keyPressedDuringJogPress = 0;
+            jogMovedDuringJogPress = 0;
+            if (!CtrlPressed()) {
+                CtrlPress(1, 1); // lock until further notice
+                jogPressedCtrl = 1;
+                jogPressedMeta = 0;
+            } else {
+                CtrlPress(0, 0);
+                MetaPress(1, 1); // lock until further notice
+                jogPressedCtrl = 0;
+                jogPressedMeta = 1;
+            }
+            return true;
+        }
+        else if (chr == vchrJogRelease) 
+        {
+            if (jogPressedCtrl  &&  CtrlPressed()) {
+                if (jogMovedDuringJogPress  ||  keyPressedDuringJogPress) {
+                    // scroll or ctrl-key sent - release ctrl
+                    CtrlPress(0, 0);
+                } else {
+                    // jog press and release - unlock ctrl but leave it set
+                    CtrlPress(1, 0);
+                }
+            }
+            else if (jogPressedMeta  /* &&  MetaPressed() */) {
+                if (jogMovedDuringJogPress  ||  keyPressedDuringJogPress) {
+                    // scroll or meta-key sent - release meta
+                    MetaPress(0, 0);
+                } else {
+                    // jog press and release - release meta and send esc
+                    MetaPress(0, 0);
+                    SendEscapeKey();
+                }
+            }
+            return true;
+        }
+        else if (NavDirectionPressed(e, Up)  ||  chr == vchrRockerUp) 
+        {
+            ClearModifiers();
+            SendUpArrowKey();
+            return true;
+        } 
+        else if (NavDirectionPressed(e, Down)  ||  chr == vchrRockerDown) {
+            ClearModifiers();
+            SendDownArrowKey();
+            return true;
+        } 
+        else if (NavDirectionPressed(e, Right)  ||  chr == vchrRockerRight) {
+            ClearModifiers();
+            SendRightArrowKey();
+            return true;
+        } 
+        else if (NavDirectionPressed(e, Left)  ||  chr == vchrRockerLeft) {
+            ClearModifiers();
+            SendLeftArrowKey();
+            return true;
+        }
+        return false;
+    }
+
+    case winExitEvent:
+        if ((FormPtr)e->data.winExit.exitWindow == 
+            FrmGetFormPtr(TerminalFormID))
+        {
+            TerminalWindowActive = false;
+            if (ss) ssh_deactivate(ss);
+            return true;
+        }
+        return false;
+
+    case winEnterEvent:
+        if ((FormPtr)e->data.winEnter.enterWindow == 
+            FrmGetFormPtr(TerminalFormID))
+        {
+            if (ss) ssh_activate(ss);
+            TerminalWindowActive = true;
+            return true;
+        }
+        return false;
+
+    case usrDrawVT100Event:
+        if (ss) ssh_update(ss);
+        return true;
+
+    case usrDrawCloseBoxEvent:
+        // draw close box if it should be visible
+        // fixme test for status bar too?
+        if (!titleShown) {
+            PrvDrawControl(TerminalCloseBoxButtonID);
+        }
+        return true;
+
+    case usrSetScrollBarEvent: {
+        SetScrollBarEventType *se = (SetScrollBarEventType *)e;
+        SetScrollBar(frmP, se);
+        return true;
+    }
+
+
+    default:
+        return false;
+    }
+}
+
+
+static Boolean IsStealableVchr(EventPtr e)
+{
+    if (e->data.keyDown.chr == vchrKeyboard) return true;
+    if (e->data.keyDown.chr == vchrKeyboardAlpha) return true;
+    if (e->data.keyDown.chr == vchrKeyboardNumeric) return true;
+    if (e->data.keyDown.chr == 0x51d) return true;
+    if (e->data.keyDown.chr == vchrJogPushedDown  &&  TerminalWindowActive) return true;
+    if (e->data.keyDown.chr == vchrJogPushedUp  &&  TerminalWindowActive) return true;
+    if (e->data.keyDown.chr == vchrRockerDown  &&  TerminalWindowActive) return true;
+    if (e->data.keyDown.chr == vchrRockerUp  &&  TerminalWindowActive) return true;
+    if (e->data.keyDown.chr == vchrJogDown  &&  TerminalWindowActive) return true;
+    if (e->data.keyDown.chr == vchrJogUp  &&  TerminalWindowActive) return true;
+
+    return false;
+}
+
+// Terminal form wants to catch some key events before the system uses them:
+// - keyboard vchrs to display its own keyboard
+// - Sony jog wheel and Treo 5-way vchrs
+Boolean TerminalFormStealEvent(EventPtr e)
+{
+    // don't steal if terminal is not active, or if event is not key down
+    if (FrmGetActiveFormID() != TerminalFormID) return false;
+    if (e->eType != keyDownEvent) return false;
+
+    // steal some virtual chars anytime
+    if (EvtKeydownIsVirtual(e)  &&  IsStealableVchr(e)) return true;
+
+    // don't steal
+    return false;
+}
+
+
+// Resize the terminal form 
+void TerminalFormResize(FormPtr frmP, Int16 dh, Int16 dv) 
+{
+    UInt16 index;
+    // fixme only handles vertical well
+        
+    // hostname field: resize to width
+    // close box: move horizontally
+    // vt100 gadget: resize to width and height
+    // everything else: move vertically
+    
+    for (index = 0; index < FrmGetNumberOfObjects(frmP); index++) {
+        UInt16 id = FrmGetObjectId(frmP, index);
+        FormObjectKind type = FrmGetObjectType(frmP, index);
+        if (id == frmInvalidObjectId && type != frmGraffitiStateObj) continue;
+        
+        if (id == TerminalHostFieldID) {
+            // fixme
+        } else if (id == TerminalTextGadgetID) {
+            RectangleType bounds;
+            FrmGetObjectBounds(frmP, index, &bounds);
+            bounds.extent.x += dh;
+            bounds.extent.y += dv;
+            SetVT100Bounds(bounds);
+        } else if (id == TerminalHostFieldID) {
+            RectangleType bounds;
+            FrmGetObjectBounds(frmP, index, &bounds);
+            bounds.extent.x += dh;
+            FrmSetObjectBounds(frmP, index, &bounds);
+        } else if (id == TerminalCloseBoxButtonID) {
+            PrvMoveObject(frmP, id, dh, 0);
+        } else {
+            switch (type) {
+            case frmBitmapObj:
+                PrvMoveObject(frmP, id, 0, dv);
+                break;
+            case frmGraffitiStateObj: {
+                // FrmSetObjectPosition is insufficient for Gsi
+                Coord x, y;
+                GsiEnable(false);
+                FrmGetObjectPosition(frmP, index, &x, &y);
+                y += dv;
+                FrmSetObjectPosition(frmP, index, x, y);
+                GsiSetLocation(x, y);
+                GsiEnable(true);
+                break;
+            }
+            default:
+                PrvMoveObject(frmP, id, 0, dv);
+                break;
+            }
+        }
+    }
+}
diff --git a/forms/terminalform.h b/forms/terminalform.h
new file mode 100644 (file)
index 0000000..9b72476
--- /dev/null
@@ -0,0 +1,34 @@
+/**********
+ * Copyright (c) 2003-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef TERMINALFORM_H
+#define TERMINALFORM_H
+
+#include "includes.h"
+
+Boolean TerminalFormHandleEvent(EventPtr e) FORMS_SEGMENT;
+Boolean TerminalFormStealEvent(EventPtr e) FORMS_SEGMENT;
+void TerminalFormResize(FormPtr frmP, Int16 dh, Int16 dv) FORMS_SEGMENT;
+
+#endif
diff --git a/main.c b/main.c
new file mode 100644 (file)
index 0000000..6f7a2f2
--- /dev/null
+++ b/main.c
@@ -0,0 +1,548 @@
+/**********
+ * Copyright (c) 2003-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "ssh/ssh.h"
+#include "vt100/vt100.h"
+#include "rsrc/rsrc.h"
+#include "crypto/rand.h"
+#include "armstubs.h"
+
+#include "data/connectionlist.h"
+#include "data/hostkeys.h"
+#include "data/memolist.h"
+#include "data/prefs.h"
+#include "data/publickeys.h"
+
+#include "forms/about.h"
+#include "forms/connectionprefsform.h"
+#include "forms/detailsform.h"
+#include "forms/displayprefsform.h"
+#include "forms/hostkeysform.h"
+#include "forms/hostkeydetailsform.h"
+#include "forms/kbdintform.h"
+#include "forms/kbdint0form.h"
+#include "forms/keyboardprefsform.h"
+#include "forms/loginform.h"
+#include "forms/mainform.h"
+#include "forms/memoform.h"
+#include "forms/passwordform.h"
+#include "forms/passphraseform.h"
+#include "forms/publickeysform.h"
+#include "forms/publickeychoiceform.h"
+#include "forms/publickeydetailsform.h"
+#include "forms/terminalform.h"
+#include "forms/DIA.h"
+
+#include "crypto/openssl/bn/bn.h"
+#include "crypto/openssl/md5/md5.h"
+
+Err errno;
+
+
+
+UInt16 NetLibCount = 0;
+struct ssh_session_t *ss = NULL;
+
+
+// fixme move to recordlist
+DmOpenRef OpenDB(UInt32 type, char *name, Boolean resDB, Boolean create)
+{
+    DmOpenRef result;
+    Err err;
+
+    result = DmOpenDatabaseByTypeCreator(type, PSSH_CREATOR, dmModeReadWrite);
+    if (!result  &&  create) {
+        UInt16 card;
+        LocalID id;
+        UInt16 attr;
+
+        err = DmCreateDatabase(0, name, PSSH_CREATOR, type, resDB);
+        if (err) { complain_int("db 1", err); return 0; }
+        result = DmOpenDatabaseByTypeCreator(type, PSSH_CREATOR, dmModeReadWrite);
+        if (!result) { complain_int("db 2", DmGetLastErr()); return 0; }
+
+        // Set backup bit
+        DmOpenDatabaseInfo(result, &id, NULL, NULL, &card, NULL);
+        DmDatabaseInfo(card, id, NULL, &attr, NULL, NULL, NULL, 
+                       NULL, NULL, NULL, NULL, NULL, NULL);
+        attr |= dmHdrAttrBackup;
+        DmSetDatabaseInfo(card, id, NULL, &attr, NULL, NULL, NULL, 
+                          NULL, NULL, NULL, NULL, NULL, NULL);
+    }
+
+    return result;
+}
+
+
+
+
+
+void complain(char *err)
+{
+    char errnobuf[20];
+    WinPushDrawState();
+    WinSetCoordinateSystem(kCoordinatesStandard);
+    FrmCustomAlert(AlertFormID, err, StrIToA(errnobuf, errno), " ");
+    WinPopDrawState();
+}
+
+void complain_int(char *err, uint32_t i) 
+{
+    char intbuf[20];
+    WinPushDrawState();
+    WinSetCoordinateSystem(kCoordinatesStandard);
+    FrmCustomAlert(AlertFormID, err, StrIToA(intbuf, i), " ");
+    WinPopDrawState();
+}
+
+
+Boolean ApplicationHandleEvent(EventPtr e)
+{
+    if (e->eType == frmLoadEvent) {
+        UInt16 formId = e->data.frmLoad.formID;
+        FormPtr frmP = FrmInitForm(formId);
+        FrmSetActiveForm(frmP);
+
+        switch(formId) {
+        case MainFormID:
+            SetResizePolicy(formId);
+            SetResizeCallback(formId, MainFormResize);
+            FrmSetEventHandler(frmP, MainFormHandleEvent);
+            break;
+        case DetailsFormID:
+            SetResizePolicy(formId);
+            FrmSetEventHandler(frmP, DetailsFormHandleEvent);
+            break;
+        case LoginFormID:
+            SetResizePolicy(formId);
+            FrmSetEventHandler(frmP, LoginFormHandleEvent);
+            break;
+        case PasswordFormID:
+            SetResizePolicy(formId);
+            FrmSetEventHandler(frmP, PasswordFormHandleEvent);
+            break;
+        case TerminalFormID:
+            SetResizePolicy(formId);
+            SetResizeCallback(formId, TerminalFormResize);
+            FrmSetEventHandler(frmP, TerminalFormHandleEvent);
+            break;
+        case HostKeysFormID:
+            SetResizePolicy(formId);
+            SetResizeCallback(formId, HostKeysFormResize);
+            FrmSetEventHandler(frmP, HostKeysFormHandleEvent);
+            break;
+        case HostKeyDetailsFormID:
+            SetResizePolicy(formId);
+            FrmSetEventHandler(frmP, HostKeyDetailsFormHandleEvent);
+            break;
+        case AboutFormID:
+            SetResizePolicy(formId);
+            FrmSetEventHandler(frmP, AboutFormHandleEvent);
+            break;
+        case CreditsFormID:
+            SetResizePolicy(formId);
+            FrmSetEventHandler(frmP, CreditsFormHandleEvent);
+            break;
+        case DisplayPrefsFormID:
+            SetResizePolicy(formId);
+            FrmSetEventHandler(frmP, DisplayPrefsFormHandleEvent);
+            break;
+        case ConnectionPrefsFormID:
+            SetResizePolicy(formId);
+            FrmSetEventHandler(frmP, ConnectionPrefsFormHandleEvent);
+            break;
+        case KeyboardPrefsFormID:
+            SetResizePolicy(formId);
+            FrmSetEventHandler(frmP, KeyboardPrefsFormHandleEvent);
+            break;
+        case MemoFormID:
+            SetResizePolicy(formId);
+            SetResizeCallback(formId, MemoFormResize);
+            FrmSetEventHandler(frmP, MemoFormHandleEvent);
+            break;
+        case PublicKeysFormID:
+            SetResizePolicy(formId);
+            SetResizeCallback(formId, PublicKeysFormResize);
+            FrmSetEventHandler(frmP, PublicKeysFormHandleEvent);
+            break;
+        case PublicKeyDetailsFormID:
+            SetResizePolicy(formId);
+            FrmSetEventHandler(frmP, PublicKeyDetailsFormHandleEvent);
+            break;
+        case PassphraseFormID:
+            SetResizePolicy(formId);
+            FrmSetEventHandler(frmP, PasswordFormHandleEvent);
+            break;
+        case PublicKeyChoiceFormID:
+            SetResizePolicy(formId);
+            FrmSetEventHandler(frmP, PublicKeyChoiceFormHandleEvent);
+            break;
+        case KbdIntFormID:
+            SetResizePolicy(formId);
+            FrmSetEventHandler(frmP, KbdIntFormHandleEvent);
+            break;
+        case KbdInt0FormID:
+            SetResizePolicy(formId);
+            FrmSetEventHandler(frmP, KbdInt0FormHandleEvent);
+            break;
+        case BannerFormID:
+            SetResizePolicy(formId);
+            FrmSetEventHandler(frmP, BannerFormHandleEvent);
+            break;
+        default:
+            break;
+        }
+        return true;
+    }
+
+    return false;
+}
+
+
+static Boolean RomVersionCompatible (UInt32 requiredVersion)
+{
+    UInt32 romVersion;
+    
+    // See if we're on in minimum required version of the ROM or later.
+    // The system records the version number in a feature.  A feature is a
+    // piece of information which can be looked up by a creator and feature
+    // number.
+    FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion);
+    return (romVersion >= requiredVersion);
+}
+
+
+static Boolean CPUIsARM(void)
+{
+    UInt32 cpu;
+    FtrGet(sysFtrCreator, sysFtrNumProcessorID, &cpu);
+    return sysFtrNumProcessorIsARM(cpu);
+}
+
+static void StartupError(char *msg, UInt16 launchFlags)
+{
+    UInt32 romVersion;
+    FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion);
+
+    // If the user launched the app from the launcher, explain
+    // why the app shouldn't run.  If the app was contacted for something
+    // else, like it was asked to find a string by the system find, then
+    // don't bother the user with a warning dialog.  These flags tell how
+    // the app was launched to decided if a warning should be displayed.
+    if ((launchFlags & (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) ==
+        (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp))
+    {
+        complain(msg);
+        
+        // Pilot 1.0 will continuously relaunch this app unless we switch to 
+        // another safe one.  The sysFileCDefaultApp is considered "safe".
+        if (romVersion < 0x02000000)
+        {
+            AppLaunchWithCommand(sysFileCDefaultApp, 
+                                 sysAppLaunchCmdNormalLaunch, NULL);
+        }
+    }
+}
+
+
+static Boolean NetLibAvailable(void) 
+{
+    Err err;
+    UInt32 version;
+    
+    err = FtrGet(netFtrCreator, netFtrNumVersion, &version);
+    if (err) return false;
+    // any NetLib version is OK
+
+    err = SysLibFind("Net.lib", &AppNetRefnum);
+    if (err) return false;
+    
+    return true;
+}
+
+
+UInt32 PilotMain(UInt16 cmd, void *cmdPBP, UInt16 launchFlags)
+{
+    int loopcount = 0;
+    UInt16 version;
+    int i;
+    UInt32 tenth = SysTicksPerSecond() / 10;
+    UInt32 lastUpdate = 0;
+    UInt32 now;
+
+    if (cmd == sysAppLaunchCmdNotify) {
+        HandleResizeNotification(((SysNotifyParamType *)cmdPBP)->notifyType);
+    }
+
+    // we don't handle search et al.
+    if (cmd != sysAppLaunchCmdNormalLaunch) return 0;
+
+    // ARM CPU required
+    // fixme unless better bnlib is written
+    if (!CPUIsARM()) {
+        StartupError("pssh requires an ARM processor", launchFlags);
+        return 0;
+    }
+
+    // ROM version 3.5+ required
+    // fixme this should always pass given ARM
+    if (!RomVersionCompatible(sysMakeROMVersion(3,5,0,0,0))) {
+        StartupError("pssh requires ROM version 3.5 or later", launchFlags);
+        return 0;
+    }
+
+    // NetLib required (any version)
+    if (!NetLibAvailable()) {
+        StartupError("pssh requires NetLib", launchFlags);
+        return 0;
+    }
+
+    if (!init_arm()) {
+        StartupError("Couldn't load ARM code", launchFlags);
+        return 0;
+    }
+
+    if (!ConnectionListInit()) {
+        StartupError("Couldn't open connection list", launchFlags);
+        return 0;
+    }
+
+    if (!HostKeysInit()) {
+        StartupError("Couldn't open known host key list", launchFlags);
+        return 0;
+    }
+
+    if (!PublicKeysInit()) {
+        StartupError("Couldn't open public key list", launchFlags);
+        return 0;
+    }
+
+    if (!PrefsInit()) {
+        StartupError("Couldn't open preferences", launchFlags);
+        return 0;
+    }
+
+    {
+        uint32_t warned;
+        Err err;
+        
+        err = FtrGet(PSSH_CREATOR, ftrSecurityWarning, &warned);
+        if (err) warned = 0;
+        if (!warned) {
+            FrmCustomAlert(AlertFormID, "WARNING: pssh is substantially UNTESTED and probably INSECURE. Do not use for security-critical applications.", " ", " ");
+            warned = 1;
+            FtrSet(PSSH_CREATOR, ftrSecurityWarning, warned);
+        }
+    }
+
+    // init virtual Graffiti area API, if any
+    InitializeResizeSupport(ResizeDataID);
+    LoadResizePrefs(PSSH_CREATOR, ResizeDataID);
+
+    RAND_init();
+
+    /*
+    {
+        // fixme quickie dynamic heap check
+        UInt16 heapID;
+        UInt32 free;
+        UInt32 max;
+        UInt32 size;
+        heapID = MemHeapID(0, 0);
+        MemHeapFreeBytes(heapID, &free, &max);
+        size = MemHeapSize(heapID);
+        complain_int("dynamic heap size ", size);
+        complain_int("dynamic heap free ", free);
+        complain_int("dynamic heap max chunk ", max);
+    }
+    */
+
+    {
+        MemHandle fontH;
+        FontType *fontP;
+
+#define DEFINEFONT(f) \
+        fontH = DmGetResource(fontExtRscType, f); \
+        fontP = MemHandleLock(fontH); \
+        FntDefineFont((FontID)f, fontP);
+
+        DEFINEFONT(NanoFontSingleID);
+        DEFINEFONT(NanoFontDoubleID);
+        DEFINEFONT(MediumFontSingleID);
+        DEFINEFONT(MediumFontDoubleID);
+        DEFINEFONT(PasswordFontID);
+
+#undef DEFINEFONT
+    }
+
+    // 10 second timeout for DNS and connect()
+    AppNetTimeout = SysTicksPerSecond() * 10;
+
+    FrmGotoForm(MainFormID);
+
+    do {
+        Int32 delay;
+        int lastEventType;
+
+        if (ss  &&  !ssh_is_closed(ss)) {
+            fd_set rfds;
+            int maxfd;
+            int ssfd;
+            int selected;
+            struct timeval tv;
+
+            FD_ZERO(&rfds);
+            FD_SET(STDIN_FILENO, &rfds);
+            
+            ssfd = ssh_request_select(ss, &rfds, NULL);
+            maxfd = MAX(STDIN_FILENO, ssfd);
+
+            // Don't block in select() if there are events in the event queue.
+            // fixme even if there are no events, keep block time short 
+            // because of stuck-in-select problem
+            if (EvtEventAvail()) {
+                tv.tv_usec = 0;
+                tv.tv_sec = 0;
+            } else {
+                tv.tv_usec = 100000L;  // 1/10 sec
+                tv.tv_sec = 0;
+            }
+
+            selected = select(maxfd + 1, &rfds, NULL, NULL, &tv);
+
+            if (selected >= 0) {
+                if (FD_ISSET(ssfd, &rfds)) {
+                    EventType e = {0};
+                    e.eType = usrNetEvent;
+                    EvtAddUniqueEventToQueue(&e, 0, true);
+                }
+            }
+
+            delay = 0; // DON'T block in EvtGetEvent
+        } else {
+            // No sockets to select() yet
+            delay = -1;  // DO block in EvtGetEvent (forever)
+        }
+
+
+        {
+            EventType event;
+            Err err;
+
+            EvtGetEvent(&event, delay);
+
+            if (event.eType == usrNetEvent) {
+                // Handle incoming network data
+                if (ss  &&  !ssh_is_closed(ss)) {
+                    ssh_read(ss);
+                }
+            }
+
+            if (TerminalFormStealEvent(&event)) {
+                FrmDispatchEvent(&event);
+            } else {
+                if (!SysHandleEvent(&event)) {
+                    if (!MenuHandleEvent(NULL, &event, &err)) {
+                        if (!ApplicationHandleEvent(&event)) {
+                            FrmDispatchEvent(&event);
+                        }
+                    }
+                }
+            }
+
+            if (ss) {
+                now = TimGetTicks();
+                if (now >= lastUpdate + tenth) {
+                    ssh_task(ss);
+                    lastUpdate = now;
+                }
+            }
+
+            if (event.eType == keyDownEvent || event.eType == keyUpEvent || 
+                event.eType == penUpEvent   || event.eType == penMoveEvent) 
+            {
+                RAND_add_event_entropy(&event);
+            }
+
+            if (event.eType == appStopEvent) break;
+        }
+    } while (1);
+
+ done:
+    FrmSaveAllForms();
+    FrmCloseAllForms();
+
+    MemoListFree();
+    PublicKeysFree();
+    HostKeysFree();
+    ConnectionListFree();
+
+    for (i = 0; i < NetLibCount; i++) {
+        NetLibClose(AppNetRefnum, false);
+    }
+
+    SaveResizePrefs(PSSH_CREATOR, ResizeDataID, 0);
+    TerminateResizeSupport();
+
+    RAND_stop();
+
+    PealUnload(arm_module);
+
+    return 0;
+}
+
+
+
+/*
+
+#if 0
+        // memory leak tracing
+        {
+            static int inited = 0;
+            static UInt16 heapID;
+            static uint32_t gen = 0;
+            UInt32 free;
+            UInt32 max;
+            UInt32 size;
+            extern uint32_t ev_block_count;
+            extern uint32_t ev_byte_count;
+            //            extern uint32_t ev_blocks_used;
+            if (!inited) {
+                inited = 1;
+                heapID = MemHeapID(0, 0);
+            }
+            MemHeapFreeBytes(heapID, &free, &max);
+            size = MemHeapSize(heapID);
+            
+            debug_printf("mem %luK,%lu[%luK]AB,%lu gen", (size-free)/1024, ev_block_count, ev_byte_count/1024, gen++);
+            // if (gen % 100 == 0) arena_dump_blocks();
+        }
+#endif
+        
+        // fixme write queue
+        //if (ssh_is_selected(ss, &wfds)) {
+        // ssh_write(ss);
+        // }
+        */
diff --git a/pssh.def b/pssh.def
new file mode 100644 (file)
index 0000000..5067a89
--- /dev/null
+++ b/pssh.def
@@ -0,0 +1,5 @@
+// app name and creator code
+application { "pssh" GPss }
+
+// secondary code resources
+multiple code { crypto crypto2 ssh ssh2 forms vt100 }
diff --git a/rsrc/123buttons.bmp b/rsrc/123buttons.bmp
new file mode 100644 (file)
index 0000000..30d8203
Binary files /dev/null and b/rsrc/123buttons.bmp differ
diff --git a/rsrc/abcbuttons.bmp b/rsrc/abcbuttons.bmp
new file mode 100644 (file)
index 0000000..d6fb196
Binary files /dev/null and b/rsrc/abcbuttons.bmp differ
diff --git a/rsrc/buttons.bmp b/rsrc/buttons.bmp
new file mode 100644 (file)
index 0000000..84b3d93
Binary files /dev/null and b/rsrc/buttons.bmp differ
diff --git a/rsrc/closebox.bmp b/rsrc/closebox.bmp
new file mode 100644 (file)
index 0000000..9961d21
Binary files /dev/null and b/rsrc/closebox.bmp differ
diff --git a/rsrc/closeboxhi.bmp b/rsrc/closeboxhi.bmp
new file mode 100644 (file)
index 0000000..6fe0fa5
Binary files /dev/null and b/rsrc/closeboxhi.bmp differ
diff --git a/rsrc/closeboxselected.bmp b/rsrc/closeboxselected.bmp
new file mode 100644 (file)
index 0000000..e2dbd74
Binary files /dev/null and b/rsrc/closeboxselected.bmp differ
diff --git a/rsrc/closeboxselectedhi.bmp b/rsrc/closeboxselectedhi.bmp
new file mode 100644 (file)
index 0000000..d980d32
Binary files /dev/null and b/rsrc/closeboxselectedhi.bmp differ
diff --git a/rsrc/downarrow.bmp b/rsrc/downarrow.bmp
new file mode 100644 (file)
index 0000000..8588122
Binary files /dev/null and b/rsrc/downarrow.bmp differ
diff --git a/rsrc/downarrowhi.bmp b/rsrc/downarrowhi.bmp
new file mode 100644 (file)
index 0000000..c825a79
Binary files /dev/null and b/rsrc/downarrowhi.bmp differ
diff --git a/rsrc/downarrowselected.bmp b/rsrc/downarrowselected.bmp
new file mode 100644 (file)
index 0000000..f6df0da
Binary files /dev/null and b/rsrc/downarrowselected.bmp differ
diff --git a/rsrc/downarrowselectedhi.bmp b/rsrc/downarrowselectedhi.bmp
new file mode 100644 (file)
index 0000000..6a44752
Binary files /dev/null and b/rsrc/downarrowselectedhi.bmp differ
diff --git a/rsrc/etcbuttons.bmp b/rsrc/etcbuttons.bmp
new file mode 100644 (file)
index 0000000..7e0ac03
Binary files /dev/null and b/rsrc/etcbuttons.bmp differ
diff --git a/rsrc/leftarrow.bmp b/rsrc/leftarrow.bmp
new file mode 100644 (file)
index 0000000..69758e5
Binary files /dev/null and b/rsrc/leftarrow.bmp differ
diff --git a/rsrc/leftarrowhi.bmp b/rsrc/leftarrowhi.bmp
new file mode 100644 (file)
index 0000000..8f71521
Binary files /dev/null and b/rsrc/leftarrowhi.bmp differ
diff --git a/rsrc/leftarrowselected.bmp b/rsrc/leftarrowselected.bmp
new file mode 100644 (file)
index 0000000..f3ed5d2
Binary files /dev/null and b/rsrc/leftarrowselected.bmp differ
diff --git a/rsrc/leftarrowselectedhi.bmp b/rsrc/leftarrowselectedhi.bmp
new file mode 100644 (file)
index 0000000..80491ed
Binary files /dev/null and b/rsrc/leftarrowselectedhi.bmp differ
diff --git a/rsrc/linedown.bmp b/rsrc/linedown.bmp
new file mode 100644 (file)
index 0000000..2e28ff4
Binary files /dev/null and b/rsrc/linedown.bmp differ
diff --git a/rsrc/linedowndisabled.bmp b/rsrc/linedowndisabled.bmp
new file mode 100644 (file)
index 0000000..6df01e6
Binary files /dev/null and b/rsrc/linedowndisabled.bmp differ
diff --git a/rsrc/linedowndisabledhi.bmp b/rsrc/linedowndisabledhi.bmp
new file mode 100644 (file)
index 0000000..03ce8a8
Binary files /dev/null and b/rsrc/linedowndisabledhi.bmp differ
diff --git a/rsrc/linedownhi.bmp b/rsrc/linedownhi.bmp
new file mode 100644 (file)
index 0000000..21a9246
Binary files /dev/null and b/rsrc/linedownhi.bmp differ
diff --git a/rsrc/linedownselected.bmp b/rsrc/linedownselected.bmp
new file mode 100644 (file)
index 0000000..27dd435
Binary files /dev/null and b/rsrc/linedownselected.bmp differ
diff --git a/rsrc/linedownselectedhi.bmp b/rsrc/linedownselectedhi.bmp
new file mode 100644 (file)
index 0000000..4c94930
Binary files /dev/null and b/rsrc/linedownselectedhi.bmp differ
diff --git a/rsrc/lineup.bmp b/rsrc/lineup.bmp
new file mode 100644 (file)
index 0000000..b01f624
Binary files /dev/null and b/rsrc/lineup.bmp differ
diff --git a/rsrc/lineupdisabled.bmp b/rsrc/lineupdisabled.bmp
new file mode 100644 (file)
index 0000000..9abf431
Binary files /dev/null and b/rsrc/lineupdisabled.bmp differ
diff --git a/rsrc/lineupdisabledhi.bmp b/rsrc/lineupdisabledhi.bmp
new file mode 100644 (file)
index 0000000..e9567bd
Binary files /dev/null and b/rsrc/lineupdisabledhi.bmp differ
diff --git a/rsrc/lineuphi.bmp b/rsrc/lineuphi.bmp
new file mode 100644 (file)
index 0000000..80c57ee
Binary files /dev/null and b/rsrc/lineuphi.bmp differ
diff --git a/rsrc/lineupselected.bmp b/rsrc/lineupselected.bmp
new file mode 100644 (file)
index 0000000..576e112
Binary files /dev/null and b/rsrc/lineupselected.bmp differ
diff --git a/rsrc/lineupselectedhi.bmp b/rsrc/lineupselectedhi.bmp
new file mode 100644 (file)
index 0000000..ee60b67
Binary files /dev/null and b/rsrc/lineupselectedhi.bmp differ
diff --git a/rsrc/med.font b/rsrc/med.font
new file mode 100644 (file)
index 0000000..9f2776e
Binary files /dev/null and b/rsrc/med.font differ
diff --git a/rsrc/medsingle.font b/rsrc/medsingle.font
new file mode 100644 (file)
index 0000000..6b434a4
Binary files /dev/null and b/rsrc/medsingle.font differ
diff --git a/rsrc/nano.font b/rsrc/nano.font
new file mode 100644 (file)
index 0000000..07673ec
Binary files /dev/null and b/rsrc/nano.font differ
diff --git a/rsrc/nanosingle.font b/rsrc/nanosingle.font
new file mode 100644 (file)
index 0000000..94aaffa
Binary files /dev/null and b/rsrc/nanosingle.font differ
diff --git a/rsrc/pagedown.bmp b/rsrc/pagedown.bmp
new file mode 100644 (file)
index 0000000..2e77191
Binary files /dev/null and b/rsrc/pagedown.bmp differ
diff --git a/rsrc/pagedowndisabled.bmp b/rsrc/pagedowndisabled.bmp
new file mode 100644 (file)
index 0000000..dae9545
Binary files /dev/null and b/rsrc/pagedowndisabled.bmp differ
diff --git a/rsrc/pagedowndisabledhi.bmp b/rsrc/pagedowndisabledhi.bmp
new file mode 100644 (file)
index 0000000..9325a7c
Binary files /dev/null and b/rsrc/pagedowndisabledhi.bmp differ
diff --git a/rsrc/pagedownhi.bmp b/rsrc/pagedownhi.bmp
new file mode 100644 (file)
index 0000000..9be3823
Binary files /dev/null and b/rsrc/pagedownhi.bmp differ
diff --git a/rsrc/pagedownselected.bmp b/rsrc/pagedownselected.bmp
new file mode 100644 (file)
index 0000000..a0e0aeb
Binary files /dev/null and b/rsrc/pagedownselected.bmp differ
diff --git a/rsrc/pagedownselectedhi.bmp b/rsrc/pagedownselectedhi.bmp
new file mode 100644 (file)
index 0000000..2ad65f6
Binary files /dev/null and b/rsrc/pagedownselectedhi.bmp differ
diff --git a/rsrc/pageup.bmp b/rsrc/pageup.bmp
new file mode 100644 (file)
index 0000000..d5e86b5
Binary files /dev/null and b/rsrc/pageup.bmp differ
diff --git a/rsrc/pageupdisabled.bmp b/rsrc/pageupdisabled.bmp
new file mode 100644 (file)
index 0000000..7968cf7
Binary files /dev/null and b/rsrc/pageupdisabled.bmp differ
diff --git a/rsrc/pageupdisabledhi.bmp b/rsrc/pageupdisabledhi.bmp
new file mode 100644 (file)
index 0000000..775c937
Binary files /dev/null and b/rsrc/pageupdisabledhi.bmp differ
diff --git a/rsrc/pageuphi.bmp b/rsrc/pageuphi.bmp
new file mode 100644 (file)
index 0000000..3836a2f
Binary files /dev/null and b/rsrc/pageuphi.bmp differ
diff --git a/rsrc/pageupselected.bmp b/rsrc/pageupselected.bmp
new file mode 100644 (file)
index 0000000..c3db424
Binary files /dev/null and b/rsrc/pageupselected.bmp differ
diff --git a/rsrc/pageupselectedhi.bmp b/rsrc/pageupselectedhi.bmp
new file mode 100644 (file)
index 0000000..1892850
Binary files /dev/null and b/rsrc/pageupselectedhi.bmp differ
diff --git a/rsrc/passwordfont b/rsrc/passwordfont
new file mode 100644 (file)
index 0000000..eb493df
Binary files /dev/null and b/rsrc/passwordfont differ
diff --git a/rsrc/pssh.rcp b/rsrc/pssh.rcp
new file mode 100755 (executable)
index 0000000..c64612f
--- /dev/null
@@ -0,0 +1,1270 @@
+/**********\r
+ * Copyright (c) 2003-2005 Greg Parker.  All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in the\r
+ *    documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``AS IS'' AND ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ **********/\r
+\r
+#include "rsrc.h"\r
+#include "forms/resizeconsts.h"\r
+\r
+VERSION ID 1 PSSH_VERSION\r
+\r
+BITMAP ID TerminalCloseBoxBitmapID COMPRESS COMPRESSBEST\r
+BEGIN\r
+    BITMAP "closebox.bmp" BPP 1 DENSITY 72\r
+    BITMAP "closeboxhi.bmp" BPP 1 DENSITY 144\r
+END\r
+\r
+BITMAP ID TerminalCloseBoxSelectedBitmapID COMPRESS COMPRESSBEST\r
+BEGIN\r
+    BITMAP "closeboxselected.bmp" BPP 1 DENSITY 72\r
+    BITMAP "closeboxselectedhi.bmp" BPP 1 DENSITY 144\r
+END\r
+\r
+BITMAP ID TerminalBTCButtonsBitmapID "tcbuttons.bmp" COMPRESS COMPRESSBEST\r
+BITMAP ID TerminalTABCButtonsBitmapID "abcbuttons.bmp" COMPRESS COMPRESSBEST\r
+BITMAP ID TerminalT123ButtonsBitmapID "123buttons.bmp" COMPRESS COMPRESSBEST\r
+BITMAP ID TerminalTEtcButtonsBitmapID "etcbuttons.bmp" COMPRESS COMPRESSBEST\r
+\r
+BITMAP ID TerminalBFullUpBitmapID COMPRESS COMPRESSBEST\r
+BEGIN\r
+    BITMAP "uparrow.bmp" BPP 1 DENSITY 72\r
+    BITMAP "uparrowhi.bmp" BPP 1 DENSITY 144\r
+END\r
+BITMAP ID TerminalBFullDownBitmapID COMPRESS COMPRESSBEST\r
+BEGIN\r
+    BITMAP "downarrow.bmp" BPP 1 DENSITY 72\r
+    BITMAP "downarrowhi.bmp" BPP 1 DENSITY 144\r
+END\r
+BITMAP ID TerminalBFullLeftBitmapID COMPRESS COMPRESSBEST\r
+BEGIN\r
+    BITMAP "leftarrow.bmp" BPP 1 DENSITY 72\r
+    BITMAP "leftarrowhi.bmp" BPP 1 DENSITY 144\r
+END\r
+BITMAP ID TerminalBFullRightBitmapID COMPRESS COMPRESSBEST\r
+BEGIN\r
+    BITMAP "rightarrow.bmp" BPP 1 DENSITY 72\r
+    BITMAP "rightarrowhi.bmp" BPP 1 DENSITY 144\r
+END\r
+\r
+BITMAP ID TerminalBFullUpSelectedBitmapID COMPRESS COMPRESSBEST\r
+BEGIN\r
+    BITMAP "uparrowselected.bmp" BPP 1 DENSITY 72\r
+    BITMAP "uparrowselectedhi.bmp" BPP 1 DENSITY 144\r
+END\r
+BITMAP ID TerminalBFullDownSelectedBitmapID COMPRESS COMPRESSBEST\r
+BEGIN\r
+    BITMAP "downarrowselected.bmp" BPP 1 DENSITY 72\r
+    BITMAP "downarrowselectedhi.bmp" BPP 1 DENSITY 144\r
+END\r
+BITMAP ID TerminalBFullLeftSelectedBitmapID COMPRESS COMPRESSBEST\r
+BEGIN\r
+    BITMAP "leftarrowselected.bmp" BPP 1 DENSITY 72\r
+    BITMAP "leftarrowselectedhi.bmp" BPP 1 DENSITY 144\r
+END\r
+BITMAP ID TerminalBFullRightSelectedBitmapID COMPRESS COMPRESSBEST\r
+BEGIN\r
+    BITMAP "rightarrowselected.bmp" BPP 1 DENSITY 72\r
+    BITMAP "rightarrowselectedhi.bmp" BPP 1 DENSITY 144\r
+END\r
+\r
+BITMAP ID TerminalRScrollLineUpBitmapID COMPRESS COMPRESSBEST \r
+BEGIN\r
+    BITMAP "lineup.bmp" BPP 1 DENSITY 72\r
+    BITMAP "lineuphi.bmp" BPP 1 DENSITY 144\r
+END\r
+BITMAP ID TerminalRScrollLineDownBitmapID COMPRESS COMPRESSBEST \r
+BEGIN\r
+    BITMAP "linedown.bmp" BPP 1 DENSITY 72\r
+    BITMAP "linedownhi.bmp" BPP 1 DENSITY 144\r
+END\r
+BITMAP ID TerminalRScrollLineUpSelectedBitmapID COMPRESS COMPRESSBEST \r
+BEGIN\r
+    BITMAP "lineupselected.bmp" BPP 1 DENSITY 72\r
+    BITMAP "lineupselectedhi.bmp" BPP 1 DENSITY 144\r
+END\r
+BITMAP ID TerminalRScrollLineDownSelectedBitmapID COMPRESS COMPRESSBEST \r
+BEGIN\r
+    BITMAP "linedownselected.bmp" BPP 1 DENSITY 72\r
+    BITMAP "linedownselectedhi.bmp" BPP 1 DENSITY 144\r
+END\r
+BITMAP ID TerminalRScrollLineUpDisabledBitmapID COMPRESS COMPRESSBEST \r
+BEGIN\r
+    BITMAP "lineupdisabled.bmp" BPP 1 DENSITY 72\r
+    BITMAP "lineupdisabledhi.bmp" BPP 1 DENSITY 144\r
+END\r
+BITMAP ID TerminalRScrollLineDownDisabledBitmapID COMPRESS COMPRESSBEST \r
+BEGIN\r
+    BITMAP "linedowndisabled.bmp" BPP 1 DENSITY 72\r
+    BITMAP "linedowndisabledhi.bmp" BPP 1 DENSITY 144\r
+END\r
+\r
+BITMAP ID TerminalRScrollPageUpBitmapID COMPRESS COMPRESSBEST \r
+BEGIN\r
+    BITMAP "pageup.bmp" BPP 1 DENSITY 72\r
+    BITMAP "pageuphi.bmp" BPP 1 DENSITY 144\r
+END\r
+BITMAP ID TerminalRScrollPageDownBitmapID COMPRESS COMPRESSBEST \r
+BEGIN\r
+    BITMAP "pagedown.bmp" BPP 1 DENSITY 72\r
+    BITMAP "pagedownhi.bmp" BPP 1 DENSITY 144\r
+END\r
+BITMAP ID TerminalRScrollPageUpSelectedBitmapID COMPRESS COMPRESSBEST \r
+BEGIN\r
+    BITMAP "pageupselected.bmp" BPP 1 DENSITY 72\r
+    BITMAP "pageupselectedhi.bmp" BPP 1 DENSITY 144\r
+END\r
+BITMAP ID TerminalRScrollPageDownSelectedBitmapID COMPRESS COMPRESSBEST \r
+BEGIN\r
+    BITMAP "pagedownselected.bmp" BPP 1 DENSITY 72\r
+    BITMAP "pagedownselectedhi.bmp" BPP 1 DENSITY 144\r
+END\r
+BITMAP ID TerminalRScrollPageUpDisabledBitmapID COMPRESS COMPRESSBEST \r
+BEGIN\r
+    BITMAP "pageupdisabled.bmp" BPP 1 DENSITY 72\r
+    BITMAP "pageupdisabledhi.bmp" BPP 1 DENSITY 144\r
+END\r
+BITMAP ID TerminalRScrollPageDownDisabledBitmapID COMPRESS COMPRESSBEST \r
+BEGIN\r
+    BITMAP "pagedowndisabled.bmp" BPP 1 DENSITY 72\r
+    BITMAP "pagedowndisabledhi.bmp" BPP 1 DENSITY 144\r
+END\r
+\r
+DATA "nfnt" ID NanoFontDoubleID "nano.font"\r
+DATA "nfnt" ID NanoFontSingleID "nanosingle.font"\r
+DATA "nfnt" ID MediumFontDoubleID "med.font"\r
+DATA "nfnt" ID MediumFontSingleID "medsingle.font"\r
+DATA "nfnt" ID PasswordFontID "passwordfont"\r
+\r
+\r
+FORM ID LoginFormID AT (2 73 156 85)\r
+USABLE\r
+MODAL\r
+DEFAULTBTNID LoginFormConnectButtonID\r
+BEGIN\r
+    TITLE "New Connection"\r
+    \r
+    BUTTON "Connect" ID LoginFormConnectButtonID AT (7 66 40 12)\r
+    BUTTON "Cancel" ID LoginFormCancelButtonID AT (54 66 40 12) \r
+    BUTTON "Save" ID LoginFormSaveButtonID AT (101 66 40 12) \r
+\r
+    FIELD ID LoginFormHostFieldID     AT (52 18 96 12) UNDERLINED MAXCHARS 80\r
+    FIELD ID LoginFormUsernameFieldID AT (52 32 96 12) UNDERLINED MAXCHARS 80 \r
+    FIELD ID LoginFormPortFieldID     AT (52 46 30 12) UNDERLINED MAXCHARS 5 NUMERIC\r
+\r
+    LABEL "Host:" AUTOID AT (29 18)\r
+    LABEL "Username:" AUTOID AT (6 32)\r
+    LABEL "Port:" AUTOID AT (30 46)\r
+\r
+    GRAFFITISTATEINDICATOR AT (145 67)\r
+END\r
+\r
+\r
+FORM ID DetailsFormID AT (2 73 156 85)\r
+USABLE\r
+MODAL\r
+DEFAULTBTNID DetailsFormOKButtonID\r
+BEGIN\r
+    TITLE "Connection Details"\r
+    \r
+    BUTTON "OK" ID DetailsFormOKButtonID AT (7 66 40 12)\r
+    BUTTON "Cancel" ID DetailsFormCancelButtonID AT (54 66 40 12) \r
+    BUTTON "Delete..." ID DetailsFormDeleteButtonID AT (101 66 40 12) \r
+\r
+    FIELD ID DetailsFormHostFieldID     AT (52 18 96 12) UNDERLINED MAXCHARS 80 \r
+    FIELD ID DetailsFormUsernameFieldID AT (52 32 96 12) UNDERLINED MAXCHARS 80 \r
+    FIELD ID DetailsFormPortFieldID     AT (52 46 30 12) UNDERLINED MAXCHARS 5 NUMERIC\r
+\r
+    LABEL "Host:" AUTOID AT (29 18)\r
+    LABEL "Username:" AUTOID AT (6 32)\r
+    LABEL "Port:" AUTOID AT (30 46)\r
+\r
+    GRAFFITISTATEINDICATOR AT (145 67)\r
+END\r
+\r
+\r
+FORM ID PasswordFormID AT (2 59 156 99)\r
+USABLE\r
+MODAL\r
+DEFAULTBTNID PasswordFormOKButtonID\r
+BEGIN\r
+    TITLE "Enter Password"\r
+    \r
+    BUTTON "OK" ID PasswordFormOKButtonID AT (7 80 44 12)\r
+    BUTTON "Cancel" ID PasswordFormCancelButtonID AT (58 80 36 12) \r
+\r
+    FIELD ID PasswordFormHostFieldID     AT (52 18 96 12) NONEDITABLE MAXCHARS 80 \r
+    FIELD ID PasswordFormUsernameFieldID AT (52 32 96 12) UNDERLINED MAXCHARS 80 \r
+    FIELD ID PasswordFormPasswordFieldID AT (52 46 96 12) UNDERLINED MAXCHARS 80 FONT PasswordFontID\r
+\r
+    CHECKBOX "Show password while typing" ID PasswordFormEchoCheckboxID AT (13 62 134 12) \r
+\r
+    LABEL "Host:" AUTOID AT (29 18)\r
+    LABEL "Username:" AUTOID AT (6 32)\r
+    LABEL "Password:" AUTOID AT (10 46)\r
+\r
+    GRAFFITISTATEINDICATOR AT (142 84)\r
+END\r
+\r
+\r
+FORM ID MainFormID AT (0 0 160 160)\r
+USABLE\r
+MENUID MainMenuBar\r
+BEGIN\r
+    TITLE "pssh"\r
+\r
+    BUTTON "Connect" ID MainConnectButtonID AT (1 147 42 12)\r
+    BUTTON "New..." ID MainNewButtonID AT (69 147 42 12)\r
+    BUTTON "Details..." ID MainDetailsButtonID AT (117 147 42 12)\r
+\r
+    TABLE ID MainConnectionTableID AT (0 16 152 128) ROWS 22 COLUMNS 1 COLUMNWIDTHS 152\r
+\r
+    SCROLLBAR ID MainConnectionScrollbarID AT (153 16 7 128) \r
+END\r
+\r
+\r
+FORM ID TerminalFormID AT (0 0 160 160)\r
+USABLE\r
+MENUID TerminalMenuBar\r
+BEGIN\r
+    TITLE "pssh"\r
+\r
+    /* Initial keyboard state is all hidden, with vt100 covering the screen */\r
+    /* This is reconfigured when the form is opened. */\r
+\r
+    /* button bitmaps should be before buttons themselves */\r
+    /* ABC/123/Etc buttons overwrite TC buttons and ctrl button */\r
+    /* TC buttons overwrites Gsi */\r
+    FORMBITMAP AT (0 87) BITMAP TerminalT123ButtonsBitmapID  NONUSABLE\r
+    FORMBITMAP AT (24 135) BITMAP TerminalBTCButtonsBitmapID NONUSABLE\r
+    FORMBITMAP AT (0 87) BITMAP TerminalTABCButtonsBitmapID  NONUSABLE\r
+    FORMBITMAP AT (0 87) BITMAP TerminalTEtcButtonsBitmapID  NONUSABLE\r
+\r
+    /* buttons: ctrl and esc */\r
+    PUSHBUTTON "ctl" ID TerminalCtrlButtonID AT (1 136 19 11) NONUSABLE\r
+    BUTTON "esc" ID TerminalMetaButtonID AT (1 148 19 11) NONUSABLE\r
+\r
+    /* Graffiti indicator */\r
+    GRAFFITISTATEINDICATOR AT (119 150)\r
+\r
+    /* username@host  - this should be BEFORE text gadget*/\r
+    FIELD ID TerminalHostFieldID AT (29 1 131 12) NONEDITABLE RIGHTALIGN MAXCHARS 80\r
+\r
+    /* vt100 area */\r
+    GADGET ID TerminalTextGadgetID AT (0 15 160 145) \r
+\r
+    /* close box bitmap - this should be AFTER text gadget */\r
+    BUTTON "" ID TerminalCloseBoxButtonID AT (153 1 6 6) NONUSABLE NOFRAME GRAPHICAL BITMAPID TerminalCloseBoxBitmapID SELECTEDBITMAPID TerminalCloseBoxSelectedBitmapID\r
+\r
+    /* Scroll arrows */\r
+    REPEATBUTTON "" ID TerminalRScrollLineUpButtonID   AT (130 136 15 12) NOFRAME GRAPHICAL BITMAPID TerminalRScrollLineUpBitmapID SELECTEDBITMAPID TerminalRScrollLineUpSelectedBitmapID NONUSABLE\r
+    REPEATBUTTON "" ID TerminalRScrollLineDownButtonID AT (130 148 15 12) NOFRAME GRAPHICAL BITMAPID TerminalRScrollLineDownBitmapID SELECTEDBITMAPID TerminalRScrollLineDownSelectedBitmapID NONUSABLE\r
+    REPEATBUTTON "" ID TerminalRScrollPageUpButtonID   AT (145 136 15 12) NOFRAME GRAPHICAL BITMAPID TerminalRScrollPageUpBitmapID SELECTEDBITMAPID TerminalRScrollPageUpSelectedBitmapID NONUSABLE\r
+    REPEATBUTTON "" ID TerminalRScrollPageDownButtonID AT (145 148 15 12) NOFRAME GRAPHICAL BITMAPID TerminalRScrollPageDownBitmapID SELECTEDBITMAPID TerminalRScrollPageDownSelectedBitmapID NONUSABLE\r
+\r
+    /* Tungsten C bottom pane */\r
+    /* Tungsten C: ~ ` % ^ & = | \ [ ] { } < > ; */\r
+    /* Treo 600:   ~ ` % ^ _ = | \ [ ] { } < > ; */\r
+    /* Sony NX80V: ` ^ | { } */\r
+    /* Sont UX50:  ` | { } */\r
+    BUTTON "~"  ID TerminalBTCFirstButtonID+0  AT (25  136 12 11) NOFRAME NONUSABLE\r
+    BUTTON "`"  ID TerminalBTCFirstButtonID+1  AT (38  136 12 11) NOFRAME NONUSABLE\r
+    BUTTON "%"  ID TerminalBTCFirstButtonID+2  AT (51  136 12 11) NOFRAME NONUSABLE\r
+    BUTTON "^"  ID TerminalBTCFirstButtonID+3  AT (64  136 12 11) NOFRAME NONUSABLE\r
+    /* NOTE "&" key's ID is used in code (TerminalBTCAmpersandButtonID) */\r
+    BUTTON "&"  ID TerminalBTCFirstButtonID+4  AT (77  136 12 11) NOFRAME NONUSABLE\r
+    BUTTON "="  ID TerminalBTCFirstButtonID+5  AT (90  136 12 11) NOFRAME NONUSABLE\r
+    BUTTON "|"  ID TerminalBTCFirstButtonID+6  AT (103 136 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\\" ID TerminalBTCFirstButtonID+7  AT (116 136 12 11) NOFRAME NONUSABLE\r
+    BUTTON "["  ID TerminalBTCFirstButtonID+8  AT (25  148 12 11) NOFRAME NONUSABLE\r
+    BUTTON "]"  ID TerminalBTCFirstButtonID+9  AT (38  148 12 11) NOFRAME NONUSABLE\r
+    BUTTON "{"  ID TerminalBTCFirstButtonID+10 AT (51  148 12 11) NOFRAME NONUSABLE\r
+    BUTTON "}"  ID TerminalBTCFirstButtonID+11 AT (64  148 12 11) NOFRAME NONUSABLE\r
+    BUTTON "<"  ID TerminalBTCFirstButtonID+12 AT (77  148 12 11) NOFRAME NONUSABLE\r
+    BUTTON ">"  ID TerminalBTCFirstButtonID+13 AT (90  148 12 11) NOFRAME NONUSABLE\r
+    BUTTON ";"  ID TerminalBTCFirstButtonID+14 AT (103 148 12 11) NOFRAME NONUSABLE\r
+\r
+\r
+    /* ABC and 123 bottom pane */\r
+    PUSHBUTTON "abc"  ID TerminalBFullABCButtonID  AT (25 136 19 11) NONUSABLE\r
+    PUSHBUTTON "123"  ID TerminalBFull123ButtonID  AT (45 136 21 11) NONUSABLE\r
+    PUSHBUTTON "intl" ID TerminalBFullIntlButtonID AT (25 148 19 11) NONUSABLE\r
+    PUSHBUTTON "etc"  ID TerminalBFullEtcButtonID  AT (45 148 21 11) NONUSABLE\r
+\r
+    REPEATBUTTON "^" ID TerminalBFullUpButtonID    AT (84 136 14 12) NOFRAME GRAPHICAL BITMAPID TerminalBFullUpBitmapID SELECTEDBITMAPID TerminalBFullUpSelectedBitmapID NONUSABLE\r
+    REPEATBUTTON "v" ID TerminalBFullDownButtonID  AT (84 148 14 12) NOFRAME GRAPHICAL BITMAPID TerminalBFullDownBitmapID SELECTEDBITMAPID TerminalBFullDownSelectedBitmapID NONUSABLE\r
+    REPEATBUTTON "<" ID TerminalBFullLeftButtonID  AT (71 136 14 24) NOFRAME GRAPHICAL BITMAPID TerminalBFullLeftBitmapID SELECTEDBITMAPID TerminalBFullLeftSelectedBitmapID NONUSABLE\r
+    REPEATBUTTON ">" ID TerminalBFullRightButtonID AT (97 136 14 24) NOFRAME GRAPHICAL BITMAPID TerminalBFullRightBitmapID SELECTEDBITMAPID TerminalBFullRightSelectedBitmapID NONUSABLE\r
+\r
+\r
+    /* ABC top pane */\r
+    BUTTON ""  ID TerminalTABCBackspaceButtonID AT (131 88 26 11) NOFRAME NONUSABLE\r
+    BUTTON ""  ID TerminalTABCTabButtonID AT (1 100 15 11) NOFRAME NONUSABLE\r
+    PUSHBUTTON "cap" ID TerminalTABCCapsButtonID AT (1 112 20 11) NONUSABLE\r
+    BUTTON ""  ID TerminalTABCReturnButtonID AT (139 112 18 11) NOFRAME NONUSABLE\r
+    PUSHBUTTON "shift" ID TerminalTABCShiftButtonID AT (1 124 29 11) NONUSABLE\r
+    BUTTON "space" ID TerminalTABCSpaceButtonID AT (31 124 100 11) NOFRAME NONUSABLE\r
+\r
+    BUTTON "q" ID TerminalTABCFirstAlphaButtonID+0 AT (  1 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "w" ID TerminalTABCFirstAlphaButtonID+1 AT ( 14 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "e" ID TerminalTABCFirstAlphaButtonID+2 AT ( 27 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "r" ID TerminalTABCFirstAlphaButtonID+3 AT ( 40 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "t" ID TerminalTABCFirstAlphaButtonID+4 AT ( 53 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "y" ID TerminalTABCFirstAlphaButtonID+5 AT ( 66 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "u" ID TerminalTABCFirstAlphaButtonID+6 AT ( 79 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "i" ID TerminalTABCFirstAlphaButtonID+7 AT ( 92 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "o" ID TerminalTABCFirstAlphaButtonID+8 AT (105 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "p" ID TerminalTABCFirstAlphaButtonID+9 AT (118 88 12 11) NOFRAME NONUSABLE\r
+\r
+    BUTTON "a" ID TerminalTABCFirstAlphaButtonID+10 AT ( 17 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "s" ID TerminalTABCFirstAlphaButtonID+11 AT ( 30 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "d" ID TerminalTABCFirstAlphaButtonID+12 AT ( 43 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "f" ID TerminalTABCFirstAlphaButtonID+13 AT ( 56 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "g" ID TerminalTABCFirstAlphaButtonID+14 AT ( 69 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "h" ID TerminalTABCFirstAlphaButtonID+15 AT ( 82 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "j" ID TerminalTABCFirstAlphaButtonID+16 AT ( 95 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "k" ID TerminalTABCFirstAlphaButtonID+17 AT (108 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "l" ID TerminalTABCFirstAlphaButtonID+18 AT (121 100 12 11) NOFRAME NONUSABLE\r
+\r
+    BUTTON "z" ID TerminalTABCFirstAlphaButtonID+19 AT ( 22 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "x" ID TerminalTABCFirstAlphaButtonID+20 AT ( 35 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "c" ID TerminalTABCFirstAlphaButtonID+21 AT ( 48 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "v" ID TerminalTABCFirstAlphaButtonID+22 AT ( 61 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "b" ID TerminalTABCFirstAlphaButtonID+23 AT ( 74 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "n" ID TerminalTABCFirstAlphaButtonID+24 AT ( 87 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "m" ID TerminalTABCFirstAlphaButtonID+25 AT (100 112 12 11) NOFRAME NONUSABLE\r
+\r
+    BUTTON ";" ID TerminalTABCFirstPunctButtonID+0 AT (134 100 11 11) NOFRAME NONUSABLE\r
+    BUTTON "'" ID TerminalTABCFirstPunctButtonID+1 AT (146 100 11 11) NOFRAME NONUSABLE\r
+    BUTTON "," ID TerminalTABCFirstPunctButtonID+2 AT (113 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "." ID TerminalTABCFirstPunctButtonID+3 AT (126 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "-" ID TerminalTABCFirstPunctButtonID+4 AT (132 124 12 11) NOFRAME NONUSABLE\r
+    BUTTON "/" ID TerminalTABCFirstPunctButtonID+5 AT (145 124 12 11) NOFRAME NONUSABLE\r
+\r
+\r
+    BUTTON "Q" ID TerminalTABCFirstALPHAButtonID+0 AT (  1 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "W" ID TerminalTABCFirstALPHAButtonID+1 AT ( 14 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "E" ID TerminalTABCFirstALPHAButtonID+2 AT ( 27 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "R" ID TerminalTABCFirstALPHAButtonID+3 AT ( 40 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "T" ID TerminalTABCFirstALPHAButtonID+4 AT ( 53 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "Y" ID TerminalTABCFirstALPHAButtonID+5 AT ( 66 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "U" ID TerminalTABCFirstALPHAButtonID+6 AT ( 79 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "I" ID TerminalTABCFirstALPHAButtonID+7 AT ( 92 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "O" ID TerminalTABCFirstALPHAButtonID+8 AT (105 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "P" ID TerminalTABCFirstALPHAButtonID+9 AT (118 88 12 11) NOFRAME NONUSABLE\r
+\r
+    BUTTON "A" ID TerminalTABCFirstALPHAButtonID+10 AT ( 17 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "S" ID TerminalTABCFirstALPHAButtonID+11 AT ( 30 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "D" ID TerminalTABCFirstALPHAButtonID+12 AT ( 43 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "F" ID TerminalTABCFirstALPHAButtonID+13 AT ( 56 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "G" ID TerminalTABCFirstALPHAButtonID+14 AT ( 69 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "H" ID TerminalTABCFirstALPHAButtonID+15 AT ( 82 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "J" ID TerminalTABCFirstALPHAButtonID+16 AT ( 95 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "K" ID TerminalTABCFirstALPHAButtonID+17 AT (108 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "L" ID TerminalTABCFirstALPHAButtonID+18 AT (121 100 12 11) NOFRAME NONUSABLE\r
+\r
+    BUTTON "Z" ID TerminalTABCFirstALPHAButtonID+19 AT ( 22 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "X" ID TerminalTABCFirstALPHAButtonID+20 AT ( 35 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "C" ID TerminalTABCFirstALPHAButtonID+21 AT ( 48 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "V" ID TerminalTABCFirstALPHAButtonID+22 AT ( 61 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "B" ID TerminalTABCFirstALPHAButtonID+23 AT ( 74 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "N" ID TerminalTABCFirstALPHAButtonID+24 AT ( 87 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "M" ID TerminalTABCFirstALPHAButtonID+25 AT (100 112 12 11) NOFRAME NONUSABLE\r
+\r
+    BUTTON ":" ID TerminalTABCFirstPUNCTButtonID+0 AT (134 100 11 11) NOFRAME NONUSABLE\r
+    BUTTON "\"" ID TerminalTABCFirstPUNCTButtonID+1 AT (146 100 11 11) NOFRAME NONUSABLE\r
+    BUTTON "!" ID TerminalTABCFirstPUNCTButtonID+2 AT (113 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "*" ID TerminalTABCFirstPUNCTButtonID+3 AT (126 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "_" ID TerminalTABCFirstPUNCTButtonID+4 AT (132 124 12 11) NOFRAME NONUSABLE\r
+    BUTTON "?" ID TerminalTABCFirstPUNCTButtonID+5 AT (145 124 12 11) NOFRAME NONUSABLE\r
+\r
+\r
+    /* 123 top pane */\r
+    BUTTON "~" ID TerminalT123FirstButtonID+0  AT (  1  88 10 11) NOFRAME NONUSABLE\r
+    BUTTON "`" ID TerminalT123FirstButtonID+1  AT ( 12  88 10 11) NOFRAME NONUSABLE\r
+    BUTTON "'" ID TerminalT123FirstButtonID+2  AT ( 23  88 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\"" ID TerminalT123FirstButtonID+3  AT ( 34  88 10 11) NOFRAME NONUSABLE\r
+    BUTTON "_" ID TerminalT123FirstButtonID+4  AT ( 45  88 10 11) NOFRAME NONUSABLE\r
+    BUTTON "=" ID TerminalT123FirstButtonID+5  AT ( 56  88 10 11) NOFRAME NONUSABLE\r
+\r
+    BUTTON "!" ID TerminalT123FirstButtonID+6  AT (  1 100 10 11) NOFRAME NONUSABLE\r
+    BUTTON "@" ID TerminalT123FirstButtonID+7  AT ( 12 100 10 11) NOFRAME NONUSABLE\r
+    BUTTON "#" ID TerminalT123FirstButtonID+8  AT ( 23 100 10 11) NOFRAME NONUSABLE\r
+    BUTTON "$" ID TerminalT123FirstButtonID+9  AT ( 34 100 10 11) NOFRAME NONUSABLE\r
+    BUTTON "^" ID TerminalT123FirstButtonID+10 AT ( 45 100 10 11) NOFRAME NONUSABLE\r
+    BUTTON "&" ID TerminalT123FirstButtonID+11 AT ( 56 100 10 11) NOFRAME NONUSABLE\r
+\r
+    BUTTON "[" ID TerminalT123FirstButtonID+12 AT (  1 112 10 11) NOFRAME NONUSABLE\r
+    BUTTON "]" ID TerminalT123FirstButtonID+13 AT ( 12 112 10 11) NOFRAME NONUSABLE\r
+    BUTTON "{" ID TerminalT123FirstButtonID+14 AT ( 23 112 10 11) NOFRAME NONUSABLE\r
+    BUTTON "}" ID TerminalT123FirstButtonID+15 AT ( 34 112 10 11) NOFRAME NONUSABLE\r
+    BUTTON "<" ID TerminalT123FirstButtonID+16 AT ( 45 112 10 11) NOFRAME NONUSABLE\r
+    BUTTON ">" ID TerminalT123FirstButtonID+17 AT ( 56 112 10 11) NOFRAME NONUSABLE\r
+\r
+    BUTTON "/" ID TerminalT123FirstButtonID+18 AT (  1 124 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\\" ID TerminalT123FirstButtonID+19 AT ( 12 124 10 11) NOFRAME NONUSABLE\r
+    BUTTON "|" ID TerminalT123FirstButtonID+20 AT ( 23 124 10 11) NOFRAME NONUSABLE\r
+    BUTTON ":" ID TerminalT123FirstButtonID+21 AT ( 34 124 10 11) NOFRAME NONUSABLE\r
+    BUTTON ";" ID TerminalT123FirstButtonID+22 AT ( 45 124 10 11) NOFRAME NONUSABLE\r
+    BUTTON "?" ID TerminalT123FirstButtonID+23 AT ( 56 124 10 11) NOFRAME NONUSABLE\r
+\r
+\r
+    BUTTON "1" ID TerminalT123FirstButtonID+24 AT ( 72  88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "2" ID TerminalT123FirstButtonID+25 AT ( 85  88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "3" ID TerminalT123FirstButtonID+26 AT ( 98  88 12 11) NOFRAME NONUSABLE\r
+\r
+    BUTTON "4" ID TerminalT123FirstButtonID+27 AT ( 72 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "5" ID TerminalT123FirstButtonID+28 AT ( 85 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "6" ID TerminalT123FirstButtonID+29 AT ( 98 100 12 11) NOFRAME NONUSABLE\r
+\r
+    BUTTON "7" ID TerminalT123FirstButtonID+30 AT ( 72 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "8" ID TerminalT123FirstButtonID+31 AT ( 85 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "9" ID TerminalT123FirstButtonID+32 AT ( 98 112 12 11) NOFRAME NONUSABLE\r
+\r
+    BUTTON "(" ID TerminalT123FirstButtonID+33 AT ( 72 124 12 11) NOFRAME NONUSABLE\r
+    BUTTON "0" ID TerminalT123FirstButtonID+34 AT ( 85 124 12 11) NOFRAME NONUSABLE\r
+    BUTTON ")" ID TerminalT123FirstButtonID+35 AT ( 98 124 12 11) NOFRAME NONUSABLE\r
+\r
+\r
+    BUTTON "-" ID TerminalT123FirstButtonID+36 AT (116  88 10 11) NOFRAME NONUSABLE\r
+    BUTTON "+" ID TerminalT123FirstButtonID+37 AT (127  88 10 11) NOFRAME NONUSABLE\r
+    BUTTON ""  ID TerminalT123BackspaceButtonID AT (138 88 21 11) NOFRAME NONUSABLE\r
+\r
+    BUTTON "/" ID TerminalT123FirstButtonID+38 AT (116 100 10 11) NOFRAME NONUSABLE\r
+    BUTTON "*" ID TerminalT123FirstButtonID+39 AT (127 100 10 11) NOFRAME NONUSABLE\r
+    BUTTON ":" ID TerminalT123FirstButtonID+40 AT (138 100 10 11) NOFRAME NONUSABLE\r
+    BUTTON ""  ID TerminalT123TabButtonID AT (149 100 10 11) NOFRAME NONUSABLE\r
+\r
+    BUTTON "." ID TerminalT123FirstButtonID+41 AT (116 112 10 11) NOFRAME NONUSABLE\r
+    BUTTON "," ID TerminalT123FirstButtonID+42 AT (127 112 10 11) NOFRAME NONUSABLE\r
+    BUTTON ""  ID TerminalT123ReturnButtonID AT (138 112 21 11) NOFRAME NONUSABLE\r
+\r
+    BUTTON "space" ID TerminalT123SpaceButtonID AT (116 124 32 11) NOFRAME NONUSABLE\r
+    BUTTON "%" ID TerminalT123FirstButtonID+43 AT (149 124 10 11) NOFRAME NONUSABLE\r
+\r
+\r
+    /* Intl top pane */\r
+\r
+    /* a' .. o/ */\r
+    BUTTON "\xe1" ID TerminalTIntlFirstLowercaseButtonID+0 AT (  1 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xe0" ID TerminalTIntlFirstLowercaseButtonID+1 AT ( 14 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xe4" ID TerminalTIntlFirstLowercaseButtonID+2 AT ( 27 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xe2" ID TerminalTIntlFirstLowercaseButtonID+3 AT ( 40 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xe5" ID TerminalTIntlFirstLowercaseButtonID+4 AT ( 53 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xe3" ID TerminalTIntlFirstLowercaseButtonID+5 AT ( 66 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xe6" ID TerminalTIntlFirstLowercaseButtonID+6 AT ( 79 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xe7" ID TerminalTIntlFirstLowercaseButtonID+7 AT ( 92 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xf1" ID TerminalTIntlFirstLowercaseButtonID+8 AT (105 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xf8" ID TerminalTIntlFirstLowercaseButtonID+9 AT (118 88 12 11) NOFRAME NONUSABLE\r
+\r
+    /* e' .. ye */\r
+    BUTTON "\xe9" ID TerminalTIntlFirstLowercaseButtonID+10 AT ( 17 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xe8" ID TerminalTIntlFirstLowercaseButtonID+11 AT ( 30 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xeb" ID TerminalTIntlFirstLowercaseButtonID+12 AT ( 43 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xea" ID TerminalTIntlFirstLowercaseButtonID+13 AT ( 56 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xed" ID TerminalTIntlFirstLowercaseButtonID+14 AT ( 69 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xec" ID TerminalTIntlFirstLowercaseButtonID+15 AT ( 82 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xef" ID TerminalTIntlFirstLowercaseButtonID+16 AT ( 95 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xee" ID TerminalTIntlFirstLowercaseButtonID+17 AT (108 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xdf" ID TerminalTIntlFirstLowercaseButtonID+18 AT (121 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xfd" ID TerminalTIntlFirstLowercaseButtonID+19 AT (134 100 11 11) NOFRAME NONUSABLE\r
+    BUTTON "\xff" ID TerminalTIntlFirstLowercaseButtonID+20 AT (146 100 11 11) NOFRAME NONUSABLE\r
+\r
+    /* o' .. u^ */\r
+    BUTTON "\xf3" ID TerminalTIntlFirstLowercaseButtonID+21 AT ( 22 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xf2" ID TerminalTIntlFirstLowercaseButtonID+22 AT ( 35 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xf6" ID TerminalTIntlFirstLowercaseButtonID+23 AT ( 48 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xf4" ID TerminalTIntlFirstLowercaseButtonID+24 AT ( 61 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xf5" ID TerminalTIntlFirstLowercaseButtonID+25 AT ( 74 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xfa" ID TerminalTIntlFirstLowercaseButtonID+26 AT ( 87 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xf9" ID TerminalTIntlFirstLowercaseButtonID+27 AT (100 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xfc" ID TerminalTIntlFirstLowercaseButtonID+28 AT (113 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xfb" ID TerminalTIntlFirstLowercaseButtonID+29 AT (126 112 12 11) NOFRAME NONUSABLE\r
+\r
+    /* ? and << */\r
+    BUTTON "\xbf" ID TerminalTIntlFirstLowercaseButtonID+30 AT (132 124 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xab" ID TerminalTIntlFirstLowercaseButtonID+31 AT (145 124 12 11) NOFRAME NONUSABLE\r
+\r
+    /* A' .. O/ */\r
+    BUTTON "\xc1" ID TerminalTIntlFirstUppercaseButtonID+0 AT (  1 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xc0" ID TerminalTIntlFirstUppercaseButtonID+1 AT ( 14 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xc4" ID TerminalTIntlFirstUppercaseButtonID+2 AT ( 27 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xc2" ID TerminalTIntlFirstUppercaseButtonID+3 AT ( 40 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xc5" ID TerminalTIntlFirstUppercaseButtonID+4 AT ( 53 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xc3" ID TerminalTIntlFirstUppercaseButtonID+5 AT ( 66 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xc6" ID TerminalTIntlFirstUppercaseButtonID+6 AT ( 79 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xc7" ID TerminalTIntlFirstUppercaseButtonID+7 AT ( 92 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xd1" ID TerminalTIntlFirstUppercaseButtonID+8 AT (105 88 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xd8" ID TerminalTIntlFirstUppercaseButtonID+9 AT (118 88 12 11) NOFRAME NONUSABLE\r
+\r
+    /* E' .. ye */\r
+    BUTTON "\xc9" ID TerminalTIntlFirstUppercaseButtonID+10 AT ( 17 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xc8" ID TerminalTIntlFirstUppercaseButtonID+11 AT ( 30 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xcb" ID TerminalTIntlFirstUppercaseButtonID+12 AT ( 43 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xca" ID TerminalTIntlFirstUppercaseButtonID+13 AT ( 56 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xcd" ID TerminalTIntlFirstUppercaseButtonID+14 AT ( 69 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xcc" ID TerminalTIntlFirstUppercaseButtonID+15 AT ( 82 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xcf" ID TerminalTIntlFirstUppercaseButtonID+16 AT ( 95 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xce" ID TerminalTIntlFirstUppercaseButtonID+17 AT (108 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xdf" ID TerminalTIntlFirstUppercaseButtonID+18 AT (121 100 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xdd" ID TerminalTIntlFirstUppercaseButtonID+19 AT (134 100 11 11) NOFRAME NONUSABLE\r
+    BUTTON "\xff" ID TerminalTIntlFirstUppercaseButtonID+20 AT (146 100 11 11) NOFRAME NONUSABLE\r
+\r
+    /* O' .. U^ */\r
+    BUTTON "\xd3" ID TerminalTIntlFirstUppercaseButtonID+21 AT ( 22 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xd2" ID TerminalTIntlFirstUppercaseButtonID+22 AT ( 35 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xd6" ID TerminalTIntlFirstUppercaseButtonID+23 AT ( 48 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xd4" ID TerminalTIntlFirstUppercaseButtonID+24 AT ( 61 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xd5" ID TerminalTIntlFirstUppercaseButtonID+25 AT ( 74 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xda" ID TerminalTIntlFirstUppercaseButtonID+26 AT ( 87 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xd9" ID TerminalTIntlFirstUppercaseButtonID+27 AT (100 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xdc" ID TerminalTIntlFirstUppercaseButtonID+28 AT (113 112 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xdb" ID TerminalTIntlFirstUppercaseButtonID+29 AT (126 112 12 11) NOFRAME NONUSABLE\r
+\r
+    /* ! and >> */\r
+    BUTTON "\xa1" ID TerminalTIntlFirstUppercaseButtonID+30 AT (132 124 12 11) NOFRAME NONUSABLE\r
+    BUTTON "\xbb" ID TerminalTIntlFirstUppercaseButtonID+31 AT (145 124 12 11) NOFRAME NONUSABLE\r
+\r
+\r
+    /* Etc top pane */\r
+\r
+    /* Scroll pad */\r
+    BUTTON "Ins"  ID TerminalTEtcInsButtonID  AT ( 80 88 25 10) NOFRAME NONUSABLE\r
+    BUTTON "Del"  ID TerminalTEtcDelButtonID  AT ( 80 99 25 10) NOFRAME NONUSABLE\r
+    BUTTON "Home" ID TerminalTEtcHomeButtonID AT (106 88 27 10) NOFRAME NONUSABLE\r
+    BUTTON "End"  ID TerminalTEtcEndButtonID  AT (106 99 27 10) NOFRAME NONUSABLE\r
+    BUTTON "PgUp" ID TerminalTEtcPgUpButtonID AT (134 88 25 10) NOFRAME NONUSABLE\r
+    BUTTON "PgDn" ID TerminalTEtcPgDnButtonID AT (134 99 25 10) NOFRAME NONUSABLE\r
+\r
+    /* FKeys */\r
+    BUTTON "F1"  ID TerminalTEtcFirstLowercaseFKeyButtonID+0 AT ( 80 112 15 11) NOFRAME NONUSABLE\r
+    BUTTON "F2"  ID TerminalTEtcFirstLowercaseFKeyButtonID+1 AT ( 96 112 15 11) NOFRAME NONUSABLE\r
+    BUTTON "F3"  ID TerminalTEtcFirstLowercaseFKeyButtonID+2 AT (112 112 15 11) NOFRAME NONUSABLE\r
+    BUTTON "F4"  ID TerminalTEtcFirstLowercaseFKeyButtonID+3 AT (128 112 15 11) NOFRAME NONUSABLE\r
+    BUTTON "F5"  ID TerminalTEtcFirstLowercaseFKeyButtonID+4 AT (144 112 15 11) NOFRAME NONUSABLE\r
+    BUTTON "F6"  ID TerminalTEtcFirstLowercaseFKeyButtonID+5 AT ( 80 124 15 11) NOFRAME NONUSABLE\r
+    BUTTON "F7"  ID TerminalTEtcFirstLowercaseFKeyButtonID+6 AT ( 96 124 15 11) NOFRAME NONUSABLE\r
+    BUTTON "F8"  ID TerminalTEtcFirstLowercaseFKeyButtonID+7 AT (112 124 15 11) NOFRAME NONUSABLE\r
+    BUTTON "F9"  ID TerminalTEtcFirstLowercaseFKeyButtonID+8 AT (128 124 15 11) NOFRAME NONUSABLE\r
+    BUTTON "F10" ID TerminalTEtcFirstLowercaseFKeyButtonID+9 AT (144 124 15 11) NOFRAME NONUSABLE\r
+\r
+    BUTTON "F11" ID TerminalTEtcFirstUppercaseFKeyButtonID+0 AT ( 80 112 15 11) NOFRAME NONUSABLE\r
+    BUTTON "F12" ID TerminalTEtcFirstUppercaseFKeyButtonID+1 AT ( 96 112 15 11) NOFRAME NONUSABLE\r
+    BUTTON "F13" ID TerminalTEtcFirstUppercaseFKeyButtonID+2 AT (112 112 15 11) NOFRAME NONUSABLE\r
+    BUTTON "F14" ID TerminalTEtcFirstUppercaseFKeyButtonID+3 AT (128 112 15 11) NOFRAME NONUSABLE\r
+    BUTTON "F15" ID TerminalTEtcFirstUppercaseFKeyButtonID+4 AT (144 112 15 11) NOFRAME NONUSABLE\r
+    BUTTON "F16" ID TerminalTEtcFirstUppercaseFKeyButtonID+5 AT ( 80 124 15 11) NOFRAME NONUSABLE\r
+    BUTTON "F17" ID TerminalTEtcFirstUppercaseFKeyButtonID+6 AT ( 96 124 15 11) NOFRAME NONUSABLE\r
+    BUTTON "F18" ID TerminalTEtcFirstUppercaseFKeyButtonID+7 AT (112 124 15 11) NOFRAME NONUSABLE\r
+    BUTTON "F19" ID TerminalTEtcFirstUppercaseFKeyButtonID+8 AT (128 124 15 11) NOFRAME NONUSABLE\r
+    BUTTON "F20" ID TerminalTEtcFirstUppercaseFKeyButtonID+9 AT (144 124 15 11) NOFRAME NONUSABLE\r
+\r
+    /* assorted Latin-1 */\r
+    BUTTON "\xa3" ID TerminalTEtcFirstLowercaseLatin1ButtonID+0  AT ( 1  88 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xa5" ID TerminalTEtcFirstLowercaseLatin1ButtonID+1  AT (12  88 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xa6" ID TerminalTEtcFirstLowercaseLatin1ButtonID+2  AT (23  88 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xb6" ID TerminalTEtcFirstLowercaseLatin1ButtonID+3  AT (34  88 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xa9" ID TerminalTEtcFirstLowercaseLatin1ButtonID+4  AT (45  88 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xaa" ID TerminalTEtcFirstLowercaseLatin1ButtonID+5  AT (56  88 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xb1" ID TerminalTEtcFirstLowercaseLatin1ButtonID+6  AT (67  88 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xb9" ID TerminalTEtcFirstLowercaseLatin1ButtonID+7  AT ( 1 100 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xb2" ID TerminalTEtcFirstLowercaseLatin1ButtonID+8  AT (12 100 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xb3" ID TerminalTEtcFirstLowercaseLatin1ButtonID+9  AT (23 100 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xd7" ID TerminalTEtcFirstLowercaseLatin1ButtonID+10 AT (34 100 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xf0" ID TerminalTEtcFirstLowercaseLatin1ButtonID+11 AT (45 100 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xfe" ID TerminalTEtcFirstLowercaseLatin1ButtonID+12 AT (56 100 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xb5" ID TerminalTEtcFirstLowercaseLatin1ButtonID+13 AT (67 100 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xb0" ID TerminalTEtcFirstLowercaseLatin1ButtonID+14 AT ( 1 112 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xb4" ID TerminalTEtcFirstLowercaseLatin1ButtonID+15 AT (12 112 10 11) NOFRAME NONUSABLE\r
+\r
+    BUTTON "\xa2" ID TerminalTEtcFirstUppercaseLatin1ButtonID+0  AT ( 1  88 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xa4" ID TerminalTEtcFirstUppercaseLatin1ButtonID+1  AT (12  88 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xaf" ID TerminalTEtcFirstUppercaseLatin1ButtonID+2  AT (23  88 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xa7" ID TerminalTEtcFirstUppercaseLatin1ButtonID+3  AT (34  88 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xae" ID TerminalTEtcFirstUppercaseLatin1ButtonID+4  AT (45  88 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xba" ID TerminalTEtcFirstUppercaseLatin1ButtonID+5  AT (56  88 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xac" ID TerminalTEtcFirstUppercaseLatin1ButtonID+6  AT (67  88 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xbc" ID TerminalTEtcFirstUppercaseLatin1ButtonID+7  AT ( 1 100 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xbd" ID TerminalTEtcFirstUppercaseLatin1ButtonID+8  AT (12 100 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xbe" ID TerminalTEtcFirstUppercaseLatin1ButtonID+9  AT (23 100 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xf7" ID TerminalTEtcFirstUppercaseLatin1ButtonID+10 AT (34 100 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xd0" ID TerminalTEtcFirstUppercaseLatin1ButtonID+11 AT (45 100 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xde" ID TerminalTEtcFirstUppercaseLatin1ButtonID+12 AT (56 100 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xb7" ID TerminalTEtcFirstUppercaseLatin1ButtonID+13 AT (67 100 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xb8" ID TerminalTEtcFirstUppercaseLatin1ButtonID+14 AT ( 1 112 10 11) NOFRAME NONUSABLE\r
+    BUTTON "\xa8" ID TerminalTEtcFirstUppercaseLatin1ButtonID+15 AT (12 112 10 11) NOFRAME NONUSABLE\r
+END\r
+\r
+\r
+FORM ID HostKeysFormID AT (0 0 160 160)\r
+USABLE\r
+MODAL\r
+DEFAULTBTNID HostKeysFormOKButtonID\r
+BEGIN\r
+    TITLE "pssh - Known Host Keys"\r
+    \r
+    BUTTON "Done" ID HostKeysFormOKButtonID AT (1 147 42 12)\r
+    BUTTON "Details..." ID HostKeysFormDetailsButtonID AT (51 147 42 12)\r
+\r
+    TABLE ID HostKeysFormKeyTableID AT (0 13 152 132) ROWS 12 COLUMNS 1 COLUMNWIDTHS 152\r
+    // fixme more rows for vertical screen growth?\r
+    SCROLLBAR ID HostKeysFormKeyScrollbarID AT (153 13 7 132)\r
+END\r
+\r
+\r
+FORM ID HostKeyWarningFormID AT (2 46 156 112)\r
+SAVEBEHIND\r
+MODAL\r
+DEFAULTBTNID HostKeyWarningFormRejectButtonID\r
+BEGIN\r
+    TITLE "Security Warning"\r
+\r
+    BUTTON "Reject" ID HostKeyWarningFormRejectButtonID AT (121 97 32 12)\r
+    BUTTON "Trust Once" ID HostKeyWarningFormTrustOnceButtonID AT (3 97 51 12)\r
+    BUTTON "Trust & Save" ID HostKeyWarningFormTrustForeverButtonID AT (58 97 59 12)\r
+\r
+    FIELD HostKeyWarningFormContentFieldID AT (3 13 150 45) NONEDITABLE MULTIPLELINE MAXCHARS 240\r
+    FIELD HostKeyWarningFormAddressFieldID AT (80 59 73 12) NONEDITABLE MAXCHARS 15\r
+\r
+    LABEL "Server address:" AUTOID AT (13 59)\r
+    LABEL "Do you wish to trust the credentials" AUTOID AT (3 71)\r
+    LABEL "offered by the server?" AUTOID AT (3 82)\r
+END\r
+\r
+\r
+FORM ID HostKeyDetailsFormID AT (0 0 160 160)\r
+MODAL\r
+DEFAULTBTNID HostKeyDetailsFormOKButtonID\r
+BEGIN\r
+    TITLE "pssh - Host Key Details"\r
+    \r
+    BUTTON "Done" ID HostKeyDetailsFormOKButtonID AT (34 147 42 12)\r
+    BUTTON "Delete..." ID HostKeyDetailsFormDeleteButtonID AT (84 147 42 12)\r
+\r
+    FIELD ID HostKeyDetailsFormHostFieldID AT (46 13 114 11) NONEDITABLE SINGLELINE MAXCHARS 80\r
+    FIELD ID HostKeyDetailsFormKeyTypeFieldID AT (46 24 114 11) NONEDITABLE SINGLELINE MAXCHARS 80\r
+    FIELD ID HostKeyDetailsFormKeyFieldID AT (0 35 153 110) NONEDITABLE MULTIPLELINE MAXCHARS 512 HASSCROLLBAR\r
+\r
+    SCROLLBAR ID HostKeyDetailsFormKeyScrollbarID AT (153 35 7 110)\r
+\r
+    LABEL "Hostname:" AUTOID AT (0 13)\r
+    LABEL "Key type:" AUTOID AT (0 24)\r
+END\r
+\r
+\r
+FORM ID AboutFormID AT (2 2 156 156)\r
+MODAL\r
+BEGIN\r
+    TITLE "About pssh"\r
+    \r
+    LABEL "pssh:" AUTOID AT (26 16) FONT 1\r
+    LABEL "SSH 2 for Palm OS" AUTOID AT (54 16) \r
+    LABEL "Version " AUTOID AT (37 28)\r
+    LABEL PSSH_VERSION AUTOID AT (70 28)\r
+    LABEL "http://sealiesoftware.com/pssh/" AUTOID AT (11 40)\r
+    LABEL "Copyright \xA9 2003-2005 Greg Parker\rand a cast of dozens.\rSee \"Credits\" for details." AUTOID AT (4 58)\r
+    LABEL "pssh is free software distributed\runder several licenses.\rSee README.licenses for details." AUTOID AT (4 96)\r
+    BUTTON "OK" AboutFormOKButtonID AT (60 140 36 12)\r
+END\r
+\r
+\r
+FORM ID CreditsFormID AT (2 2 156 156)\r
+MODAL\r
+BEGIN\r
+    TITLE "pssh Credits"\r
+\r
+    BUTTON "Thank you" CreditsFormOKButtonID AT (55 141 50 12)\r
+\r
+    FIELD ID CreditsFormFieldID AT (3 14 146 122) NONEDITABLE MULTIPLELINE MAXCHARS 800 HASSCROLLBAR\r
+    SCROLLBAR ID CreditsFormScrollbarID AT (149 14 7 122)\r
+END\r
+\r
+\r
+FORM ID DisplayPrefsFormID AT (2 2 156 156)\r
+MODAL\r
+BEGIN\r
+    TITLE "Display Settings"\r
+\r
+    BUTTON "OK" DisplayPrefsFormOKButtonID AT (31 140 36 12)\r
+    BUTTON "Cancel" DisplayPrefsFormCancelButtonID AT (88 140 36 12)\r
+\r
+    LABEL "Font:" AUTOID AT (3 13) FONT 1\r
+    CHECKBOX "Small (4x6)"  DisplayPrefsFormSmallFontCheckboxID AT (6 24 74 12) GROUP 1\r
+    CHECKBOX "Large (6x10)" DisplayPrefsFormLargeFontCheckboxID AT (82 24 74 12) GROUP 1\r
+\r
+    LABEL "Colors:" AUTOID AT (3 38) FONT 1\r
+    POPUPTRIGGER "Hooked" ID DisplayPrefsFormForeColorTriggerID AT (5 49 57 12)\r
+    LABEL "on" AUTOID AT (66 49) FONT 1\r
+    POPUPTRIGGER "Phonics" ID DisplayPrefsFormBackColorTriggerID AT (82 49 57 12)\r
+    LIST "black" "red" "green" "yellow" "blue" "magenta" "cyan" "white" ID DisplayPrefsFormForeColorListID AT (18 49 40 1) NONUSABLE VISIBLEITEMS 8\r
+    LIST "black" "red" "green" "yellow" "blue" "magenta" "cyan" "white" ID DisplayPrefsFormBackColorListID AT (95 49 40 1) NONUSABLE VISIBLEITEMS 8\r
+    POPUPLIST ID DisplayPrefsFormForeColorTriggerID DisplayPrefsFormForeColorListID\r
+    POPUPLIST ID DisplayPrefsFormBackColorTriggerID DisplayPrefsFormBackColorListID\r
+\r
+    GADGET ID DisplayPrefsFormSampleTextGadgetID AT (34 14 120 10)\r
+\r
+    LABEL "Scrollback:" AUTOID AT (3 63) FONT 1\r
+    FIELD ID DisplayPrefsFormScrollbackFieldID AT (75 63 22 12) UNDERLINED MAXCHARS 4 NUMERIC\r
+    LABEL "lines" AUTOID AT (101 63)\r
+    LABEL "(pssh may crash if this is too large)" AUTOID AT (7 74)\r
+\r
+    LABEL "Scroll to bottom on:" AUTOID AT (3 87) FONT 1\r
+    CHECKBOX "Activity" ID DisplayPrefsFormActivityCheckboxID AT (6 98 74 12)\r
+    CHECKBOX "Typing" ID DisplayPrefsFormTypingCheckboxID AT (82 98 74 12)\r
+\r
+    LABEL "Bell:" AUTOID AT (3 112) FONT 1\r
+    CHECKBOX "Beep" ID DisplayPrefsFormBeepCheckboxID AT (6 123 74 12)\r
+    CHECKBOX "Flash screen" ID DisplayPrefsFormFlashCheckboxID AT (82 123 74 12)\r
+\r
+    GRAFFITISTATEINDICATOR AT (142 142)\r
+END\r
+\r
+\r
+FORM ID ConnectionPrefsFormID AT (2 2 156 156)\r
+MODAL\r
+BEGIN\r
+    TITLE "Connection Settings"\r
+\r
+    BUTTON "OK" ConnectionPrefsFormOKButtonID AT (31 140 36 12)\r
+    BUTTON "Cancel" ConnectionPrefsFormCancelButtonID AT (88 140 36 12)\r
+\r
+    LABEL "Ciphers:" AUTOID AT (3 14) FONT 1\r
+    CHECKBOX "AES128-cbc" ID ConnectionPrefsFormAESCheckboxID AT (6 25 74 12)\r
+    CHECKBOX "3DES-cbc" ID ConnectionPrefsForm3DESCheckboxID AT (82 25 74 12)\r
+\r
+    LABEL "Authentication methods:" AUTOID AT (3 43) FONT 1\r
+    CHECKBOX "public-key" ID ConnectionPrefsFormPublicKeyCheckboxID AT (6 54 74 12)\r
+    CHECKBOX "password" ID ConnectionPrefsFormPasswordCheckboxID AT (82 54 74 12)\r
+    CHECKBOX "keyboard-interactive" ID ConnectionPrefsFormKbdIntCheckboxID AT (6 66 150 12)\r
+\r
+    LABEL "Compression:" AUTOID AT (3 84) FONT 1\r
+    CHECKBOX "zlib" ID ConnectionPrefsFormZLibCheckboxID AT (6 95 74 12)\r
+\r
+    LABEL "Terminal type string:" AUTOID AT (3 112) FONT 1\r
+    FIELD ID ConnectionPrefsFormTerminalFieldID AT (22 123 74 12) UNDERLINED MAXCHARS 20\r
+    POPUPTRIGGER "" ID ConnectionPrefsFormTerminalTriggerID AT (5 123 14 12)\r
+    LIST "putty" "vt100" "vt220" "xterm" "xterm-color" ID ConnectionPrefsFormTerminalListID AT (20 123 57 1) NONUSABLE SEARCH VISIBLEITEMS 5\r
+    POPUPLIST ID ConnectionPrefsFormTerminalTriggerID ConnectionPrefsFormTerminalListID\r
+\r
+    GRAFFITISTATEINDICATOR AT (142 142)\r
+END\r
+\r
+\r
+FORM ID KeyboardPrefsFormID AT (2 73 156 85)\r
+MODAL\r
+BEGIN\r
+    TITLE "Keyboard Settings"\r
+\r
+    BUTTON "OK" KeyboardPrefsFormOKButtonID AT (31 68 36 12)\r
+    BUTTON "Cancel" KeyboardPrefsFormCancelButtonID AT (88 68 36 12)\r
+\r
+    LABEL "Backspace sends:" AUTOID AT (3 13) FONT 1\r
+    CHECKBOX "^? (DEL)"  KeyboardPrefsFormBackspaceDELCheckboxID AT (6 24 74 12) GROUP 1\r
+    CHECKBOX "^H (BS)" KeyboardPrefsFormBackspaceBSCheckboxID AT (82 24 74 12) GROUP 1\r
+\r
+    LABEL "` sends:" AUTOID AT (3 40) FONT 1\r
+    CHECKBOX "`"  KeyboardPrefsFormBackquoteNormalCheckboxID AT (6 51 74 12) GROUP 2\r
+    CHECKBOX "ESC" KeyboardPrefsFormBackquoteESCCheckboxID AT (82 51 74 12) GROUP 2\r
+END\r
+\r
+\r
+FORM ID MemoFormID AT (0 0 160 160)\r
+MODAL\r
+BEGIN\r
+    TITLE "pssh - Import Public Key"\r
+\r
+    LABEL "Choose the Memo Pad memo\rcontaining the key to import:" AUTOID AT (21 12)\r
+    BUTTON "Import" ID MemoFormImportButtonID AT (34 147 42 12)\r
+    BUTTON "Cancel" ID MemoFormCancelButtonID AT (84 147 42 12)\r
+\r
+    TABLE ID MemoFormTableID AT (0 35 152 110) ROWS 10 COLUMNS 1 COLUMNWIDTHS 152\r
+    // fixme more rows for vertical screen growth?\r
+    SCROLLBAR ID MemoFormScrollbarID AT (153 35 7 110)\r
+END\r
+\r
+\r
+FORM ID PublicKeysFormID AT (0 0 160 160)\r
+USABLE\r
+MODAL\r
+DEFAULTBTNID PublicKeysFormOKButtonID\r
+BEGIN\r
+    TITLE "pssh - Public Keys"\r
+    \r
+    BUTTON "Done" ID PublicKeysFormOKButtonID AT (7 147 42 12)\r
+    BUTTON "Details..." ID PublicKeysFormDetailsButtonID AT (111 147 42 12)\r
+    BUTTON "Import..." ID PublicKeysFormImportButtonID AT (59 147 42 12)\r
+\r
+    TABLE ID PublicKeysFormKeyTableID AT (0 13 152 132) ROWS 12 COLUMNS 1 COLUMNWIDTHS 152\r
+    // fixme more rows for vertical screen growth?\r
+    SCROLLBAR ID PublicKeysFormKeyScrollbarID AT (153 13 7 132)\r
+END\r
+\r
+\r
+FORM ID PublicKeyDetailsFormID AT (0 0 160 160)\r
+MODAL\r
+DEFAULTBTNID PublicKeyDetailsFormOKButtonID\r
+BEGIN\r
+    TITLE "pssh - Public Key Details"\r
+    \r
+    BUTTON "OK" ID PublicKeyDetailsFormOKButtonID AT (3 147 42 12)\r
+    BUTTON "Cancel" ID PublicKeyDetailsFormCancelButtonID AT (53 147 42 12)\r
+    BUTTON "Delete..." ID PublicKeyDetailsFormDeleteButtonID AT (103 147 42 12)\r
+\r
+    FIELD ID PublicKeyDetailsFormCommentFieldID AT (46 13 114 11) UNDERLINED SINGLELINE MAXCHARS 80\r
+    FIELD ID PublicKeyDetailsFormKeyTypeFieldID AT (46 24 114 11) NONEDITABLE SINGLELINE MAXCHARS 80\r
+    FIELD ID PublicKeyDetailsFormKeyFieldID AT (0 35 153 110) NONEDITABLE MULTIPLELINE MAXCHARS 512 HASSCROLLBAR\r
+\r
+    SCROLLBAR ID PublicKeyDetailsFormKeyScrollbarID AT (153 35 7 110)\r
+\r
+    LABEL "Key name:" AUTOID AT (0 13)\r
+    LABEL "Key type:" AUTOID AT (0 24)\r
+\r
+    GRAFFITISTATEINDICATOR AT (150 148)\r
+END\r
+\r
+\r
+\r
+FORM ID PassphraseFormID AT (2 45 156 113)\r
+USABLE\r
+MODAL\r
+DEFAULTBTNID PassphraseFormOKButtonID\r
+BEGIN\r
+    TITLE "Enter Passphrase"\r
+    \r
+    BUTTON "OK" ID PassphraseFormOKButtonID AT (7 94 44 12)\r
+    BUTTON "Cancel" ID PassphraseFormCancelButtonID AT (58 94 36 12) \r
+\r
+    FIELD ID PassphraseFormMessageFieldID     AT (6 19 144 36) NONEDITABLE MAXCHARS 256 MULTIPLELINE\r
+    FIELD ID PassphraseFormPassphraseFieldID AT (6 60 144 12) UNDERLINED MAXCHARS 80 FONT PasswordFontID\r
+\r
+    CHECKBOX "Show passphrase while typing" ID PassphraseFormEchoCheckboxID AT (5 76 137 12) \r
+\r
+    GRAFFITISTATEINDICATOR AT (142 98)\r
+END\r
+\r
+\r
+FORM ID PublicKeyChoiceFormID AT (2 45 156 113)\r
+MODAL\r
+BEGIN\r
+    TITLE "Enter Passphrase"\r
+\r
+    BUTTON "OK" ID PublicKeyChoiceFormOKButtonID AT (7 94 44 12)\r
+    BUTTON "Cancel" ID PublicKeyChoiceFormCancelButtonID AT (58 94 36 12)\r
+\r
+    LABEL "Host:" AUTOID AT (33 18)\r
+    LABEL "Username:" AUTOID AT (10 32)\r
+    LABEL "Public key:" AUTOID AT (11 46)\r
+    LABEL "Passphrase:" AUTOID AT (6 60)\r
+\r
+    FIELD ID PublicKeyChoiceFormHostFieldID     AT (56 18 96 12) NONEDITABLE MAXCHARS 80\r
+    FIELD ID PublicKeyChoiceFormUsernameFieldID AT (56 32 96 12) UNDERLINED MAXCHARS 80 \r
+    FIELD ID PublicKeyChoiceFormPassphraseFieldID AT (56 60 96 12) UNDERLINED MAXCHARS 80 FONT PasswordFontID\r
+\r
+    POPUPTRIGGER "Your Ad Here" ID PublicKeyChoiceFormKeyTriggerID AT (56 46 96 12) \r
+    LIST ID PublicKeyChoiceFormKeyListID AT (57 47 94 1) NONUSABLE SEARCH\r
+    POPUPLIST ID PublicKeyChoiceFormKeyTriggerID PublicKeyChoiceFormKeyListID\r
+\r
+    CHECKBOX "Show passphrase while typing" ID PublicKeyChoiceFormEchoCheckboxID AT (13 76 137 12) \r
+    \r
+    GRAFFITISTATEINDICATOR AT (142 98)\r
+END\r
+\r
+\r
+FORM ID KbdIntFormID AT (2 16 156 142)\r
+MODAL\r
+BEGIN\r
+    TITLE "Your Ad Here!"\r
+\r
+    LABEL "Host:" KbdIntFormHostLabelID AT (5 16)\r
+    FIELD ID KbdIntFormHostFieldID AT (28 16 96 12) NONEDITABLE \r
+\r
+    FIELD ID KbdIntFormInstructionFieldID AT (5 31 140 48) NONEDITABLE HASSCROLLBAR MULTIPLELINE\r
+    SCROLLBAR ID KbdIntFormInstructionScrollbarID AT (145 31 7 48)\r
+\r
+    FIELD ID KbdIntFormPromptFieldID AT (5 82 147 12) NONEDITABLE\r
+    FIELD ID KbdIntFormResponseFieldID AT (5 94 147 12) UNDERLINED MAXCHARS 400\r
+\r
+    CHECKBOX "Show text while typing" ID KbdIntFormEchoCheckboxID AT (13 109 115 12) \r
+    GRAFFITISTATEINDICATOR AT (143 111)\r
+\r
+    BUTTON "Next" ID KbdIntFormNextButtonID AT (6 125 34 12)\r
+    BUTTON "Cancel" ID KbdIntFormCancelButtonID AT (47 125 34 12)\r
+    BUTTON "Back" ID KbdIntFormBackButtonID AT (116 125 34 12)\r
+    \r
+    FIELD ID KbdIntFormProgressFieldID AT (86 125 26 12) NONEDITABLE\r
+END\r
+\r
+\r
+FORM ID KbdInt0FormID AT (2 16 156 142)\r
+MODAL\r
+BEGIN\r
+    TITLE "Your Ad Here!"\r
+\r
+    LABEL "Host:" KbdInt0FormHostLabelID AT (5 16)\r
+    FIELD ID KbdInt0FormHostFieldID AT (28 16 96 12) NONEDITABLE \r
+\r
+    FIELD ID KbdInt0FormInstructionFieldID AT (5 31 140 90) NONEDITABLE HASSCROLLBAR MULTIPLELINE\r
+    SCROLLBAR ID KbdInt0FormInstructionScrollbarID AT (145 31 7 90)\r
+\r
+    BUTTON "OK" ID KbdInt0FormOKButtonID AT (6 125 34 12)\r
+    BUTTON "Cancel" ID KbdInt0FormCancelButtonID AT (47 125 34 12)\r
+END\r
+\r
+\r
+FORM ID BannerFormID AT (2 22 156 136)\r
+MODAL\r
+BEGIN\r
+    TITLE "Server Message"\r
+\r
+    BUTTON "OK" BannerFormOKButtonID AT (55 121 50 12)\r
+\r
+    FIELD ID BannerFormFieldID AT (3 14 146 102) NONEDITABLE MULTIPLELINE MAXCHARS 4000 HASSCROLLBAR\r
+    SCROLLBAR ID BannerFormScrollbarID AT (149 14 7 102)\r
+END\r
+\r
+\r
+MENU MainMenuBar\r
+BEGIN\r
+    PULLDOWN "pssh"\r
+    BEGIN\r
+        MENUITEM "New Connection" ID MenuConnect \r
+    END\r
+    PULLDOWN "Options"\r
+    BEGIN\r
+        MENUITEM "Connection Settings..." MenuConnectionSettings\r
+        MENUITEM "Display Settings..." MenuDisplaySettings\r
+        MENUITEM "Keyboard Settings..." MenuKeyboardSettings\r
+        MENUITEM SEPARATOR\r
+        MENUITEM "Known Host Keys..." ID MenuHostKeys\r
+        MENUITEM "Public Keys..." ID MenuPublicKeys\r
+        MENUITEM SEPARATOR\r
+        MENUITEM "About pssh" ID MenuAboutPalmSSH\r
+        MENUITEM "Credits" ID MenuCredits\r
+    END\r
+END\r
+\r
+MENU TerminalMenuBar\r
+BEGIN\r
+    PULLDOWN "Terminal"\r
+    BEGIN\r
+       MENUITEM "Clear Scrollback" ID MenuClearScrollback\r
+        MENUITEM "Ctrl" ID MenuCtrl "T"\r
+        MENUITEM "Esc" ID MenuEsc "E"\r
+       MENUITEM SEPARATOR\r
+        MENUITEM "Close" ID MenuDisconnect "W"\r
+    END\r
+    PULLDOWN "Edit"\r
+    BEGIN\r
+        MENUITEM "Undo" ID 10000 "U"\r
+        MENUITEM "Cut" ID 10001 "X"\r
+        MENUITEM "Copy" ID 10002 "C"\r
+        MENUITEM "Paste" ID 10003 "P"\r
+        MENUITEM "Select All" ID 10004 "S"\r
+        MENUITEM SEPARATOR\r
+        MENUITEM "Full Keyboard" ID 10006 "K"\r
+        MENUITEM "Mini Keyboard" ID MenuTCKeyboard\r
+        MENUITEM "No Keyboard" ID MenuNoKeyboard\r
+       MENUITEM SEPARATOR\r
+        MENUITEM "Graffiti Help" ID 10007 "G"\r
+    END\r
+    PULLDOWN "Options"\r
+    BEGIN\r
+        MENUITEM "Display Settings..." MenuDisplaySettings\r
+        MENUITEM "Keyboard Settings..." MenuKeyboardSettings\r
+        MENUITEM SEPARATOR\r
+        MENUITEM "Toggle title bar" MenuToggleTitle\r
+        MENUITEM "Toggle control bar" MenuToggleStatusBar\r
+        MENUITEM SEPARATOR\r
+        MENUITEM "About pssh" ID MenuAboutPalmSSH\r
+        MENUITEM "Credits" ID MenuCredits\r
+    END\r
+END\r
+\r
+\r
+ALERT ID AlertFormID\r
+BEGIN\r
+        TITLE "Alert"\r
+        MESSAGE "^1 ^2 ^3"\r
+        BUTTONS "OK"\r
+END\r
+\r
+\r
+ALERT ID FatalAlertID\r
+BEGIN\r
+        TITLE "pssh Fatal Error"\r
+        MESSAGE "Fatal Error: ^1"\r
+        BUTTONS "Quit"\r
+END\r
+\r
+\r
+ALERT ID DeleteConnectionAlertID\r
+BEGIN\r
+        TITLE "Delete Connection"\r
+        MESSAGE "Delete selected connection?"\r
+        BUTTONS "Yes" "No"\r
+END\r
+\r
+\r
+ALERT ID DeleteHostKeyAlertID\r
+BEGIN\r
+        TITLE "Delete Known Host Key"\r
+        MESSAGE "Delete current host key?"\r
+        BUTTONS "Yes" "No"\r
+END\r
+\r
+\r
+ALERT ID DeletePublicKeyAlertID\r
+BEGIN\r
+        TITLE "Delete Public Key"\r
+        MESSAGE "Delete current public key?"\r
+        BUTTONS "Yes" "No"\r
+END\r
+\r
+\r
+ALERT ID NetworkErrorAlertID\r
+BEGIN\r
+        TITLE "Network Error"\r
+        MESSAGE "^1 ^2\n^3"\r
+        BUTTONS "OK"\r
+END\r
+\r
+\r
+WORDLIST ID ResizeDataID\r
+BEGIN\r
+       LoginFormID LoginFormID\r
+       DetailsFormID DetailsFormID\r
+       PasswordFormID PasswordFormID\r
+       MainFormID MainFormID\r
+       TerminalFormID TerminalFormID\r
+       HostKeysFormID HostKeysFormID\r
+       HostKeyWarningFormID HostKeyWarningFormID\r
+       HostKeyDetailsFormID HostKeyDetailsFormID\r
+       AboutFormID AboutFormID\r
+       CreditsFormID CreditsFormID\r
+       DisplayPrefsFormID DisplayPrefsFormID\r
+       ConnectionPrefsFormID ConnectionPrefsFormID\r
+       KeyboardPrefsFormID KeyboardPrefsFormID\r
+       MemoFormID MemoFormID\r
+       PublicKeysFormID PublicKeysFormID\r
+       PublicKeyDetailsFormID PublicKeyDetailsFormID\r
+       PassphraseFormID PassphraseFormID\r
+       PublicKeyChoiceFormID PublicKeyChoiceFormID\r
+       KbdIntFormID KbdIntFormID\r
+       KbdInt0FormID KbdInt0FormID\r
+       BannerFormID BannerFormID\r
+END\r
+\r
+WORDLIST ID LoginFormID\r
+BEGIN\r
+       DIA_FORM_KEEP_LAST+DIA_FORM_USE_BIN 2 0\r
+       0 DIA_W_PLUS_DW 0\r
+       LoginFormHostFieldID DIA_W_PLUS_DW 0\r
+       LoginFormUsernameFieldID DIA_W_PLUS_DW 0\r
+       GSI_OBJECT_ID DIA_X_RIGHT 0\r
+END\r
+\r
+WORDLIST ID DetailsFormID\r
+BEGIN\r
+       DIA_FORM_KEEP_LAST+DIA_FORM_USE_BIN 2 0\r
+       0 DIA_W_PLUS_DW 0\r
+       DetailsFormHostFieldID DIA_W_PLUS_DW 0\r
+       DetailsFormUsernameFieldID DIA_W_PLUS_DW 0\r
+       GSI_OBJECT_ID DIA_X_RIGHT 0\r
+END\r
+\r
+WORDLIST ID PasswordFormID\r
+BEGIN\r
+       DIA_FORM_KEEP_LAST+DIA_FORM_USE_BIN 2 0\r
+       0 DIA_W_PLUS_DW 0\r
+       PasswordFormHostFieldID DIA_W_PLUS_DW 0\r
+       PasswordFormUsernameFieldID DIA_W_PLUS_DW 0\r
+       PasswordFormPasswordFieldID DIA_W_PLUS_DW 0\r
+       GSI_OBJECT_ID DIA_X_RIGHT 0\r
+END\r
+\r
+WORDLIST ID MainFormID\r
+BEGIN\r
+       DIA_FORM_KEEP_LAST+DIA_FORM_USE_BIN 2 0\r
+       0 DIA_W_PLUS_DW+DIA_H_PLUS_DH 0\r
+       MainConnectButtonID DIA_Y_BOTTOM 0\r
+       MainNewButtonID DIA_Y_BOTTOM+DIA_X_RIGHT 0\r
+       MainDetailsButtonID DIA_Y_BOTTOM+DIA_X_RIGHT 0\r
+       /* table and scrollbar handled by resize function */\r
+END\r
+\r
+WORDLIST ID TerminalFormID\r
+BEGIN\r
+       DIA_FORM_KEEP_LAST+DIA_FORM_USE_BIN 1 0\r
+       0 DIA_W_PLUS_DW+DIA_H_PLUS_DH 0\r
+END\r
+\r
+WORDLIST ID HostKeysFormID\r
+BEGIN\r
+       DIA_FORM_KEEP_LAST+DIA_FORM_USE_BIN 2 0\r
+       0 DIA_W_PLUS_DW+DIA_H_PLUS_DH 0\r
+       HostKeysFormOKButtonID DIA_Y_BOTTOM 0\r
+       HostKeysFormDetailsButtonID DIA_Y_BOTTOM 0\r
+       /* table and scrollbar handled by resize function */\r
+END\r
+\r
+WORDLIST ID HostKeyWarningFormID\r
+BEGIN\r
+       DIA_FORM_KEEP_LAST+DIA_FORM_USE_BIN 2 0\r
+       0 DIA_W_PLUS_DW 0\r
+       HostKeyWarningFormContentFieldID DIA_W_PLUS_DW 0\r
+       HostKeyWarningFormAddressFieldID DIA_W_PLUS_DW 0\r
+END\r
+\r
+WORDLIST ID HostKeyDetailsFormID\r
+BEGIN\r
+       DIA_FORM_KEEP_LAST+DIA_FORM_USE_BIN 2 0\r
+       0 DIA_W_PLUS_DW+DIA_H_PLUS_DH 0\r
+       HostKeyDetailsFormOKButtonID DIA_Y_BOTTOM 0\r
+       HostKeyDetailsFormDeleteButtonID DIA_Y_BOTTOM 0\r
+       HostKeyDetailsFormHostFieldID DIA_W_PLUS_DW 0\r
+       HostKeyDetailsFormKeyTypeFieldID DIA_W_PLUS_DW 0\r
+       HostKeyDetailsFormKeyFieldID DIA_W_PLUS_DW+DIA_H_PLUS_DH 0\r
+       HostKeyDetailsFormKeyScrollbarID DIA_X_RIGHT+DIA_H_PLUS_DH 0\r
+END\r
+\r
+WORDLIST ID AboutFormID\r
+BEGIN\r
+       DIA_FORM_KEEP_LAST+DIA_FORM_USE_BIN 2 0\r
+       0 0 0\r
+END\r
+\r
+WORDLIST ID CreditsFormID\r
+BEGIN\r
+       DIA_FORM_KEEP_LAST+DIA_FORM_USE_BIN 2 0\r
+       0 DIA_W_PLUS_DW+DIA_H_PLUS_DH 0\r
+       CreditsFormOKButtonID DIA_X_PLUS_1_2_DW+DIA_Y_BOTTOM 0\r
+       CreditsFormFieldID  DIA_W_PLUS_DW+DIA_H_PLUS_DH 0\r
+       CreditsFormScrollbarID DIA_X_RIGHT+DIA_H_PLUS_DH 0\r
+END\r
+\r
+WORDLIST ID DisplayPrefsFormID\r
+BEGIN\r
+       DIA_FORM_KEEP_LAST+DIA_FORM_USE_BIN 2 0\r
+       0 0 0\r
+END\r
+\r
+WORDLIST ID ConnectionPrefsFormID\r
+BEGIN\r
+       DIA_FORM_KEEP_LAST+DIA_FORM_USE_BIN 2 0\r
+       0 0 0\r
+END\r
+\r
+WORDLIST ID KeyboardPrefsFormID\r
+BEGIN\r
+       DIA_FORM_KEEP_LAST+DIA_FORM_USE_BIN 2 0\r
+       0 0 0\r
+END\r
+\r
+WORDLIST ID MemoFormID\r
+BEGIN\r
+       DIA_FORM_KEEP_LAST+DIA_FORM_USE_BIN 2 0\r
+       0 DIA_W_PLUS_DW+DIA_H_PLUS_DH 0\r
+       MemoFormImportButtonID DIA_Y_BOTTOM 0\r
+       MemoFormCancelButtonID DIA_Y_BOTTOM 0\r
+       /* table and scrollbar handled by resize function */\r
+END\r
+\r
+WORDLIST ID PublicKeysFormID\r
+BEGIN\r
+       DIA_FORM_KEEP_LAST+DIA_FORM_USE_BIN 2 0\r
+       0 DIA_W_PLUS_DW+DIA_H_PLUS_DH 0\r
+       PublicKeysFormOKButtonID DIA_Y_BOTTOM 0\r
+       PublicKeysFormDetailsButtonID DIA_Y_BOTTOM 0\r
+       PublicKeysFormImportButtonID DIA_Y_BOTTOM 0\r
+       /* table and scrollbar handled by resize function */\r
+END\r
+\r
+WORDLIST ID PublicKeyDetailsFormID\r
+BEGIN\r
+       DIA_FORM_KEEP_LAST+DIA_FORM_USE_BIN 2 0\r
+       0 DIA_W_PLUS_DW+DIA_H_PLUS_DH 0\r
+       PublicKeyDetailsFormOKButtonID DIA_Y_BOTTOM 0\r
+       PublicKeyDetailsFormCancelButtonID DIA_Y_BOTTOM 0\r
+       PublicKeyDetailsFormDeleteButtonID DIA_Y_BOTTOM 0\r
+       PublicKeyDetailsFormCommentFieldID DIA_W_PLUS_DW 0\r
+       PublicKeyDetailsFormKeyTypeFieldID DIA_W_PLUS_DW 0\r
+       PublicKeyDetailsFormKeyFieldID DIA_W_PLUS_DW+DIA_H_PLUS_DH 0\r
+       PublicKeyDetailsFormKeyScrollbarID DIA_X_RIGHT+DIA_H_PLUS_DH 0\r
+       GSI_OBJECT_ID DIA_X_RIGHT+DIA_Y_BOTTOM\r
+END\r
+\r
+WORDLIST ID PassphraseFormID\r
+BEGIN\r
+       DIA_FORM_KEEP_LAST+DIA_FORM_USE_BIN 2 0\r
+       0 DIA_W_PLUS_DW 0\r
+       PassphraseFormMessageFieldID DIA_W_PLUS_DW 0\r
+       GSI_OBJECT_ID DIA_X_RIGHT 0\r
+END\r
+\r
+WORDLIST ID PublicKeyChoiceFormID\r
+BEGIN\r
+       DIA_FORM_KEEP_LAST+DIA_FORM_USE_BIN 2 0\r
+       0 DIA_W_PLUS_DW 0\r
+       PublicKeyChoiceFormHostFieldID DIA_W_PLUS_DW 0\r
+       PublicKeyChoiceFormUsernameFieldID DIA_W_PLUS_DW 0\r
+       PublicKeyChoiceFormPassphraseFieldID DIA_W_PLUS_DW 0\r
+       PublicKeyChoiceFormKeyTriggerID DIA_W_PLUS_DW 0\r
+       PublicKeyChoiceFormKeyListID DIA_W_PLUS_DW+DIA_H_PLUS_DH 0\r
+       GSI_OBJECT_ID DIA_X_RIGHT 0\r
+END\r
+\r
+WORDLIST ID KbdIntFormID\r
+BEGIN\r
+       DIA_FORM_KEEP_LAST+DIA_FORM_USE_BIN 2 0\r
+       0 DIA_W_PLUS_DW+DIA_H_PLUS_DH 0\r
+       KbdIntFormHostFieldID DIA_W_PLUS_DW 0\r
+       KbdIntFormInstructionFieldID DIA_W_PLUS_DW+DIA_H_PLUS_DH 0\r
+       KbdIntFormInstructionScrollbarID DIA_X_RIGHT+DIA_H_PLUS_DH 0\r
+       KbdIntFormPromptFieldID DIA_W_PLUS_DW+DIA_Y_BOTTOM 0\r
+       KbdIntFormResponseFieldID DIA_W_PLUS_DW+DIA_Y_BOTTOM 0\r
+       KbdIntFormEchoCheckboxID DIA_Y_BOTTOM 0\r
+       GSI_OBJECT_ID DIA_X_RIGHT+DIA_Y_BOTTOM 0\r
+       KbdIntFormNextButtonID DIA_Y_BOTTOM 0\r
+       KbdIntFormCancelButtonID DIA_Y_BOTTOM 0\r
+       KbdIntFormBackButtonID DIA_X_RIGHT+DIA_Y_BOTTOM 0\r
+END\r
+\r
+WORDLIST ID KbdInt0FormID\r
+BEGIN\r
+       DIA_FORM_KEEP_LAST+DIA_FORM_USE_BIN 2 0\r
+       0 DIA_W_PLUS_DW+DIA_H_PLUS_DH 0\r
+       KbdInt0FormHostFieldID DIA_W_PLUS_DW 0\r
+       KbdInt0FormInstructionFieldID DIA_W_PLUS_DW+DIA_H_PLUS_DH 0\r
+       KbdInt0FormInstructionScrollbarID DIA_X_RIGHT+DIA_H_PLUS_DH 0\r
+       KbdInt0FormOKButtonID DIA_Y_BOTTOM 0\r
+       KbdInt0FormCancelButtonID DIA_Y_BOTTOM 0\r
+END\r
+\r
+WORDLIST ID BannerFormID\r
+BEGIN\r
+       DIA_FORM_KEEP_LAST+DIA_FORM_USE_BIN 2 0\r
+       0 DIA_H_PLUS_DH+DIA_W_PLUS_DW 0\r
+       BannerFormOKButtonID DIA_X_PLUS_1_2_DW+DIA_Y_BOTTOM 0\r
+       BannerFormFieldID DIA_W_PLUS_DW+DIA_H_PLUS_DH 0\r
+       BannerFormScrollbarID DIA_X_RIGHT+DIA_H_PLUS_DH 0\r
+END\r
+\r
+\r
diff --git a/rsrc/pssh.rsrc b/rsrc/pssh.rsrc
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rsrc/rightarrow.bmp b/rsrc/rightarrow.bmp
new file mode 100644 (file)
index 0000000..62d534f
Binary files /dev/null and b/rsrc/rightarrow.bmp differ
diff --git a/rsrc/rightarrowhi.bmp b/rsrc/rightarrowhi.bmp
new file mode 100644 (file)
index 0000000..6f1262b
Binary files /dev/null and b/rsrc/rightarrowhi.bmp differ
diff --git a/rsrc/rightarrowselected.bmp b/rsrc/rightarrowselected.bmp
new file mode 100644 (file)
index 0000000..3621a26
Binary files /dev/null and b/rsrc/rightarrowselected.bmp differ
diff --git a/rsrc/rightarrowselectedhi.bmp b/rsrc/rightarrowselectedhi.bmp
new file mode 100644 (file)
index 0000000..b30682f
Binary files /dev/null and b/rsrc/rightarrowselectedhi.bmp differ
diff --git a/rsrc/rsrc.h b/rsrc/rsrc.h
new file mode 100644 (file)
index 0000000..13f5df3
--- /dev/null
@@ -0,0 +1,395 @@
+/**********
+ * Copyright (c) 2003-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#define PSSH_VERSION "2005-06-23"
+#define PSSH_UVERSION "2005_06_23"
+
+#define PSSH_CREATOR 'GPss'
+
+#define ftrEntropy 1  // entropy cache
+#define ftrEntropyWarning 2  // warned about crappy RNG?
+#define ftrSecurityWarning 3 // warned about pssh insecurity?
+
+#define MainMenuBar                                        1000
+#define TerminalMenuBar                                    1001
+
+#define MenuAboutPalmSSH                                   1000
+#define MenuConnect                                        1001
+#define MenuHostKeys                                       1002
+#define MenuDisconnect                                     1003
+#define MenuClearScrollback                                1004
+#define MenuCredits                                        1005
+#define MenuPublicKeys                                     1006
+#define MenuTCKeyboard                                     1007
+#define MenuDisplaySettings                                1008
+#define MenuConnectionSettings                             1009
+#define MenuToggleTitle                                    1010
+#define MenuToggleInputArea                                1011
+#define MenuCtrl                                           1012
+#define MenuEsc                                            1013
+#define MenuKeyboardSettings                               1014
+#define MenuNoKeyboard                                     1015
+#define MenuToggleStatusBar                                1016
+
+
+#define NanoFontDoubleID                                   200
+#define NanoFontSingleID                                   201
+#define MediumFontDoubleID                                 202
+#define MediumFontSingleID                                 203
+#define PasswordFontID                                     204
+
+
+#define MainFormID                                         1000
+#define MainConnectButtonID 1001
+#define MainNewButtonID 1002
+#define MainDetailsButtonID 1003
+#define MainConnectionTableID 1004
+#define MainConnectionScrollbarID 1005
+
+#define AboutFormID                                        1100
+#define AboutFormOKButtonID                                1101
+
+// 1200..1299 Terminal graphical button bitmaps
+#define TerminalCloseBoxBitmapID 1200
+#define TerminalCloseBoxSelectedBitmapID 1201
+#define TerminalRScrollLineUpBitmapID 1202
+#define TerminalRScrollLineUpSelectedBitmapID 1203
+#define TerminalRScrollLineUpDisabledBitmapID 1204
+#define TerminalRScrollLineDownBitmapID 1205
+#define TerminalRScrollLineDownSelectedBitmapID 1206
+#define TerminalRScrollLineDownDisabledBitmapID 1207
+#define TerminalRScrollPageUpBitmapID 1208
+#define TerminalRScrollPageUpSelectedBitmapID 1209
+#define TerminalRScrollPageUpDisabledBitmapID 1210
+#define TerminalRScrollPageDownBitmapID 1211
+#define TerminalRScrollPageDownSelectedBitmapID 1212
+#define TerminalRScrollPageDownDisabledBitmapID 1213
+
+#define TerminalFormID 1300
+// 1300-1305 Controls present on all Terminal form flavors
+#define TerminalCtrlButtonID 1301
+#define TerminalMetaButtonID 1302
+#define TerminalTextGadgetID 1303
+#define TerminalHostFieldID 1304
+#define TerminalCloseBoxButtonID 1305
+
+// RArrows: Right side is arrow keys (harware keys are scolling)
+// fixme unimplemented
+
+// 1306-1329 RScroll: Right side is scrolling (hardware keys are arrow keys)
+#define TerminalRScrollLineUpButtonID 1306
+#define TerminalRScrollLineDownButtonID 1310
+#define TerminalRScrollPageUpButtonID 1314
+#define TerminalRScrollPageDownButtonID 1318
+
+// 1330-1349 BTC: Bottom side is all 15 ASCII chars not on Tungsten C keyboard
+// This set is also used for Treo 600, with '&' changed to '_'
+#define TerminalBTCButtonsBitmapID 1330
+// 15 self-labeled buttons, one of which is changed between T|C and Treo 600
+#define TerminalBTCFirstButtonID 1331
+#define TerminalBTCAmpersandButtonID TerminalBTCFirstButtonID+4
+#define TerminalBTCLastButtonID 1345
+
+// 1350-1374 BFull: Bottom side is scroll arrows and full-keyboard selectors
+#define TerminalBFullABCButtonID 1350
+#define TerminalBFull123ButtonID 1351
+#define TerminalBFullIntlButtonID 1352
+#define TerminalBFullEtcButtonID 1353
+#define TerminalBFullUpButtonID 1354
+#define TerminalBFullDownButtonID 1355
+#define TerminalBFullLeftButtonID 1356
+#define TerminalBFullRightButtonID 1357
+#define TerminalBFullUpBitmapID 1358
+#define TerminalBFullDownBitmapID 1359
+#define TerminalBFullLeftBitmapID 1360
+#define TerminalBFullRightBitmapID 1361
+#define TerminalBFullUpSelectedBitmapID 1362
+#define TerminalBFullDownSelectedBitmapID 1363
+#define TerminalBFullLeftSelectedBitmapID 1364
+#define TerminalBFullRightSelectedBitmapID 1365
+
+// TNone: Top side is full-size vt100
+// No additional controls
+
+// 1375-1449 TABC: Top side is QWERTY keyboard
+#define TerminalTABCButtonsBitmapID 1375
+// 26 self-labeled lowercase letters
+#define TerminalTABCFirstAlphaButtonID 1376
+#define TerminalTABCLastAlphaButtonID 1401
+// 6 self-labeled punctuation
+#define TerminalTABCFirstPunctButtonID 1402
+#define TerminalTABCLastPunctButtonID 1407
+// 26 self-labeled uppercase letters
+#define TerminalTABCFirstALPHAButtonID 1408
+#define TerminalTABCLastALPHAButtonID 1433
+// 6 self-labeled shifted punctuation
+#define TerminalTABCFirstPUNCTButtonID 1434
+#define TerminalTABCLastPUNCTButtonID 1439
+// 6 non-self-labeled buttons
+#define TerminalTABCTabButtonID 1440
+#define TerminalTABCCapsButtonID 1441
+#define TerminalTABCShiftButtonID 1442
+#define TerminalTABCSpaceButtonID 1443
+#define TerminalTABCBackspaceButtonID 1444
+#define TerminalTABCReturnButtonID 1445
+
+// button ranges: all, lower, upper, caps (upper alpha but lower punct)
+#define TerminalTABCFirstButtonID TerminalTABCFirstAlphaButtonID
+#define TerminalTABCLastButtonID TerminalTABCLastPUNCTButtonID
+#define TerminalTABCFirstLowercaseButtonID TerminalTABCFirstAlphaButtonID
+#define TerminalTABCLastLowercaseButtonID TerminalTABCLastPunctButtonID
+#define TerminalTABCFirstUppercaseButtonID TerminalTABCFirstALPHAButtonID
+#define TerminalTABCLastUppercaseButtonID TerminalTABCLastPUNCTButtonID
+#define TerminalTABCFirstCapscaseButtonID TerminalTABCFirstPunctButtonID
+#define TerminalTABCLastCapscaseButtonID TerminalTABCLastALPHAButtonID
+
+// 1450-1499 T123: Top side is number pad and symbols
+#define TerminalT123ButtonsBitmapID 1450
+// 44 self-labeled buttons
+#define TerminalT123FirstButtonID 1451
+#define TerminalT123LastButtonID 1494
+// 4 non-self-labeled buttons
+#define TerminalT123BackspaceButtonID 1495
+#define TerminalT123TabButtonID 1496
+#define TerminalT123ReturnButtonID 1497
+#define TerminalT123SpaceButtonID 1498
+
+// 1500-1574 TIntl: Top side is accented characters
+// Some of these controls are shared with the ABC pane
+#define TerminalTIntlButtonsBitmapID TerminalTABCButtonsBitmapID
+// 32 self-labeled lowercase letters
+#define TerminalTIntlFirstLowercaseButtonID 1501
+#define TerminalTIntlLastLowercaseButtonID 1532
+// 32 self-labeled uppercase letters
+#define TerminalTIntlFirstUppercaseButtonID 1533
+#define TerminalTIntlLastUppercaseButtonID 1564
+#define TerminalTIntlFirstButtonID TerminalTIntlFirstLowercaseButtonID
+#define TerminalTIntlLastButtonID TerminalTIntlLastUppercaseButtonID
+// 6 non-self-labeled buttons
+#define TerminalTIntlTabButtonID TerminalTABCTabButtonID
+#define TerminalTIntlCapsButtonID TerminalTABCCapsButtonID
+#define TerminalTIntlShiftButtonID TerminalTABCShiftButtonID
+#define TerminalTIntlSpaceButtonID TerminalTABCSpaceButtonID
+#define TerminalTIntlBackspaceButtonID TerminalTABCBackspaceButtonID
+#define TerminalTIntlReturnButtonID TerminalTABCReturnButtonID
+
+
+// 1575-1650 TEtc: Top side is function keys, scroll pad, and misc Latin 1
+// Some of these controls are shared with the ABC pane
+#define TerminalTEtcButtonsBitmapID 1575
+// 16 self-labeled "lowercase" Latin 1 characters
+#define TerminalTEtcFirstLowercaseLatin1ButtonID 1576
+#define TerminalTEtcLastLowercaseLatin1ButtonID 1591
+// 16 self-labeled "uppercase" Latin 1 characters
+#define TerminalTEtcFirstUppercaseLatin1ButtonID 1592
+#define TerminalTEtcLastUppercaseLatin1ButtonID 1607
+// 10 "lowercase" FKeys F1..F10
+#define TerminalTEtcFirstLowercaseFKeyButtonID 1608
+#define TerminalTEtcLastLowercaseFKeyButtonID 1617
+// 10 "uppercase" FKeys F11..F20
+#define TerminalTEtcFirstUppercaseFKeyButtonID 1618
+#define TerminalTEtcLastUppercaseFKeyButtonID 1627
+// 6 scroll pad keys (ordered by emulation code; do not reorder!)
+#define TerminalTEtcHomeButtonID 1628
+#define TerminalTEtcInsButtonID 1629
+#define TerminalTEtcDelButtonID 1630
+#define TerminalTEtcEndButtonID 1631
+#define TerminalTEtcPgUpButtonID 1632
+#define TerminalTEtcPgDnButtonID 1633
+// 1 shift key
+#define TerminalTEtcShiftButtonID TerminalTABCShiftButtonID
+// ranges
+// self-labeled and FKeys are each contiguous, but lower and uppercase are not
+#define TerminalTEtcFirstButtonID TerminalTEtcFirstLowercaseLatin1ButtonID
+#define TerminalTEtcLastButtonID  TerminalTEtcLastUppercaseFKeyButtonID
+#define TerminalTEtcFirstLatin1ButtonID TerminalTEtcFirstLowercaseLatin1ButtonID
+#define TerminalTEtcLastLatin1ButtonID  TerminalTEtcLastUppercaseLatin1ButtonID
+#define TerminalTEtcFirstFKeyButtonID TerminalTEtcFirstLowercaseFKeyButtonID
+#define TerminalTEtcLastFKeyButtonID  TerminalTEtcLastUppercaseFKeyButtonID
+
+
+#define HostKeysFormID 1800
+#define HostKeysFormOKButtonID 1801
+#define HostKeysFormDetailsButtonID 1802
+#define HostKeysFormKeyTableID 1803
+#define HostKeysFormKeyScrollbarID 1804
+
+#define HostKeyWarningFormID 1900
+#define HostKeyWarningFormRejectButtonID 1901
+#define HostKeyWarningFormTrustOnceButtonID 1902
+#define HostKeyWarningFormTrustForeverButtonID 1903
+#define HostKeyWarningFormContentFieldID 1904
+#define HostKeyWarningFormAddressFieldID 1905
+
+#define HostKeyDetailsFormID 2000
+#define HostKeyDetailsFormOKButtonID 2001
+#define HostKeyDetailsFormDeleteButtonID 2002
+#define HostKeyDetailsFormHostFieldID 2003
+#define HostKeyDetailsFormKeyTypeFieldID 2004
+#define HostKeyDetailsFormKeyFieldID 2005
+#define HostKeyDetailsFormKeyScrollbarID 2006
+
+#define CreditsFormID 2100
+#define CreditsFormFieldID 2101
+#define CreditsFormScrollbarID 2102
+#define CreditsFormOKButtonID 2103
+
+#define DisplayPrefsFormID 2200
+#define DisplayPrefsFormOKButtonID 2201
+#define DisplayPrefsFormCancelButtonID 2202
+#define DisplayPrefsFormSmallFontCheckboxID 2203
+#define DisplayPrefsFormLargeFontCheckboxID 2204
+#define DisplayPrefsFormForeColorTriggerID 2205
+#define DisplayPrefsFormBackColorTriggerID 2206
+#define DisplayPrefsFormForeColorListID 2207
+#define DisplayPrefsFormBackColorListID 2208
+#define DisplayPrefsFormSampleTextGadgetID 2209
+#define DisplayPrefsFormScrollbackFieldID 2210
+#define DisplayPrefsFormActivityCheckboxID 2211
+#define DisplayPrefsFormTypingCheckboxID 2212
+#define DisplayPrefsFormBeepCheckboxID 2213
+#define DisplayPrefsFormFlashCheckboxID 2214
+
+#define MemoFormID 2300
+#define MemoFormImportButtonID 2301
+#define MemoFormCancelButtonID 2302
+#define MemoFormTableID 2303
+#define MemoFormScrollbarID 2304
+
+#define PublicKeysFormID 2400
+#define PublicKeysFormOKButtonID 2401
+#define PublicKeysFormDetailsButtonID 2402
+#define PublicKeysFormImportButtonID 2403
+#define PublicKeysFormKeyTableID 2404
+#define PublicKeysFormKeyScrollbarID 2405
+
+#define PublicKeyDetailsFormID 2500
+#define PublicKeyDetailsFormOKButtonID 2501
+#define PublicKeyDetailsFormCancelButtonID 2502
+#define PublicKeyDetailsFormDeleteButtonID 2503
+#define PublicKeyDetailsFormCommentFieldID 2504
+#define PublicKeyDetailsFormKeyTypeFieldID 2505
+#define PublicKeyDetailsFormKeyFieldID 2506
+#define PublicKeyDetailsFormKeyScrollbarID 2507
+
+#define PassphraseFormID 2600
+#define PassphraseFormOKButtonID 2601
+#define PassphraseFormCancelButtonID 2602
+#define PassphraseFormMessageFieldID 2603
+#define PassphraseFormPassphraseFieldID 2604
+#define PassphraseFormEchoCheckboxID 2605
+
+#define PublicKeyChoiceFormID 2700
+#define PublicKeyChoiceFormOKButtonID 2701
+#define PublicKeyChoiceFormCancelButtonID 2702
+#define PublicKeyChoiceFormHostFieldID 2703
+#define PublicKeyChoiceFormUsernameFieldID 2704
+#define PublicKeyChoiceFormPassphraseFieldID 2705
+#define PublicKeyChoiceFormEchoCheckboxID 2706
+#define PublicKeyChoiceFormKeyListID 2707
+#define PublicKeyChoiceFormKeyTriggerID 2708
+
+#define ConnectionPrefsFormID 2800
+#define ConnectionPrefsFormOKButtonID 2801
+#define ConnectionPrefsFormCancelButtonID 2802
+#define ConnectionPrefsFormAESCheckboxID 2803
+#define ConnectionPrefsForm3DESCheckboxID 2804
+#define ConnectionPrefsFormPublicKeyCheckboxID 2805
+#define ConnectionPrefsFormPasswordCheckboxID 2806
+#define ConnectionPrefsFormKbdIntCheckboxID 2807
+#define ConnectionPrefsFormZLibCheckboxID 2808
+#define ConnectionPrefsFormTerminalFieldID 2809
+#define ConnectionPrefsFormTerminalTriggerID 2810
+#define ConnectionPrefsFormTerminalListID 2811
+
+#define LoginFormID 2900
+#define LoginFormConnectButtonID 2901
+#define LoginFormCancelButtonID 2902
+#define LoginFormSaveButtonID 2903
+#define LoginFormHostFieldID 2904
+#define LoginFormPortFieldID 2905
+#define LoginFormUsernameFieldID 2906
+
+#define BannerFormID 3000
+#define BannerFormFieldID 3001
+#define BannerFormScrollbarID 3002
+#define BannerFormOKButtonID 3003
+
+#define PasswordFormID 3100
+#define PasswordFormOKButtonID 3101
+#define PasswordFormCancelButtonID 3102
+#define PasswordFormHostFieldID 3103
+#define PasswordFormUsernameFieldID 3104
+#define PasswordFormPasswordFieldID 3105
+#define PasswordFormEchoCheckboxID 3106
+
+#define DetailsFormID 3200
+#define DetailsFormOKButtonID 3201
+#define DetailsFormCancelButtonID 3202
+#define DetailsFormDeleteButtonID 3203
+#define DetailsFormHostFieldID 3204
+#define DetailsFormPortFieldID 3205
+#define DetailsFormUsernameFieldID 3206
+
+#define KeyboardPrefsFormID 3300
+#define KeyboardPrefsFormOKButtonID 3301
+#define KeyboardPrefsFormCancelButtonID 3302
+#define KeyboardPrefsFormBackspaceDELCheckboxID 3303
+#define KeyboardPrefsFormBackspaceBSCheckboxID 3304
+#define KeyboardPrefsFormBackquoteNormalCheckboxID 3305
+#define KeyboardPrefsFormBackquoteESCCheckboxID 3306
+
+// This order is significant; see ShortenForm() in kbdintform.c
+#define KbdIntFormID 3400
+#define KbdIntFormHostLabelID 3401
+#define KbdIntFormHostFieldID 3402
+#define KbdIntFormInstructionFieldID 3403
+#define KbdIntFormInstructionScrollbarID 3404
+#define KbdIntFormPromptFieldID 3405
+#define KbdIntFormResponseFieldID 3406
+#define KbdIntFormEchoCheckboxID 3407
+#define KbdIntFormProgressFieldID 3408
+#define KbdIntFormNextButtonID 3409
+#define KbdIntFormBackButtonID 3410
+#define KbdIntFormCancelButtonID 3411
+#define KbdIntFormLastID 3411
+
+// This order is significant; see ShortenForm() in kbdint0form.c
+#define KbdInt0FormID 3500
+#define KbdInt0FormHostLabelID 3501
+#define KbdInt0FormHostFieldID 3502
+#define KbdInt0FormInstructionFieldID 3503
+#define KbdInt0FormInstructionScrollbarID 3504
+#define KbdInt0FormOKButtonID 3505
+#define KbdInt0FormCancelButtonID 3506
+#define KbdInt0FormLastID 3506
+
+#define DeleteConnectionAlertID 6000
+#define DeleteHostKeyAlertID 6100
+#define AlertFormID 6200
+#define FatalAlertID 6300
+#define NetworkErrorAlertID 6400
+#define DeletePublicKeyAlertID 6500
+
+#define ResizeDataID 999
diff --git a/rsrc/tcbuttons.bmp b/rsrc/tcbuttons.bmp
new file mode 100644 (file)
index 0000000..2bb46d3
Binary files /dev/null and b/rsrc/tcbuttons.bmp differ
diff --git a/rsrc/uparrow.bmp b/rsrc/uparrow.bmp
new file mode 100644 (file)
index 0000000..4901e9f
Binary files /dev/null and b/rsrc/uparrow.bmp differ
diff --git a/rsrc/uparrowhi.bmp b/rsrc/uparrowhi.bmp
new file mode 100644 (file)
index 0000000..b82265d
Binary files /dev/null and b/rsrc/uparrowhi.bmp differ
diff --git a/rsrc/uparrowselected.bmp b/rsrc/uparrowselected.bmp
new file mode 100644 (file)
index 0000000..8b950ed
Binary files /dev/null and b/rsrc/uparrowselected.bmp differ
diff --git a/rsrc/uparrowselectedhi.bmp b/rsrc/uparrowselectedhi.bmp
new file mode 100644 (file)
index 0000000..4b74c4f
Binary files /dev/null and b/rsrc/uparrowselectedhi.bmp differ
diff --git a/ssh/connection.c b/ssh/connection.c
new file mode 100644 (file)
index 0000000..597ebc2
--- /dev/null
@@ -0,0 +1,1783 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "connection.h"
+
+#include "xmalloc.h"
+#include "assert.h"
+#include "session.h"
+#include "transport.h"
+#include "packetizer.h"
+#include "vt100/vt100.h"
+#include "ssh2.h"
+#include "data/prefs.h"
+#include "data/publickeys.h"
+#include "forms/about.h"
+#include "openssh/buffer.h"
+#include "openssh/bufaux.h"
+#include "openssh/key.h"
+#include "openssh/match.h"
+#include "rsrc/rsrc.h"
+
+#define DATA_MAX 32768
+#define RECEIVE_WINDOW_MIN DATA_MAX
+#define RECEIVE_WINDOW_MAX DATA_MAX*4
+
+
+static void connection_send_pty_request(ssh_session_t *ss, uint32_t channel) CONNECTION_SEGMENT;
+static void connection_send_shell_request(ssh_session_t *ss, uint32_t channel) CONNECTION_SEGMENT;
+static void connection_send_window_change(ssh_session_t *ss, uint32_t channel, int charsWide, int charsHigh, int pixelsWide, int pixelsHigh) CONNECTION_SEGMENT;
+static void connection_send_service_request(ssh_session_t *ss, char *name) CONNECTION_SEGMENT;
+static void connection_send_userauth(ssh_session_t *ss, char *username, char *authmethod, uint8_t *authdata, uint16_t authdatalen) CONNECTION_SEGMENT;
+static void connection_send_userauth_password(ssh_session_t *ss, char *username, char *password) CONNECTION_SEGMENT;
+static void connection_send_userauth_publickey(ssh_session_t *ss, char *username, Key *key, Boolean check) CONNECTION_SEGMENT;
+static void connection_send_userauth_kbdint(ssh_session_t *ss, char *username) CONNECTION_SEGMENT; 
+static void connection_send_authmethod_request(ssh_session_t *ss, char *username) CONNECTION_SEGMENT;
+static void connection_send_kbdint_responses(ssh_session_t *ss, char **responses, uint16_t count) CONNECTION_SEGMENT;
+static void connection_send_channel_open(ssh_session_t *ss, uint32_t channel, uint32_t receiveWindow, uint32_t packetMax) CONNECTION_SEGMENT;
+static void connection_send_window_adjust(ssh_session_t *ss, uint32_t channel, uint32_t adjustment) CONNECTION_SEGMENT;
+static void connection_send_channel_close(ssh_session_t *ss, uint32_t channel) CONNECTION_SEGMENT;
+static void connection_send_global_request_failure(ssh_session_t *ss) CONNECTION_SEGMENT;
+static void connection_send_channel_request_failure(ssh_session_t *ss, uint32_t channel) CONNECTION_SEGMENT;
+static void connection_send_channel_data(ssh_session_t *ss, uint32_t channel, uint8_t *bytes, uint16_t len) CONNECTION_SEGMENT;
+
+static connection_state_t connection_request_kbdint(ssh_session_t *ss) CONNECTION_SEGMENT;
+static connection_state_t connection_check_next_publickey(ssh_session_t *ss, queue_t *q) CONNECTION_SEGMENT;
+static connection_state_t connection_get_password(ssh_session_t *ss) CONNECTION_SEGMENT;
+static connection_state_t connection_get_passphrase(ssh_session_t *ss, queue_t *q) CONNECTION_SEGMENT;
+static void connection_increase_receive_window(ssh_session_t *ss) CONNECTION_SEGMENT;
+static void connection_handle_typed_data(ssh_session_t *ss, uint32_t type, uint8_t *data, uint32_t datalen, int closing) CONNECTION_SEGMENT;
+static connection_state_t connection_handle_unexpected_message(ssh_session_t *ss, uint8_t msg, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_handle_userauth_service_accept(ssh_session_t *ss, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_handle_banner(ssh_session_t *ss, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_handle_userauth_success(ssh_session_t *ss, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_try_next_userauth(ssh_session_t *ss) CONNECTION_SEGMENT;
+static connection_state_t connection_handle_userauth_failure(ssh_session_t *ss, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_handle_good_publickey(ssh_session_t *ss, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_handle_bad_publickey(ssh_session_t *ss, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_handle_kbdint_info_request(ssh_session_t *ss, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_handle_password_change(ssh_session_t *ss, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_handle_channel_open(ssh_session_t *ss, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_handle_channel_open_failure(ssh_session_t *ss, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_handle_pty_success(ssh_session_t *ss, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_handle_pty_failure(ssh_session_t *ss, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_handle_shell_success(ssh_session_t *ss, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_handle_shell_failure(ssh_session_t *ss, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_handle_window_adjust(ssh_session_t *ss, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_handle_channel_close(ssh_session_t *ss, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_handle_data(ssh_session_t *ss, Buffer *packet, int closing) CONNECTION_SEGMENT;
+static connection_state_t connection_handle_extended_data(ssh_session_t *ss, Buffer *packet, int closing) CONNECTION_SEGMENT;
+
+static connection_state_t connection_state_waiting_for_userauth_service(ssh_session_t *ss, uint8_t msg, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_state_waiting_for_password(ssh_session_t *ss, uint8_t msg, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_state_waiting_for_password_userauth(ssh_session_t *ss, uint8_t msg, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_state_waiting_for_pubkey_check(ssh_session_t *ss, uint8_t msg, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_state_waiting_for_pubkey_passphrase(ssh_session_t *ss, uint8_t msg, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_state_waiting_for_pubkey_userauth(ssh_session_t *ss, uint8_t msg, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_state_waiting_for_kbdint_info_request(ssh_session_t *ss, uint8_t msg, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_state_waiting_for_kbdint_userauth(ssh_session_t *ss, uint8_t msg, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_state_waiting_for_channel_open(ssh_session_t *ss, uint8_t msg, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_state_waiting_for_pty(ssh_session_t *ss, uint8_t msg, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_state_waiting_for_shell(ssh_session_t *ss, uint8_t msg, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_state_running(ssh_session_t *ss, uint8_t msg, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_state_closing(ssh_session_t *ss, uint8_t msg, Buffer *packet) CONNECTION_SEGMENT;
+static connection_state_t connection_state_closed(ssh_session_t *ss, uint8_t msg, Buffer *packet) CONNECTION_SEGMENT;
+static void reset_untried_authmethods(ssh_session_t *ss) CONNECTION_SEGMENT;
+static void kbdint_cleanup(ssh_session_t *ss) CONNECTION_SEGMENT;
+static void connection_cleanup(ssh_session_t *ss) CONNECTION_SEGMENT;
+
+
+/***********************************************************************
+ * raw packet output
+ */
+
+static void connection_send_pty_request(ssh_session_t *ss, uint32_t channel)
+{
+    Buffer payload;
+    int charsWide;
+    int charsHigh;
+    char *termtype;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    ssh_size(ss, &charsWide, &charsHigh);
+    termtype = PrefsGetString(prefTerminalType, "xterm");
+
+    printf("   Opening pty...\r\n");
+
+    buffer_init(&payload);
+    buffer_put_char(&payload, SSH2_MSG_CHANNEL_REQUEST);
+    buffer_put_int(&payload, channel);
+    buffer_put_cstring(&payload, "pty-req");
+    buffer_put_char(&payload, 1); // want-reply
+    buffer_put_cstring(&payload, termtype); // TERM
+    buffer_put_int(&payload, charsWide); // tty width  (chars)
+    buffer_put_int(&payload, charsHigh); // tty height (chars)
+    buffer_put_int(&payload, 0);  // tty width  (pixels) fixme
+    buffer_put_int(&payload, 0);  // tty height (pixels) fixme
+    buffer_put_cstring(&payload, ""); // encoded terminal modes
+    transport_send_payload(ss, &payload);
+    buffer_free(&payload);
+    connection_log("connection: sent pty request\r\n");
+
+    arena_free(termtype);
+}
+
+
+static void connection_send_shell_request(ssh_session_t *ss, uint32_t channel)
+{
+    Buffer payload;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    printf("   Starting shell...\r\n");
+
+    buffer_init(&payload);
+    buffer_put_char(&payload, SSH2_MSG_CHANNEL_REQUEST);
+    buffer_put_int(&payload, channel);
+    buffer_put_cstring(&payload, "shell");
+    buffer_put_char(&payload, 1); // want-reply
+    transport_send_payload(ss, &payload);
+    buffer_free(&payload);
+    connection_log("connection: sent shell request\r\n");
+}
+
+
+static void connection_send_window_change(ssh_session_t *ss, uint32_t channel, 
+                                          int charsWide, int charsHigh, 
+                                          int pixelsWide, int pixelsHigh)
+{
+    Buffer payload;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    buffer_init(&payload);
+    buffer_put_char(&payload, SSH2_MSG_CHANNEL_REQUEST);
+    buffer_put_int(&payload, channel);
+    buffer_put_cstring(&payload, "window-change");
+    buffer_put_char(&payload, 0); // want-reply
+    buffer_put_int(&payload, charsWide);
+    buffer_put_int(&payload, charsHigh);
+    buffer_put_int(&payload, pixelsWide);
+    buffer_put_int(&payload, pixelsHigh);
+    transport_send_payload(ss, &payload);
+    buffer_free(&payload);
+    connection_log("connection: sent WINCH\r\n");    
+}
+
+static void connection_send_service_request(ssh_session_t *ss, char *name)
+{
+    Buffer packet;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    buffer_init(&packet);
+    buffer_put_char(&packet, SSH2_MSG_SERVICE_REQUEST);
+    buffer_put_cstring(&packet, name);
+    transport_send_payload(ss, &packet);
+    buffer_free(&packet);
+    connection_log("connection: sent service request for '%s'\r\n", name);
+}
+
+
+static void 
+connection_send_userauth(ssh_session_t *ss, char *username, 
+                         char *authmethod, uint8_t *authdata, 
+                         uint16_t authdatalen)
+{
+    Buffer payload;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    buffer_init(&payload);
+    buffer_put_char(&payload, SSH2_MSG_USERAUTH_REQUEST);
+    buffer_put_cstring(&payload, username);
+    buffer_put_cstring(&payload, "ssh-connection"); // service
+    buffer_put_cstring(&payload, authmethod);
+    if (authdata) {
+        buffer_append(&payload, authdata, authdatalen);
+    }
+    transport_send_payload(ss, &payload);
+    buffer_free(&payload);
+    connection_log("connection: sent userauth request for username '%s' using authmethod '%s'\r\n", username, authmethod);
+}
+
+
+static void 
+connection_send_userauth_password(ssh_session_t *ss, char *username, char *password)
+{
+    Buffer authdata;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    buffer_init(&authdata);
+    buffer_put_char(&authdata, 0); // boolean FALSE
+    buffer_put_cstring(&authdata, password);
+    connection_send_userauth(ss, username, "password", 
+                             buffer_ptr(&authdata), buffer_len(&authdata));
+    buffer_free(&authdata);
+}
+
+
+static void 
+connection_send_userauth_publickey(ssh_session_t *ss, char *username, 
+                                   Key *key, Boolean check)
+{
+    Buffer authdata;
+    Buffer keyblob;
+    int realAuth = (check ? 0 : 1);
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    buffer_init(&authdata);
+    buffer_put_char(&authdata, realAuth); // FALSE if this is validity check
+    buffer_put_cstring(&authdata, key_ssh_name(key));
+
+    buffer_init(&keyblob);
+    key_to_blob_buffer(key, &keyblob);
+    buffer_put_string(&authdata, buffer_ptr(&keyblob), buffer_len(&keyblob));
+    buffer_free(&keyblob);
+
+    if (realAuth) {
+        // yuck - signature covers data that isn't needed until
+        // connection_send_userauth()
+        Buffer signbuf;
+        uint8_t *signature;
+        uint16_t signaturelen;
+        buffer_init(&signbuf);
+        buffer_put_string(&signbuf, ss->t.session_id, ss->t.session_id_len);
+        buffer_put_char(&signbuf, SSH2_MSG_USERAUTH_REQUEST);
+        buffer_put_cstring(&signbuf, username);
+        buffer_put_cstring(&signbuf, "ssh-connection");
+        buffer_put_cstring(&signbuf, "publickey");
+        buffer_append(&signbuf, buffer_ptr(&authdata), buffer_len(&authdata));
+        
+        // sign signdata with privkey and append signature to authdata
+        key_sign(key, &signature, &signaturelen, 
+                 buffer_ptr(&signbuf), buffer_len(&signbuf));
+        buffer_put_string(&authdata, signature, signaturelen);
+        xfree(signature);
+        buffer_free(&signbuf);
+    }
+    connection_send_userauth(ss, username, "publickey", 
+                             buffer_ptr(&authdata), buffer_len(&authdata));
+    // wipe keys from buffer
+    memset(buffer_ptr(&authdata), 0, buffer_len(&authdata));
+    buffer_free(&authdata);
+}
+
+
+static void 
+connection_send_userauth_kbdint(ssh_session_t *ss, char *username)
+{
+    Buffer authdata;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    // authdata is language (empty) and submethods (also empty)
+    buffer_init(&authdata);
+    buffer_put_cstring(&authdata, "");
+    buffer_put_cstring(&authdata, "");
+    connection_send_userauth(ss, username, "keyboard-interactive", 
+                             buffer_ptr(&authdata), buffer_len(&authdata));
+    buffer_free(&authdata);
+}
+
+
+static void 
+connection_send_authmethod_request(ssh_session_t *ss, char *username)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    // To request the list of authentication methods, 
+    // send a USERAUTH_REQUEST with authentication type "none". 
+    // This will either succeed with no auth (USERAUTH_SUCCESS), 
+    // or be rejected with a list of authentication methods supported.
+
+    connection_send_userauth(ss, username, "none", NULL, 0);
+}
+
+
+static void
+connection_send_kbdint_responses(ssh_session_t *ss, char **responses, 
+                                 uint16_t count)
+{
+    uint16_t i;
+    Buffer payload;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    buffer_init(&payload);
+
+    buffer_put_char(&payload, SSH2_MSG_USERAUTH_INFO_RESPONSE);
+    buffer_put_int(&payload, count);
+    for (i = 0; i < count; i++) {
+        buffer_put_cstring(&payload, responses[i]);
+    }
+
+    transport_send_payload(ss, &payload);
+    buffer_free(&payload);
+}
+
+
+static void 
+connection_send_channel_open(ssh_session_t *ss, uint32_t channel, 
+                             uint32_t receiveWindow, uint32_t packetMax)
+{
+    Buffer payload;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    printf("   Opening channel...\r\n");
+
+    buffer_init(&payload);
+    buffer_put_char(&payload, SSH2_MSG_CHANNEL_OPEN);
+    buffer_put_cstring(&payload, "session");
+    buffer_put_int(&payload, channel);
+    buffer_put_int(&payload, receiveWindow); // initial window size
+    buffer_put_int(&payload, packetMax); // packet size
+    transport_send_payload(ss, &payload);
+    buffer_free(&payload);
+    connection_log("connection: sent channel open\r\n");
+}
+
+
+static void 
+connection_send_window_adjust(ssh_session_t *ss, uint32_t channel, 
+                              uint32_t adjustment)
+{
+    // this gets used a lot, so keep a static Buffer
+    static Buffer payload;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (!payload.buf) buffer_init(&payload);
+    buffer_clear(&payload);
+    buffer_put_char(&payload, SSH2_MSG_CHANNEL_WINDOW_ADJUST);
+    buffer_put_int(&payload, channel);
+    buffer_put_int(&payload, adjustment);
+    transport_send_payload(ss, &payload);
+    connection_log("connection: sent window adjust\r\n");
+}
+
+
+static void 
+connection_send_channel_close(ssh_session_t *ss, uint32_t channel)
+{
+    Buffer payload;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    buffer_init(&payload);
+    buffer_put_char(&payload, SSH2_MSG_CHANNEL_CLOSE);
+    buffer_put_int(&payload, channel);
+    transport_send_payload(ss, &payload);
+    buffer_free(&payload);
+    connection_log("connection: sent channel close\r\n");
+}
+
+static void 
+connection_send_global_request_failure(ssh_session_t *ss)
+{
+    Buffer payload;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    buffer_init(&payload);
+    buffer_put_char(&payload, SSH2_MSG_REQUEST_FAILURE);
+    transport_send_payload(ss, &payload);
+    buffer_free(&payload);
+    connection_log("connection: sent global request failure\r\n");
+}
+
+
+static void 
+connection_send_channel_request_failure(ssh_session_t *ss, uint32_t channel)
+{
+    Buffer payload;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    buffer_init(&payload);
+    buffer_put_char(&payload, SSH2_MSG_CHANNEL_FAILURE);
+    buffer_put_int(&payload, channel);
+    transport_send_payload(ss, &payload);
+    buffer_free(&payload);
+    connection_log("connection: sent channel request failure\r\n");
+}
+
+
+// does NOT enforce send window and max packet size
+static void 
+connection_send_channel_data(ssh_session_t *ss, uint32_t channel, 
+                             uint8_t *bytes, uint16_t len)
+{
+    static Buffer payload;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (!payload.buf) buffer_init(&payload);
+    buffer_clear(&payload);
+    buffer_put_char(&payload, SSH2_MSG_CHANNEL_DATA);
+    buffer_put_int(&payload, channel);
+    buffer_put_string(&payload, bytes, len);
+    transport_send_payload(ss, &payload);
+}
+
+
+/***********************************************************************
+ * misc
+ */
+
+
+static connection_state_t
+connection_request_kbdint(ssh_session_t *ss)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    connection_send_userauth_kbdint(ss, ss->username);
+    return CONNECTION_STATE_WAITING_FOR_KBDINT_INFO_REQUEST;
+
+    // kbdint test data
+    /*
+    ss->c.prompt_name = arena_strdup("NAME");
+    ss->c.prompt_instruction = arena_strdup("0 INSTRUCTIONS 0\r\n 0 0 0");
+    ss->c.prompt_list = arena_malloc(sizeof(prompt_t)*3);
+    ss->c.prompt_list[0].msg = arena_strdup("MESSAGE");
+    ss->c.prompt_list[0].echo = 1;
+    ss->c.prompt_list[1].msg = arena_strdup("MESSAGE2");
+    ss->c.prompt_list[1].echo = 0;
+    ss->c.prompt_list[2].msg = arena_strdup("MESSAGE3");
+    ss->c.prompt_list[2].echo = 1;
+    ss->c.prompt_count = 3;
+    ssh_request_kbdint(ss->c.prompt_name, ss->c.prompt_instruction, 
+                       ss->c.prompt_list, ss->c.prompt_count);
+    return CONNECTION_STATE_WAITING_FOR_KBDINT_RESPONSES;
+    */
+}
+
+
+static connection_state_t
+connection_check_next_publickey(ssh_session_t *ss, queue_t *q)
+{
+    Key *k;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    assert (!queue_empty(q));
+
+    ss->c.current_pubkey = (MemHandle)queue_dequeue(q);
+    k = PublicKeyForRecord(MemHandleLock(ss->c.current_pubkey));
+    MemHandleUnlock(ss->c.current_pubkey);
+    if (!k) return 0;
+
+    connection_send_userauth_publickey(ss, ss->username, k, true);
+    return CONNECTION_STATE_WAITING_FOR_PUBKEY_CHECK;
+}
+
+
+static connection_state_t
+connection_get_password(ssh_session_t *ss)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    ss->c.passwordAttempts++;
+
+    if (ss->c.passwordAttempts == 1) {
+        // Look for a saved username and password, but only once
+        // fixme wait for banner?
+        // fixme
+    }
+
+    if (ss->c.passwordAttempts > 3) {
+        // too many password attempts
+        // fixme don't bother enforcing this?
+    }
+
+    // get name and password from GUI
+    // reuse username if known
+    // fixme
+    ssh_request_password(ss->c.passwordAttempts);
+
+    return CONNECTION_STATE_WAITING_FOR_PASSWORD;
+}
+
+
+static connection_state_t
+connection_get_passphrase(ssh_session_t *ss, queue_t *q)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    // get name and password and public key choice from GUI
+    // reuse username if known
+    // fixme
+    ssh_request_passphrase(q);
+
+    return CONNECTION_STATE_WAITING_FOR_PUBKEY_PASSPHRASE;
+}
+
+
+void connection_use_password(ssh_session_t *ss, char *username, char *password)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (ss->c.state == CONNECTION_STATE_WAITING_FOR_PASSWORD) {
+        if (ss->username) arena_free(ss->username);
+        ss->username = arena_strdup(username);
+        connection_send_userauth_password(ss, username, password);
+        ss->c.state = CONNECTION_STATE_WAITING_FOR_PASSWORD_USERAUTH;
+    } else {
+        printf("connection: got password outside waiting-for-password\r\n");
+    }
+}
+
+
+Boolean connection_use_passphrase(ssh_session_t *ss, char *username, char *passphrase, MemHandle pubkey)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (ss->c.state == CONNECTION_STATE_WAITING_FOR_PUBKEY_PASSPHRASE) {
+        Key *priv;
+
+        if (!pubkey) {
+            // user cancel - try something else
+            // clear list of good pubkeys so we finish pubkey attempts
+            while (!queue_empty(ss->c.good_pubkeys)) {
+                queue_dequeue(ss->c.good_pubkeys);
+            }
+            ss->c.state = connection_try_next_userauth(ss);
+            return true;
+        }
+
+        priv = PrivateKeyForRecord(MemHandleLock(pubkey), passphrase);
+        MemHandleUnlock(pubkey);
+
+        if (!priv) return false; // bad passphrase, try again
+
+        if (ss->username) arena_free(ss->username);
+        ss->username = arena_strdup(username);
+
+        connection_send_userauth_publickey(ss, username, priv, false);
+        key_free(priv);
+
+        // remove this pubkey from good_pubkeys
+        // in case server rejects it despite the validity check
+        // If this is the last valid key, pubkey authentication won't continue
+        queue_remove_if_present(ss->c.good_pubkeys, pubkey);
+
+        ss->c.state = CONNECTION_STATE_WAITING_FOR_PUBKEY_USERAUTH;
+        return true;
+    } else {
+        printf("connection: got passphrase outside waiting-for-passphrase\r\n");
+        return false;
+    }
+}
+
+
+void connection_use_kbdint(ssh_session_t *ss, char **responses)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (ss->c.state != CONNECTION_STATE_WAITING_FOR_KBDINT_RESPONSES) {
+        printf("connection: got keyboard-interactive responses outside waiting-for-kbdint\r\n");
+        return;
+    }
+
+    if (responses) {
+        connection_send_kbdint_responses(ss, responses, ss->c.prompt_count);
+        ss->c.state = CONNECTION_STATE_WAITING_FOR_KBDINT_USERAUTH;    
+    } else {
+        // NULL responses means user cancel
+        printf("canceled\r\n");
+        remove_match("keyboard-interactive", ss->c.untriedAuthmethods);
+        ss->c.state = connection_try_next_userauth(ss);
+    }
+
+    kbdint_cleanup(ss);
+}
+
+
+void connection_use_bounds(ssh_session_t *ss, RectangleType bounds, 
+                           int charsWide, int charsHigh)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (ss->c.state == CONNECTION_STATE_RUNNING) {
+        connection_send_window_change(ss, ss->c.remoteChannel, 
+                                      charsWide, charsHigh, 
+                                      bounds.extent.x, bounds.extent.y);
+    } else {
+        // fixme need to send it later? maybe not
+    }
+}
+
+static void connection_increase_receive_window(ssh_session_t *ss)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (ss->c.receiveWindow < RECEIVE_WINDOW_MIN) {
+        uint32_t delta = RECEIVE_WINDOW_MAX - ss->c.receiveWindow;
+        connection_send_window_adjust(ss, ss->c.remoteChannel, delta);
+        ss->c.receiveWindow += delta;
+    }
+}
+
+
+static void connection_handle_typed_data(ssh_session_t *ss, uint32_t type, 
+                                         uint8_t *data, uint32_t datalen, 
+                                         int closing)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (ss->c.receiveWindow < datalen) {
+        printf("connection: receive window full\r\n");
+        return; // ignore data
+    }
+    ss->c.receiveWindow -= datalen;
+    if (ss->c.receiveWindow < RECEIVE_WINDOW_MIN  &&  !closing) {
+        connection_increase_receive_window(ss);
+    }
+
+    if (type == 0  ||  type == 1) {
+        // fixme handle stderr differently?
+        ssh_receive_bytes(ss, data, datalen);
+    } else {
+        printf("connection: got %d bytes of data typed %d\r\n", datalen, type);
+    }
+}
+
+
+
+/***********************************************************************
+ * incoming message handlers
+ */
+
+static connection_state_t 
+connection_handle_unexpected_message(ssh_session_t *ss, 
+                                     uint8_t msg, Buffer *packet)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (msg == SSH2_MSG_GLOBAL_REQUEST) {
+        // all global requests are refused
+        uint16_t len;
+        uint8_t *request;
+        uint8_t want_reply;
+        request = buffer_get_string(packet, &len);
+        want_reply = buffer_get_char(packet);
+        // do NOT require empty - there might be unknown request-specific data
+        printf("connection (state %d): refused global request '%s'\r\n", 
+                   ss->c.state, request);
+        arena_free(request);
+        if (want_reply) {
+            connection_send_global_request_failure(ss);
+        }
+        return ss->c.state;
+    } else if (msg == SSH2_MSG_CHANNEL_REQUEST) {
+        // all channel requests are currently refused with a printf
+        // EXCEPT: keepalive@openssh.com and exit-status are silently refused
+        // fixme requests that may be desirable (would implement elsewhere):
+        // xon-xoff, signal, exit-status, exit-signal, keepalive@openssh.com
+        uint16_t len;
+        uint32_t channel;
+        uint8_t *request;
+        uint8_t want_reply;
+        channel = buffer_get_int(packet);
+        request = buffer_get_string(packet, &len);
+        want_reply = buffer_get_char(packet);
+        // do NOT require empty - there might be unknown request-specific data
+        // Don't print keepalives or exit-status
+        if (0 != StrCompare(request, "keepalive@openssh.com")  &&  
+            0 != StrCompare(request, "exit-status"))
+        {
+            printf("connection (state %d): refused channel request '%s'\r\n",
+                   ss->c.state, request);
+        }
+        arena_free(request);
+        if (ss->c.localChannel == 0  ||  channel != ss->c.localChannel) {
+            // wrong channel or no channel - die
+            ssh_kill(ss);
+            return ss->c.state;
+        }
+        if (want_reply) {
+            connection_send_channel_request_failure(ss, ss->c.remoteChannel);
+        }
+        return ss->c.state;
+    } else {
+        // fixme die?
+        // fixme are there any other messages?
+        // fixme send UNIMPLEMENTED?
+        printf("connection (state %d): ignored unknown message %d\r\n", 
+                   ss->c.state, msg);
+        return ss->c.state;
+    }
+}
+
+
+static connection_state_t 
+connection_handle_userauth_service_accept(ssh_session_t *ss, Buffer *packet)
+{
+    uint16_t len;
+    char *service = buffer_get_string(packet, &len);
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (len != strlen("ssh-userauth")  ||  
+        0 != memcmp(service, "ssh-userauth", len)) 
+    {
+        printf("connection: service-accept for wrong service '%s'\r\n",
+                   service);
+        arena_free(service);
+        ssh_kill(ss);
+        return ss->c.state;
+    }
+
+    arena_free(service);
+    buffer_require_empty(packet);
+
+    printf("   Authenticating (none) ... ");
+
+    connection_send_authmethod_request(ss, ss->username);
+    return CONNECTION_STATE_WAITING_FOR_NONE_USERAUTH;
+}
+
+
+static connection_state_t 
+connection_handle_banner(ssh_session_t *ss, Buffer *packet)
+{
+    uint16_t len;
+    char *msg;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    msg = buffer_get_string(packet, &len);
+    arena_free(buffer_get_string(packet, &len)); // ignore language
+    buffer_require_empty(packet);
+
+    Banner(msg);
+
+    arena_free(msg);
+    return ss->c.state;
+}
+
+
+static connection_state_t 
+connection_handle_userauth_success(ssh_session_t *ss, Buffer *packet)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    buffer_require_empty(packet);
+
+    printf("succeeded\r\n"); // terminate "Authenticating..." line
+
+    ss->c.localChannel = 42;
+    ss->c.receiveWindow = RECEIVE_WINDOW_MAX;
+    
+    connection_send_channel_open(ss, ss->c.localChannel, 
+                                 ss->c.receiveWindow, DATA_MAX);
+
+    return CONNECTION_STATE_WAITING_FOR_CHANNEL_OPEN;    
+}
+
+
+static connection_state_t
+connection_try_next_userauth(ssh_session_t *ss)
+{
+    connection_state_t result = 0;
+    char *authmethod_name = NULL;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    // Choose an untried authmethod and try it.
+    // publickey is only tried once
+    // kbd-interactive is tried repeatedly until the user or server gives up
+    // password is tried repeatedly until the user or server gives up
+
+    while (result == 0) {
+        authmethod_name = match_list(ss->c.untriedAuthmethods, 
+                                     ss->c.usableAuthmethods, NULL);
+        if (!authmethod_name) break;
+
+        connection_log("authmethod %s", authmethod_name);
+
+        if (0 == strcmp(authmethod_name, "publickey")) {
+            
+            // Public Key Authentication Process
+            // 1: send public key acceptibility query for passphrase-less keys
+            // 2: send auth attempts for acceptable passphrase-less keys
+            // 3: send public key acceptibility query for passphrase-ful keys
+            // 4: query user for passphrase-ful key and passphrase
+            // 5: send auth attempt for passphrase-ful key
+            // 1 and 2 are performed simultaneously (if an acceptable key is 
+            //   found, immediately try to auth with it)
+            // 4 and 5 are repeated until user or server gives up
+
+            switch (ss->c.pubkey_state) {
+            case PUBKEY_STARTING:
+                printf("   Authenticating (publickey) ... ");
+                ss->c.pubkey_state = PUBKEY_QUERY_PHRASELESS;
+                // FALL-THROUGH to PUBKEY_QUERY_PHRASELESS
+            case PUBKEY_QUERY_PHRASELESS:
+                // steps 1 and 2
+                if (!ss->c.phraseless_pubkeys) {
+                    ss->c.phraseless_pubkeys = PhraselessPublicKeys();
+                }
+                if (!queue_empty(ss->c.phraseless_pubkeys)) {
+                    result = connection_check_next_publickey(ss, ss->c.phraseless_pubkeys);
+                    break;
+                } else {
+                    queue_free(ss->c.phraseless_pubkeys);
+                    ss->c.phraseless_pubkeys = NULL;
+                    ss->c.pubkey_state = PUBKEY_QUERY_PHRASEFUL;
+                }
+                // FALL-THROUGH to PUBKEY_QUERY_PHRASEFUL
+            case PUBKEY_QUERY_PHRASEFUL:
+                // step 3
+                if (!ss->c.phraseful_pubkeys) {
+                    ss->c.phraseful_pubkeys = PhrasefulPublicKeys();
+                }
+                if (!ss->c.good_pubkeys) {
+                    ss->c.good_pubkeys = queue_new();
+                }
+                if (!queue_empty(ss->c.phraseful_pubkeys)) {
+                    result = connection_check_next_publickey(ss, ss->c.phraseful_pubkeys);
+                    break;
+                } else {
+                    queue_free(ss->c.phraseful_pubkeys);
+                    ss->c.phraseful_pubkeys = NULL;
+                    ss->c.pubkey_state = PUBKEY_GET_PASSPHRASE;
+                }
+                // FALL-THROUGH to PUBKEY_GET_PASSPHRASE
+            case PUBKEY_GET_PASSPHRASE:
+                // step 4 and 5
+                if (!queue_empty(ss->c.good_pubkeys)) {
+                    result = connection_get_passphrase(ss, ss->c.good_pubkeys);
+                    break;
+                } else {
+                    queue_free(ss->c.good_pubkeys);
+                    ss->c.good_pubkeys = NULL;
+                    ss->c.pubkey_state = PUBKEY_DONE;
+                }
+                // FALL-THROUGH to PUBKEY_DONE
+            case PUBKEY_DONE:
+                // all steps completed with no successful auth - don't try more
+                remove_match("publickey", ss->c.untriedAuthmethods);
+                // terminate previous "Authenticating ..." line
+                printf("failed\r\n");
+                break;
+            }
+        }
+        else if (0 == strcmp(authmethod_name, "keyboard-interactive")) {
+            printf("   Authenticating (keyboard-interactive) ... ");
+            result = connection_request_kbdint(ss);
+        }
+        else if (0 == strcmp(authmethod_name, "password")) {
+            // Try password authentication
+            // Password auth is always considered "untried"; don't remove it.
+            printf("   Authenticating (password) ... ");
+            
+            result = connection_get_password(ss);
+        }
+
+        arena_free(authmethod_name);
+    }
+
+    if (result == 0) {
+        // No acceptable auth methods left. Bail.        
+        printf("userauth: no more untried authmethods available (server offered '%s')\r\n", ss->c.usableAuthmethods);
+        ssh_kill(ss);
+        result = ss->c.state;
+    }
+
+    return result;
+}
+
+static connection_state_t 
+connection_handle_userauth_failure(ssh_session_t *ss, Buffer *packet)
+{
+    uint16_t len;
+    uint8_t partialSuccess;
+    connection_state_t result = 0;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (ss->c.usableAuthmethods) arena_free(ss->c.usableAuthmethods);
+    ss->c.usableAuthmethods = buffer_get_string(packet, &len);
+    partialSuccess = buffer_get_char(packet);
+    buffer_require_empty(packet);
+
+    if (partialSuccess) {
+        // Previous authentication succeeded, but more are required
+        printf("succeeded\r\n"); // terminate previous "Authenticating..." line
+        printf("   More authentication required.\r\n");
+        reset_untried_authmethods(ss);
+    } else {
+        // Previous authentication failed completely.
+        printf("failed\r\n");    // terminate previous "Authenticating..." line
+    }
+
+    result = connection_try_next_userauth(ss);
+
+ done:
+    return result;
+}
+
+
+static connection_state_t
+connection_handle_good_publickey(ssh_session_t *ss, Buffer *packet)
+{
+    // fixme verify good packet
+    // fixme verify that returned results match the key
+    connection_state_t result;
+    char *p;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    p = MemHandleLock(ss->c.current_pubkey);
+    if (*p == 0) {
+        // not encrypted - send auth attempt with this key
+        Key *priv = PrivateKeyForRecord(p, "");
+        MemHandleUnlock(ss->c.current_pubkey);
+        ss->c.current_pubkey = NULL;
+
+        if (priv) {
+            connection_send_userauth_publickey(ss, ss->username, priv, false);
+            result = CONNECTION_STATE_WAITING_FOR_PUBKEY_USERAUTH;
+            key_free(priv);
+        } else {
+            // bogus key - try something else
+            printf("bogus publickey! ");
+            result = connection_try_next_userauth(ss);
+        }
+    } else {
+        // encrypted - keep this key and try to validate more keys
+        MemHandleUnlock(ss->c.current_pubkey);
+        queue_enqueue(ss->c.good_pubkeys, ss->c.current_pubkey);
+        ss->c.current_pubkey = NULL;
+
+        result = connection_try_next_userauth(ss);
+    }
+
+    // clean up
+    return result;
+}
+
+
+static connection_state_t
+connection_handle_bad_publickey(ssh_session_t *ss, Buffer *packet)
+{
+    uint16_t len;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    // server rejected this public key - try something else
+    if (ss->c.pubkey_state == PUBKEY_GET_PASSPHRASE) {
+        // passphraseful key rejected by server - tell user
+        FrmCustomAlert(AlertFormID, "Public key rejected by server.", " "," ");
+    }
+
+    // server might be refusing publickey auth now
+    if (ss->c.usableAuthmethods) arena_free(ss->c.usableAuthmethods);
+    ss->c.usableAuthmethods = buffer_get_string(packet, &len);
+    buffer_get_char(packet); // partial success (ignore here)
+    buffer_require_empty(packet);
+
+    ss->c.current_pubkey = NULL;
+    return connection_try_next_userauth(ss);
+}
+
+
+static connection_state_t
+connection_handle_kbdint_info_request(ssh_session_t *ss, Buffer *packet)
+{
+    uint16_t i;
+    uint16_t len;
+    uint32_t count32;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    ss->c.prompt_name = buffer_get_string(packet, &len);
+    ss->c.prompt_instruction = buffer_get_string(packet, &len);
+    arena_free(buffer_get_string(packet, &len)); // language
+    count32 = buffer_get_int(packet);
+    if (count32 >= 10) fatal("too many keyboard-interactive prompts");
+    ss->c.prompt_count = count32;
+
+    ss->c.prompt_list = arena_calloc(ss->c.prompt_count * sizeof(prompt_t));
+
+    for (i = 0; i < ss->c.prompt_count; i++) {
+        ss->c.prompt_list[i].msg = buffer_get_string(packet, &len);
+        ss->c.prompt_list[i].echo = buffer_get_char(packet);
+    }
+
+    buffer_require_empty(packet);
+
+    if (ss->c.prompt_count == 0  &&  strlen(ss->c.prompt_name) == 0  &&  
+        strlen(ss->c.prompt_instruction) == 0) 
+    {
+        // completely empty info request - don't show user anything
+        connection_send_kbdint_responses(ss, NULL, 0);
+        kbdint_cleanup(ss);
+        return CONNECTION_STATE_WAITING_FOR_KBDINT_USERAUTH;
+    } else {
+        // ordinary request - show prompts to user, wait for user response
+        ssh_request_kbdint(ss->c.prompt_name, ss->c.prompt_instruction,
+                           ss->c.prompt_list, ss->c.prompt_count);
+        return CONNECTION_STATE_WAITING_FOR_KBDINT_RESPONSES;
+    }
+}
+
+
+static connection_state_t
+connection_handle_kbdint_refused(ssh_session_t *ss, Buffer *packet)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    // server refused to play along - try something else
+    remove_match("keyboard-interactive", ss->c.untriedAuthmethods);
+    kbdint_cleanup(ss);
+    return connection_handle_userauth_failure(ss, packet);
+}
+
+
+static connection_state_t 
+connection_handle_password_change(ssh_session_t *ss, Buffer *packet)
+{
+    // fixme
+    /*
+    uint16_t promptLen, languageLen;
+    uint8_t *prompt = buffer_get_string(packet, &promptLen);
+    uint8_t *language = buffer_get_string(packet, &languageLen);
+    arena_free(language);
+    buffer_require_empty(packet);
+    connection_get_new_password(ss, prompt, promptLen);
+    arena_free(prompt);
+    return CONNECTION_STATE_WAITING_FOR_NEW_PASSWORD;
+    */
+    connection_log(__PRETTY_FUNCTION__);
+
+    printf("connection: password change unimplemented\r\n");
+    return ss->c.state;
+}
+
+
+static connection_state_t 
+connection_handle_channel_open(ssh_session_t *ss, Buffer *packet)
+{
+    uint32_t recipientChannel;
+    uint32_t senderChannel;
+    uint32_t windowSize;
+    uint32_t packetSize;
+    
+    connection_log(__PRETTY_FUNCTION__);
+
+    recipientChannel = buffer_get_int(packet);
+    if (recipientChannel != ss->c.localChannel) {
+        printf("connection: channel-open-confirmation had unexpected recipient channel (wanted %d, got %d)\r\n", ss->c.localChannel, recipientChannel);
+        ssh_kill(ss);
+        return ss->c.state;
+    }
+
+    senderChannel = buffer_get_int(packet);
+    windowSize = buffer_get_int(packet);
+    packetSize = buffer_get_int(packet);
+    buffer_require_empty(packet);
+
+    ss->c.remoteChannel = senderChannel;
+    ss->c.sendWindow = windowSize;
+    ss->c.sendMaxPacket = packetSize;
+    ss->c.channelOpen = 1;
+
+    connection_send_pty_request(ss, ss->c.remoteChannel);
+    return CONNECTION_STATE_WAITING_FOR_PTY;
+}
+
+
+static connection_state_t 
+connection_handle_channel_open_failure(ssh_session_t *ss, Buffer *packet)
+{
+    uint32_t channel;
+    uint32_t reasonCode;
+    uint16_t len;
+    uint8_t *reasonString;
+    uint16_t languageLen;
+    uint8_t *languageString;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    channel = buffer_get_int(packet);
+    // don't bother verifying channel - we're about to die anyway
+
+    reasonCode = buffer_get_int(packet);
+    reasonString = buffer_get_string(packet, &len);
+    languageString = buffer_get_string(packet, &languageLen);
+    // don't bother requiring empty packet - we're about to die anyway
+
+    printf("connection: channel-open-failure because %d '%s'\r\n", 
+               reasonCode, reasonString);
+    arena_free(reasonString);
+    arena_free(languageString);
+
+    ssh_kill(ss);
+    return ss->c.state;
+}
+
+
+static connection_state_t 
+connection_handle_pty_success(ssh_session_t *ss, Buffer *packet)
+{
+    uint32_t channel = buffer_get_int(packet);
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (channel != ss->c.localChannel) {
+        printf("connection: pty success on wrong channel (wanted %d, got %d)\r\n", ss->c.localChannel, channel);
+        ssh_kill(ss);
+        return ss->c.state;
+    }
+
+    buffer_require_empty(packet);
+
+    connection_send_shell_request(ss, ss->c.remoteChannel);
+    return CONNECTION_STATE_WAITING_FOR_SHELL;
+}
+
+
+static connection_state_t 
+connection_handle_pty_failure(ssh_session_t *ss, Buffer *packet)
+{
+    // don't bother verifying channel - we're about to die anyway
+    // don't bother requiring empty packet - we're about to die anyway
+    connection_log(__PRETTY_FUNCTION__);
+
+    printf("connection: pty failure\r\n");
+    ssh_kill(ss);
+    return ss->c.state;
+}
+
+
+static connection_state_t 
+connection_handle_shell_success(ssh_session_t *ss, Buffer *packet)
+{
+    uint32_t channel = buffer_get_int(packet);
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (channel != ss->c.localChannel) {
+        printf("connection: shell success on wrong channel (wanted %d, got %d)\r\n", 
+               ss->c.localChannel, channel);
+        ssh_kill(ss);
+        return ss->c.state;
+    }
+
+    buffer_require_empty(packet);
+
+    // nothing to send
+    // fixme wire up tty if needed
+
+    printf("Connected to host '%s'.\r\n", ss->s.hostname);
+
+    return CONNECTION_STATE_RUNNING;
+}
+
+
+static connection_state_t 
+connection_handle_shell_failure(ssh_session_t *ss, Buffer *packet)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    // don't bother verifying channel - we're about to die anyway
+    // don't bother requiring empty packet - we're about to die anyway
+    printf("connection: shell failure\r\n");
+    ssh_kill(ss);
+    return ss->c.state;
+}
+
+
+static connection_state_t
+connection_handle_window_adjust(ssh_session_t *ss, Buffer *packet)
+{
+    uint32_t channel;
+    uint32_t delta;
+    
+    connection_log(__PRETTY_FUNCTION__);
+
+    channel = buffer_get_int(packet);
+    if (channel != ss->c.localChannel) {
+        printf("connection: window adjust got wrong channel (wanted %d, got %d)\r\n", ss->c.localChannel, channel);
+        ssh_kill(ss);
+        return ss->c.state;
+    }
+
+    delta = buffer_get_int(packet);
+    buffer_require_empty(packet);
+    ss->c.sendWindow += delta;
+    return ss->c.state;
+}
+
+
+static connection_state_t
+connection_handle_channel_close(ssh_session_t *ss, Buffer *packet)
+{
+    uint32_t channel;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    channel = buffer_get_int(packet);
+    if (channel != ss->c.localChannel) {
+        printf("connection: close got wrong channel (wanted %d, got %d)\r\n", ss->c.localChannel, channel);
+        ssh_kill(ss);
+        return ss->c.state;
+    }
+    buffer_require_empty(packet);
+
+    ss->c.remoteCloseReceived = 1;
+    ssh_close(ss);
+    return ss->c.state;
+}
+
+
+static connection_state_t
+connection_handle_data(ssh_session_t *ss, Buffer *packet, int closing)
+{
+    uint32_t channel;
+    uint8_t *data;
+    uint16_t len;
+
+    connection_log("conn handle data: 0x%x (len 0x%x)", packet, packet->alloc);
+
+    channel = buffer_get_int(packet);
+    if (channel != ss->c.localChannel) {
+        printf("connection: data got wrong channel (wanted %d, got %d)\r\n", ss->c.localChannel, channel);
+        ssh_kill(ss);
+        return ss->c.state;
+    }
+    data = buffer_get_string(packet, &len);
+    buffer_require_empty(packet);
+    connection_handle_typed_data(ss, 0, data, len, closing);
+    arena_free(data);
+    return ss->c.state;
+}
+
+
+static connection_state_t 
+connection_handle_extended_data(ssh_session_t *ss, Buffer *packet, int closing)
+{
+    uint32_t channel;
+    uint32_t type;
+    uint8_t *data;
+    uint16_t len;
+
+    connection_log(__PRETTY_FUNCTION__);
+
+    channel = buffer_get_int(packet);
+    if (channel != ss->c.localChannel) {
+        printf("connection: extended data got wrong channel (wanted %d, got %d)\r\n", ss->c.localChannel, channel);
+        ssh_kill(ss);
+        return ss->c.state;
+    }
+    type = buffer_get_int(packet);
+    data = buffer_get_string(packet, &len);
+    buffer_require_empty(packet);
+    connection_handle_typed_data(ss, type, data, len, closing);
+    arena_free(data);
+    return ss->c.state;
+}
+
+
+
+
+
+
+
+
+/***********************************************************************
+ * state handlers
+ */
+
+
+// fixme move to transport
+static connection_state_t 
+connection_state_waiting_for_userauth_service(ssh_session_t *ss, 
+                                              uint8_t msg, 
+                                              Buffer *packet)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (msg == SSH2_MSG_SERVICE_ACCEPT) {
+        return connection_handle_userauth_service_accept(ss, packet);
+    } else {
+        return connection_handle_unexpected_message(ss, msg, packet);
+    }
+}
+
+
+static connection_state_t 
+connection_state_waiting_for_password(ssh_session_t *ss, 
+                                      uint8_t msg, Buffer *packet)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    // not expecting anything in particular - GUI triggers state change
+    if (msg == SSH2_MSG_USERAUTH_BANNER) {
+        return connection_handle_banner(ss, packet);
+    } else {
+        return connection_handle_unexpected_message(ss, msg, packet);
+    }
+}
+
+
+// waiting for authentication after sending no credentials
+static connection_state_t
+connection_state_waiting_for_none_userauth(ssh_session_t *ss, 
+                                           uint8_t msg, Buffer *packet)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (msg == SSH2_MSG_USERAUTH_SUCCESS) {
+        return connection_handle_userauth_success(ss, packet);
+    } else if (msg == SSH2_MSG_USERAUTH_FAILURE) {
+        return connection_handle_userauth_failure(ss, packet);
+    } else if (msg == SSH2_MSG_USERAUTH_BANNER) {
+        return connection_handle_banner(ss, packet);
+    } else {
+        return connection_handle_unexpected_message(ss, msg, packet);
+    }
+}
+
+
+// waiting for userauth after sending a password
+// Server may request password change.
+static connection_state_t
+connection_state_waiting_for_password_userauth(ssh_session_t *ss, 
+                                               uint8_t msg, Buffer *packet)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (msg == SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ) {
+        return connection_handle_password_change(ss, packet);
+    } else {
+        return connection_state_waiting_for_none_userauth(ss, msg, packet);
+    }
+}
+
+
+// waiting for userauth after sending a public key
+static connection_state_t
+connection_state_waiting_for_pubkey_userauth(ssh_session_t *ss, 
+                                             uint8_t msg, Buffer *packet)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    return connection_state_waiting_for_none_userauth(ss, msg, packet);
+}
+
+
+// waiting for userauth after sending keyboard-interactive responses
+// Server may provide more keyboard-interactive prompts.
+static connection_state_t
+connection_state_waiting_for_kbdint_userauth(ssh_session_t *ss, 
+                                             uint8_t msg, Buffer *packet)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (msg == SSH2_MSG_USERAUTH_INFO_REQUEST) {
+        return connection_handle_kbdint_info_request(ss, packet);
+    } else {
+        return connection_state_waiting_for_none_userauth(ss, msg, packet);
+    }
+}
+
+
+static connection_state_t
+connection_state_waiting_for_pubkey_check(ssh_session_t *ss, 
+                                          uint8_t msg, Buffer *packet)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (msg == SSH2_MSG_USERAUTH_PK_OK) {
+        return connection_handle_good_publickey(ss, packet);
+    } else if (msg == SSH2_MSG_USERAUTH_FAILURE) {
+        return connection_handle_bad_publickey(ss, packet);
+    } else if (msg == SSH2_MSG_USERAUTH_BANNER) {
+        return connection_handle_banner(ss, packet);
+    } else {
+        return connection_handle_unexpected_message(ss, msg, packet);
+    }
+}
+
+
+static connection_state_t 
+connection_state_waiting_for_pubkey_passphrase(ssh_session_t *ss, 
+                                               uint8_t msg, Buffer *packet)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    // not expecting anything in particular - GUI triggers state change
+    if (msg == SSH2_MSG_USERAUTH_BANNER) {
+        return connection_handle_banner(ss, packet);
+    } else {
+        return connection_handle_unexpected_message(ss, msg, packet);
+    }
+}
+
+
+
+static connection_state_t
+connection_state_waiting_for_kbdint_info_request(ssh_session_t *ss, 
+                                                 uint8_t msg, Buffer *packet)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (msg == SSH2_MSG_USERAUTH_INFO_REQUEST) {
+        return connection_handle_kbdint_info_request(ss, packet);
+    } else if (msg == SSH2_MSG_USERAUTH_FAILURE) {
+        return connection_handle_kbdint_refused(ss, packet);
+    } else if (msg == SSH2_MSG_USERAUTH_BANNER) {
+        return connection_handle_banner(ss, packet);
+    } else {
+        return connection_handle_unexpected_message(ss, msg, packet);
+    }
+}
+
+
+static connection_state_t
+connection_state_waiting_for_channel_open(ssh_session_t *ss, 
+                                          uint8_t msg, Buffer *packet)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (msg == SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
+        return connection_handle_channel_open(ss, packet);
+    } else if (msg == SSH2_MSG_CHANNEL_OPEN_FAILURE) {
+        return connection_handle_channel_open_failure(ss, packet);
+    } else {
+        return connection_handle_unexpected_message(ss, msg, packet);
+    }
+}
+
+
+static connection_state_t 
+connection_state_waiting_for_pty(ssh_session_t *ss, 
+                                 uint8_t msg, Buffer *packet)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (msg == SSH2_MSG_CHANNEL_SUCCESS) {
+        return connection_handle_pty_success(ss, packet);
+    } else if (msg == SSH2_MSG_CHANNEL_FAILURE) {
+        return connection_handle_pty_failure(ss, packet);
+    } else if (msg == SSH2_MSG_CHANNEL_WINDOW_ADJUST) {
+        return connection_handle_window_adjust(ss, packet);
+    } else if (msg == SSH2_MSG_CHANNEL_CLOSE) {
+        return connection_handle_channel_close(ss, packet);
+    } else {
+        return connection_handle_unexpected_message(ss, msg, packet);
+    }
+}
+
+
+static connection_state_t 
+connection_state_waiting_for_shell(ssh_session_t *ss, 
+                                   uint8_t msg, Buffer *packet)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (msg == SSH2_MSG_CHANNEL_SUCCESS) {
+        return connection_handle_shell_success(ss, packet);
+    } else if (msg == SSH2_MSG_CHANNEL_FAILURE) {
+        return connection_handle_shell_failure(ss, packet);
+    } else if (msg == SSH2_MSG_CHANNEL_WINDOW_ADJUST) {
+        return connection_handle_window_adjust(ss, packet);
+    } else if (msg == SSH2_MSG_CHANNEL_CLOSE) {
+        return connection_handle_channel_close(ss, packet);
+    } else {
+        return connection_handle_unexpected_message(ss, msg, packet);
+    }
+}
+
+
+static connection_state_t 
+connection_state_running(ssh_session_t *ss, 
+                         uint8_t msg, Buffer *packet)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (msg == SSH2_MSG_CHANNEL_DATA) {
+        return connection_handle_data(ss, packet, 0);
+    } else if (msg == SSH2_MSG_CHANNEL_EXTENDED_DATA) {
+        return connection_handle_extended_data(ss, packet, 0);
+    } else if (msg == SSH2_MSG_CHANNEL_WINDOW_ADJUST) {
+        return connection_handle_window_adjust(ss, packet);
+    } else if (msg == SSH2_MSG_CHANNEL_CLOSE) {
+        return connection_handle_channel_close(ss, packet);
+    } else if (msg == SSH2_MSG_CHANNEL_EOF) {
+        // silently ignore (fixme correct?)
+        return ss->c.state;
+    } else {
+        return connection_handle_unexpected_message(ss, msg, packet);
+    }
+}
+
+
+
+static connection_state_t 
+connection_state_closing(ssh_session_t *ss, 
+                         uint8_t msg, Buffer *packet)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (msg == SSH2_MSG_CHANNEL_DATA) {
+        return connection_handle_data(ss, packet, 1);
+    } else if (msg == SSH2_MSG_CHANNEL_EXTENDED_DATA) {
+        return connection_handle_extended_data(ss, packet, 1);
+    } else if (msg == SSH2_MSG_CHANNEL_WINDOW_ADJUST) {
+        // ignore window adjust - we're sending no more data
+        return ss->c.state;
+    } else if (msg == SSH2_MSG_CHANNEL_CLOSE) {
+        return connection_handle_channel_close(ss, packet);
+    } else {
+        return connection_handle_unexpected_message(ss, msg, packet);
+    }
+}
+
+
+static connection_state_t 
+connection_state_closed(ssh_session_t *ss, 
+                        uint8_t msg, Buffer *packet)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    // shouldn't happen
+    printf("connection: packet sent to connection_state_closed!\r\n");
+    return connection_handle_unexpected_message(ss, msg, packet);
+}
+
+/***********************************************************************
+ * incoming packet handler 
+ */
+
+
+// msg is gone from packet
+void connection_receive_packet(ssh_session_t *ss, uint8_t msg, Buffer *packet)
+{
+    connection_state_t s = ss->c.state;
+
+    connection_log("conn (state %d): received msg %d\r\n", ss->c.state, msg);
+
+    switch (ss->c.state) {
+    case CONNECTION_STATE_WAITING_FOR_USERAUTH_SERVICE:
+        s = connection_state_waiting_for_userauth_service(ss, msg, packet);
+        break;
+    case CONNECTION_STATE_WAITING_FOR_PASSWORD:
+    case CONNECTION_STATE_WAITING_FOR_NEW_PASSWORD:
+        s = connection_state_waiting_for_password(ss, msg, packet);
+        break;
+    case CONNECTION_STATE_WAITING_FOR_NONE_USERAUTH:
+        s = connection_state_waiting_for_none_userauth(ss, msg, packet);
+        break;
+    case CONNECTION_STATE_WAITING_FOR_PASSWORD_USERAUTH:
+        s = connection_state_waiting_for_password_userauth(ss, msg, packet);
+        break;
+    case CONNECTION_STATE_WAITING_FOR_PUBKEY_USERAUTH:
+        s = connection_state_waiting_for_pubkey_userauth(ss, msg, packet);
+        break;
+    case CONNECTION_STATE_WAITING_FOR_KBDINT_USERAUTH:
+        s = connection_state_waiting_for_kbdint_userauth(ss, msg, packet);
+        break;
+    case CONNECTION_STATE_WAITING_FOR_PUBKEY_CHECK:
+        s = connection_state_waiting_for_pubkey_check(ss, msg, packet);
+        break;
+    case CONNECTION_STATE_WAITING_FOR_PUBKEY_PASSPHRASE:
+        s = connection_state_waiting_for_pubkey_passphrase(ss, msg, packet);
+        break;
+    case CONNECTION_STATE_WAITING_FOR_KBDINT_INFO_REQUEST:
+        s = connection_state_waiting_for_kbdint_info_request(ss, msg, packet);
+        break;
+
+    case CONNECTION_STATE_WAITING_FOR_CHANNEL_OPEN:
+        s = connection_state_waiting_for_channel_open(ss, msg, packet);
+        break;
+    case CONNECTION_STATE_WAITING_FOR_PTY:
+        s = connection_state_waiting_for_pty(ss, msg, packet);
+        break;
+    case CONNECTION_STATE_WAITING_FOR_SHELL:
+        s = connection_state_waiting_for_shell(ss, msg, packet);
+        break;
+    case CONNECTION_STATE_RUNNING:
+        s = connection_state_running(ss, msg, packet);
+        break;
+    case CONNECTION_STATE_CLOSING:
+        s = connection_state_closing(ss, msg, packet);
+        break;
+    case CONNECTION_STATE_CLOSED:
+        s = connection_state_closed(ss, msg, packet);
+        break;
+
+    default:
+        printf("connection: BUSTED\r\n");
+        break;
+    }
+
+    ss->c.state = s;
+}
+
+
+void connection_send_data(ssh_session_t *ss, uint8_t *bytes, uint16_t len)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (ss->c.state == CONNECTION_STATE_RUNNING) {
+        // fixme enforce packet sizes and send window
+        connection_send_channel_data(ss, ss->c.remoteChannel, bytes, len);
+    }
+}
+
+
+/***********************************************************************
+ * startup and shutdown 
+ */
+
+static void reset_untried_authmethods(ssh_session_t *ss)
+{
+    char *auths = arena_calloc(1+strlen("publickey,")+strlen("keyboard-interactive,")+strlen("password,"));
+    if (PrefsGetInt(prefAuthPublicKey, 1)) strcat(auths, "publickey,");
+    if (PrefsGetInt(prefAuthKbdInt, 1)) strcat(auths, "keyboard-interactive,");
+    if (PrefsGetInt(prefAuthPassword, 1)) strcat(auths, "password,");
+    // use password if nothing is specified
+    if (strlen(auths) == 0) strcat(auths, "password,"); 
+    auths[strlen(auths)-1] = '\0'; // squish trailing comma
+    
+    if (ss->c.untriedAuthmethods) arena_free(ss->c.untriedAuthmethods);
+    ss->c.untriedAuthmethods = auths;
+}
+
+
+void connection_start(ssh_session_t *ss)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (ss->c.state == CONNECTION_STATE_STARTING) {
+        reset_untried_authmethods(ss);
+
+        printf("Logging in to host '%s'\r\n", ss->s.hostname);
+        connection_send_service_request(ss, "ssh-userauth");
+        ss->c.state = CONNECTION_STATE_WAITING_FOR_USERAUTH_SERVICE;
+    }
+}
+
+
+static void kbdint_cleanup(ssh_session_t *ss)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (ss->c.prompt_name) {
+        arena_free(ss->c.prompt_name);
+        ss->c.prompt_name = NULL;
+    }
+    if (ss->c.prompt_instruction) {
+        arena_free(ss->c.prompt_instruction);
+        ss->c.prompt_instruction = NULL;
+    }
+    if (ss->c.prompt_list) {
+        arena_free(ss->c.prompt_list);
+        ss->c.prompt_list = NULL;
+    }
+    ss->c.prompt_count = 0;
+}
+
+
+static void connection_cleanup(ssh_session_t *ss)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    kbdint_cleanup(ss);
+    if (ss->c.untriedAuthmethods) arena_free(ss->c.untriedAuthmethods);
+    if (ss->c.usableAuthmethods) arena_free(ss->c.usableAuthmethods);
+    queue_free(ss->c.phraseful_pubkeys);
+    queue_free(ss->c.phraseless_pubkeys);
+    queue_free(ss->c.good_pubkeys);
+    memset(&ss->c, 0, sizeof(ss->c));
+    ss->c.state = CONNECTION_STATE_CLOSED;
+}
+
+
+void connection_kill(ssh_session_t *ss)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (ss->c.state != CONNECTION_STATE_CLOSED) {
+        connection_cleanup(ss);
+    }
+}
+
+
+// clean shutdown
+// send CHANNEL_CLOSE and wait for remote, if necessary
+void connection_close(ssh_session_t *ss)
+{
+    connection_log(__PRETTY_FUNCTION__);
+
+    if (ss->c.state != CONNECTION_STATE_CLOSED) {
+        if (! ss->c.channelOpen) {
+            // channel not open - no two-way handshake needed
+            connection_kill(ss);
+        } else {
+            // handle two-way channel close
+            if (!ss->c.localCloseSent) {
+                // tell remote that we want to close
+                connection_send_channel_close(ss, ss->c.remoteChannel);
+                ss->c.localCloseSent = 1;
+            }
+            if (!ss->c.remoteCloseReceived) {
+                // continue processing packets until remote's channel close arrives
+                ss->c.state = CONNECTION_STATE_CLOSING;
+            } 
+            if (ss->c.localCloseSent  &&  ss->c.remoteCloseReceived) {
+                // two-way handshake done - really close
+                ss->c.channelOpen = 0;
+                ss->c.localCloseSent = 0;
+                ss->c.remoteCloseReceived = 0;
+                connection_kill(ss);
+            }
+        }
+    }
+}
+
+
+int connection_is_open(ssh_session_t *ss) {
+    connection_log(__PRETTY_FUNCTION__);
+
+    return (ss->c.state != CONNECTION_STATE_STARTING  &&  
+            ss->c.state != CONNECTION_STATE_CLOSING  &&  
+            ss->c.state != CONNECTION_STATE_CLOSED);
+}
+
+
+int connection_is_closing(ssh_session_t *ss) {
+    connection_log(__PRETTY_FUNCTION__);
+
+    return (ss->c.state == CONNECTION_STATE_CLOSING);
+}
diff --git a/ssh/connection.h b/ssh/connection.h
new file mode 100644 (file)
index 0000000..3dab498
--- /dev/null
@@ -0,0 +1,44 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef CONNECTION_H
+#define CONNECTION_H
+
+#include "includes.h"
+#include "session.h"
+#include "openssh/buffer.h"
+
+void connection_use_password(ssh_session_t *ss, char *username, char *password) CONNECTION_SEGMENT;
+Boolean connection_use_passphrase(ssh_session_t *ss, char *username, char *passphrase, MemHandle pubkey) CONNECTION_SEGMENT;
+void connection_use_kbdint(ssh_session_t *ss, char **responses) CONNECTION_SEGMENT;
+void connection_use_bounds(ssh_session_t *ss, RectangleType bounds, int charsWide, int charsHigh) CONNECTION_SEGMENT;
+void connection_receive_packet(ssh_session_t *ss, uint8_t msg, Buffer *packet) CONNECTION_SEGMENT;
+void connection_send_data(ssh_session_t *ss, uint8_t *bytes, uint16_t len) CONNECTION_SEGMENT;
+void connection_start(ssh_session_t *ss) CONNECTION_SEGMENT;
+int connection_is_open(ssh_session_t *ss) CONNECTION_SEGMENT;
+int connection_is_closing(ssh_session_t *ss) CONNECTION_SEGMENT;
+void connection_close(ssh_session_t *ss) CONNECTION_SEGMENT;
+void connection_kill(ssh_session_t *ss) CONNECTION_SEGMENT;
+
+#endif
diff --git a/ssh/keyfile.c b/ssh/keyfile.c
new file mode 100644 (file)
index 0000000..daea60b
--- /dev/null
@@ -0,0 +1,218 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "data/hostkeys.h"
+#include "openssh/key.h"
+#include "formutils.h"
+#include "rsrc/rsrc.h"
+
+#include "keyfile.h"
+
+
+typedef enum {
+    trustNever = 0,
+    trustOnce,
+    trustAlways
+} key_trust_t;
+
+#define warnstart "The credentials offered by the ser- ver "
+#define warnend   ". This connection may be insecure."
+// fixme write security problem info text
+// #define warnend   ". This connection may be insecure. Tap (i) for details "
+//                   "about this possible security problem."
+
+
+static UInt16 WarningDialog(UInt16 formID, char *content, char *address) SSH_SEGMENT;
+static key_trust_t ask_trust_for_new(const char *hostname, const char *hostaddr) SSH_SEGMENT;
+static key_trust_t ask_trust_for_change(const char *hostname, const char *hostaddr) SSH_SEGMENT;
+
+
+static UInt16 WarningDialog(UInt16 formID, char *content, char *address)
+{
+    UInt16 result;
+    FormPtr frm;
+    FieldPtr fld;
+
+    frm = FrmInitForm(formID);
+    fld = FrmGetObjectPtr(frm, FrmGetObjectIndex(frm, HostKeyWarningFormContentFieldID));
+    PrvSetFieldToValue(fld, content);
+    fld = FrmGetObjectPtr(frm, FrmGetObjectIndex(frm, HostKeyWarningFormAddressFieldID));
+    PrvSetFieldToValue(fld, address);
+    result = FrmDoDialog(frm);
+    FrmDeleteForm(frm);
+    return result;
+}
+
+
+static key_trust_t ask_trust_for_new(const char *hostname, const char *hostaddr)
+{
+    char address[16];
+    char content[241];
+    UInt16 buttonID;
+
+    strcpy(address, hostaddr);
+    
+    strcpy(content, warnstart);
+    strcat(content, "are UNKNOWN");
+    strcat(content, warnend);
+
+    buttonID = WarningDialog(HostKeyWarningFormID, content, address);
+
+    switch (buttonID) {
+    case HostKeyWarningFormTrustOnceButtonID:
+        return trustOnce;
+    case HostKeyWarningFormTrustForeverButtonID:
+        return trustAlways;
+    case HostKeyWarningFormRejectButtonID:
+        return trustNever;
+    default:
+        return trustNever;
+    }
+}
+
+
+static key_trust_t ask_trust_for_change(const char *hostname, const char *hostaddr)
+{
+    char address[16];
+    char content[241];
+    UInt16 buttonID;
+
+    strcpy(address, hostaddr);
+    
+    strcpy(content, warnstart);
+    strcat(content, "have CHANGED");
+    strcat(content, warnend);
+
+    buttonID = WarningDialog(HostKeyWarningFormID, content, address);
+
+    switch (buttonID) {
+    case HostKeyWarningFormTrustOnceButtonID:
+        return trustOnce;
+    case HostKeyWarningFormTrustForeverButtonID:
+        return trustAlways;
+    case HostKeyWarningFormRejectButtonID:
+        return trustNever;
+    default:
+        return trustNever;
+    }
+}
+
+
+Boolean check_host_key(const char *hostname, const char *hostaddr, Key *hostkey)
+{
+    UInt16 keyIndex;
+    UInt16 hostIndex;
+    key_trust_t trust;
+
+    keyIndex = HostKeysFindRecordForKey(hostkey);
+    hostIndex = HostKeysFindRecordForHostname(hostname);
+
+    if (hostIndex != noRecord  &&  
+        keyIndex != noRecord  &&  
+        hostIndex == keyIndex) 
+    {
+        // This host and this key have been seen before, 
+        // and they match (i.e. host key has not changed) - OK
+        return true;
+    }
+
+    // Ask user whether to trust this key.
+
+    if (hostIndex == noRecord) {
+        // no history for this hostname - NEW
+        trust = ask_trust_for_new(hostname, hostaddr);
+    } 
+    else {
+        // history for this hostname has a differnt key - CHANGED
+        // fixme emit weaker warning if key is known for some other host?
+        trust = ask_trust_for_change(hostname, hostaddr);
+    }
+
+    // Fix up key history (or not), and return whether to 
+    // trust this key for this connection.
+
+    if (trust == trustAlways) {
+        // Save this hostname/key in key history:
+        // 1. add new record for this key, if needed
+        // 2. add hostname to key's record
+        // 3. remove previous history for this hostname, if any
+        if (keyIndex == noRecord) {
+            HostKeysAddRecord(hostname, hostkey);
+        } else {
+            HostKeysAddHostnameToRecord(hostname, keyIndex);
+        }
+        if (hostIndex != noRecord) {
+            HostKeysRemoveHostnameFromRecord(hostname, hostIndex);
+        }
+    }
+
+    if (trust == trustAlways  ||  trust == trustOnce) {
+        // user wants to trust this key for this connection
+        return true;
+    } else {
+        // user doesn't trust this key
+        return false;
+    }
+}
+
+
+/*
+  fixme check hostname and IP together (OpenSSH options.check_host_ip)
+
+       | addr
+  host | NEW | BAD | GOOD
+   NEW |  1  |  2  |  3
+   BAD |  4  |  5  |  6
+  GOOD |  7  |  8  |  9
+
+1: new host key, new addr key - totally unknown host
+openssh: NEW  pssh: NEW
+
+2: new host key, BAD addr key - dyndns? route spoof?
+openssh: NEW with warning  pssh: NEW
+
+3: new host key, KNOWN addr key - new alias? 
+openssh: NEW  pssh: NEW (qualified by new alias?)
+
+4: BAD host key, new addr key - DNS spoof; MITM; key&addr simultaneous change
+openssh: spoof & MITM; disable some auth  pssh: spoof & MITM (strong warning)
+
+5a: BAD host key, BAD addr key, same key - MITM; key change
+openssh: MITM; disable some auth  pssh: MITM (strong warning)
+
+5b: BAD host key, BAD addr key, different key - same as 4
+
+6: BAD host key, KNOWN addr key - same as 4 (with same vs. diff key qualifiers)
+
+7: KNOWN host key, NEW addr key - rr/dyn DNS;
+openssh: adds IP with warning  pssh: silently add IP? warn?
+
+8: KNOWN host key, BAD addr key - dyn DNS;
+openssh: warn  pssh: warn (weak warning)
+
+9: KNOWN host key, KNOWN addr key
+openssh: ok  pssh: ok
+*/
+
diff --git a/ssh/keyfile.h b/ssh/keyfile.h
new file mode 100644 (file)
index 0000000..471f7e5
--- /dev/null
@@ -0,0 +1,32 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef KEYFILE_H
+#define KEYFILE_H
+
+#include "openssh/key.h"
+
+Boolean check_host_key(const char *hostname, const char *hostaddr, Key *hostkey) SSH_SEGMENT;
+
+#endif
diff --git a/ssh/keyimport.c b/ssh/keyimport.c
new file mode 100644 (file)
index 0000000..d7f3a04
--- /dev/null
@@ -0,0 +1,1082 @@
+/**********
+ * Portions Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+/*
+ * Code for PuTTY to import and export private key files in other
+ * SSH clients' formats.
+ */
+
+// GrP pssh:
+// based on PuTTY's import.c
+// changed includes
+// replace file I/O with memory operations
+// remove export
+
+#include "includes.h"
+#include "ctype.h"
+#include "openssh/buffer.h"
+#include "openssh/bufaux.h"
+#include "openssh/key.h"
+#include "openssh/openbsd-compat/base64.h"
+#include "openssl/evp/evp.h"
+#include "openssl/md5/md5.h"
+
+#include "keyimport.h"
+
+static char fromhex(char c) SSH2_SEGMENT;
+static int ber_read_id_len(Buffer *source, uint32_t *id, uint32_t *length, int *flags) SSH2_SEGMENT;
+static struct openssh_key *load_openssh_key(char *buffer, uint16_t bufferlen) SSH2_SEGMENT;
+
+
+
+
+
+#define PUT_32BIT(cp, value) do { \
+  (cp)[3] = (unsigned char)(value); \
+  (cp)[2] = (unsigned char)((value) >> 8); \
+  (cp)[1] = (unsigned char)((value) >> 16); \
+  (cp)[0] = (unsigned char)((value) >> 24); } while (0)
+
+#define GET_32BIT(cp) \
+    (((unsigned long)(unsigned char)(cp)[0] << 24) | \
+    ((unsigned long)(unsigned char)(cp)[1] << 16) | \
+    ((unsigned long)(unsigned char)(cp)[2] << 8) | \
+    ((unsigned long)(unsigned char)(cp)[3]))
+
+
+/* ----------------------------------------------------------------------
+ * Helper routines. (The base64 ones are defined in sshpubk.c.)
+ */
+
+#define isbase64(c) (    ((c) >= 'A' && (c) <= 'Z') || \
+                         ((c) >= 'a' && (c) <= 'z') || \
+                         ((c) >= '0' && (c) <= '9') || \
+                         (c) == '+' || (c) == '/' || (c) == '=' \
+                         )
+
+
+// assumes isxdigit(c)
+static char fromhex(char c)
+{
+    if (isdigit(c)) return c - '0';
+    else return 10 + (tolower(c) - 'a');
+}
+
+/*
+ * Read an ASN.1/BER identifier and length pair.
+ * 
+ * Flags are a combination of the #defines listed below.
+ * 
+ * Returns 0 on failure, 1 on success
+ */
+
+/* ASN.1 tag classes. */
+#define ASN1_CLASS_UNIVERSAL        (0 << 6)
+#define ASN1_CLASS_APPLICATION      (1 << 6)
+#define ASN1_CLASS_CONTEXT_SPECIFIC (2 << 6)
+#define ASN1_CLASS_PRIVATE          (3 << 6)
+#define ASN1_CLASS_MASK             (3 << 6)
+
+/* Primitive versus constructed bit. */
+#define ASN1_CONSTRUCTED            (1 << 5)
+
+static int ber_read_id_len(Buffer *source, uint32_t *id, uint32_t *length, int *flags)
+{
+    uint8_t c;
+
+#define NEXT(cc) \
+    do { \
+    if (buffer_len(source) == 0) return 0; \
+    cc = buffer_get_char(source); \
+    } while (0)
+
+    NEXT(c);
+
+    *flags = (c & 0xE0);
+    if ((c & 0x1F) == 0x1F) {
+       *id = 0;
+       while (c & 0x80) {
+           *id = (*id << 7) | (c & 0x7F);
+            NEXT(c);
+       }
+       *id = (*id << 7) | (c & 0x7F);
+    } else {
+       *id = c & 0x1F;
+    }
+
+    NEXT(c);
+
+    if (c & 0x80) {
+       unsigned int n = c & 0x7F;
+        if (buffer_len(source) < n) return 0;
+       *length = 0;
+       while (n--) {
+            NEXT(c);
+           *length = (*length << 8) | c;
+        }
+    } else {
+       *length = c;
+    }
+
+    return 1;
+#undef NEXT
+}
+
+#if 0
+static int put_string(void *target, void *data, uint32_t len)
+{
+    unsigned char *d = (unsigned char *)target;
+
+    PUT_32BIT(d, len);
+    memcpy(d+4, data, len);
+    return len+4;
+}
+
+static int put_mp(void *target, void *data, uint32_t len)
+{
+    unsigned char *d = (unsigned char *)target;
+    unsigned char *i = (unsigned char *)data;
+
+    if (*i & 0x80) {
+        PUT_32BIT(d, len+1);
+        d[4] = 0;
+        memcpy(d+5, data, len);
+        return len+5;
+    } else {
+        PUT_32BIT(d, len);
+        memcpy(d+4, data, len);
+        return len+4;
+    }
+}
+
+/* Simple structure to point to an mp-int within a blob. */
+struct mpint_pos { void *start; int bytes; };
+
+int ssh2_read_mpint(void *data, int len, struct mpint_pos *ret)
+{
+    int bytes;
+    unsigned char *d = (unsigned char *) data;
+
+    if (len < 4)
+        goto error;
+    bytes = GET_32BIT(d);
+    if (len < 4+bytes)
+        goto error;
+
+    ret->start = d + 4;
+    ret->bytes = bytes;
+    return bytes+4;
+
+    error:
+    ret->start = NULL;
+    ret->bytes = -1;
+    return len;                        /* ensure further calls fail as well */
+}
+#endif
+
+/* ----------------------------------------------------------------------
+ * Code to read and write OpenSSH private keys.
+ */
+
+struct openssh_key {
+    int type;
+    int encrypted;
+    char iv[32];
+    Buffer keyblob;
+};
+
+
+static struct openssh_key *load_openssh_key(char *buffer, uint16_t bufferlen)
+{
+    struct openssh_key *ret;
+    char *errmsg = NULL, *p, *base64_start, *line;
+    int base64_size;
+    char *buffercopy;
+
+    ret = arena_calloc(sizeof(*ret));
+
+    // strsep mangles data. Don't modify passed-in buffer.
+    buffercopy = arena_malloc(bufferlen);
+    memcpy(buffercopy, buffer, bufferlen);
+    buffer = buffercopy;
+
+    line = strsep(&buffer, "\n");
+    if (!line  ||  
+       0 != strncmp(line, "-----BEGIN ", 11) ||
+       0 != strcmp(line+strlen(line)-16, "PRIVATE KEY-----")) {
+       errmsg = "File does not begin with OpenSSH key header";
+       goto error;
+    }
+    if (!strcmp(line, "-----BEGIN RSA PRIVATE KEY-----"))
+       ret->type = KEY_RSA;
+    else if (!strcmp(line, "-----BEGIN DSA PRIVATE KEY-----"))
+       ret->type = KEY_DSA;
+    else {
+       errmsg = "Unrecognised key type";
+       goto error;
+    }
+
+    while (1) {
+        line = strsep(&buffer, "\n");
+        if (!line) {
+           errmsg = "Unexpected end of file";
+           goto error;
+        }
+
+        if (0 == strncmp(line, "-----END ", 9)  &&  
+            strstr(line, "PRIVATE KEY-----"))
+        {
+            errmsg = "Key body not present";
+            goto error;
+        }
+
+       if ((p = strchr(line, ':')) == NULL) {
+            // done with headers
+            // put line back into buffer
+            buffer[-1] = '\n';
+            buffer = line;
+            break;
+        }
+
+        *p++ = '\0'; // replace ':' with '\0'
+        while (*p  &&  isspace(*p)) p++;
+        if (0 == strcmp(line, "Proc-Type")) {
+            if (p[0] != '4' || p[1] != ',') {
+                errmsg = "Proc-Type is not 4 (only 4 is supported)";
+                goto error;
+            }
+            p += 2;
+            if (0 == strcmp(p, "ENCRYPTED"))
+                ret->encrypted = 1;
+        }
+        else if (0 == strcmp(line, "DEK-Info")) {
+            int i;
+
+            if (0 != strncmp(p, "DES-EDE3-CBC,", 13)) {
+                // fixme use OpenSSL to support other ciphers
+                errmsg = "Ciphers other than DES-EDE3-CBC not supported";
+                goto error;
+            }
+            p += 13;
+            // 16 hex digits follow
+            for (i = 0; i < 8; i++) {
+                if (!isxdigit(p[0])  ||  !isxdigit(p[1])) break;
+                ret->iv[i] = (fromhex(p[0]) << 4) | fromhex(p[1]);
+                p += 2;
+            }
+            if (i < 8) {
+                errmsg = "Expected 16-digit iv in DEK-Info";
+                goto error;
+            }
+        }
+    }
+
+    // done reading headers
+    // read base64 data
+
+    if (strchr(buffer, ':')) {
+        errmsg = "Header found in body of key data";
+        goto error;
+    }
+
+    base64_start = buffer;
+    while (isspace(*buffer) || isbase64(*buffer)) buffer++;
+    // buffer is now the last line, or something invalid
+    // But be flexible about garbage after the end.
+    if (0 != strncmp(buffer, "-----END ", 9)  ||  
+        !strstr(buffer, "PRIVATE KEY-----"))
+    {
+        // last line is bogus
+        errmsg = "Unexpected end of file";
+        goto error;
+    }
+
+    // [base64_start, buffer) should be valid base64 data
+
+    *buffer = '\0';
+    base64_size = strlen(base64_start);
+
+    buffer_init(&ret->keyblob);
+    buffer_append_space(&ret->keyblob, base64_size);
+
+    base64_size = b64_pton(base64_start, buffer_ptr(&ret->keyblob), base64_size);
+    if (base64_size < 0) {
+        errmsg = "Invalid base64 encoding";
+        goto error;
+    }
+    
+    if (base64_size == 0) {
+       errmsg = "Key body not present";
+       goto error;
+    }
+
+    if (ret->encrypted && base64_size % 8 != 0) {
+       errmsg = "Encrypted key blob is not a multiple of cipher block size";
+       goto error;
+    }
+
+    // trim buffer
+    buffer_consume_end(&ret->keyblob, buffer_len(&ret->keyblob) - base64_size);
+
+    arena_free(buffercopy);
+    return ret;
+
+    error:
+    // if (errmsg) debug_printf("load_openssh_key %s", errmsg);
+    if (ret->keyblob.buf) {
+        // fixme clear too?
+        buffer_free(&ret->keyblob);
+    }
+    memset(ret, 0, sizeof(*ret));
+    arena_free(ret);
+    arena_free(buffercopy);
+    return NULL;
+}
+
+int openssh_encrypted(char *buffer, uint16_t bufferlen)
+{
+    struct openssh_key *key = load_openssh_key(buffer, bufferlen);
+    int ret;
+
+    if (!key)
+       return 0;
+    ret = key->encrypted;
+    buffer_free(&key->keyblob); // fixme clear too?
+    memset(key, 0, sizeof(*key)); // GrP fixme PuTTY bug?
+    arena_free(key);
+    return ret;
+}
+
+Key *openssh_read(char *buffer, uint16_t bufferlen, char *passphrase)
+{
+    struct openssh_key *key = load_openssh_key(buffer, bufferlen);
+    Buffer *keyblob;
+    int flags;
+    uint32_t id, len;
+    char *errmsg = NULL;
+    Key *result = NULL;
+
+    if (!key)
+       return 0;
+
+    keyblob = &key->keyblob;
+
+    if (key->encrypted) {
+       /*
+        * Derive encryption key from passphrase and iv/salt:
+        * 
+        *  - let block A equal MD5(passphrase || iv)
+        *  - let block B equal MD5(A || passphrase || iv)
+        *  - block C would be MD5(B || passphrase || iv) and so on
+        *  - encryption key is the first N bytes of A || B
+        */
+       MD5_CTX md5c;
+        const EVP_CIPHER *cipher;
+        EVP_CIPHER_CTX ctx;
+        
+       unsigned char keybuf[32];
+        uint8_t *kb;
+        int written;
+        int total;
+        Buffer de;
+        int decryptOK;
+
+       MD5_Init(&md5c);
+       MD5_Update(&md5c, passphrase, strlen(passphrase));
+       MD5_Update(&md5c, key->iv, 8);
+       MD5_Final(keybuf, &md5c);
+
+       MD5_Init(&md5c);
+       MD5_Update(&md5c, keybuf, 16);
+       MD5_Update(&md5c, passphrase, strlen(passphrase));
+       MD5_Update(&md5c, key->iv, 8);
+       MD5_Final(keybuf+16, &md5c);
+
+        // Decrypt keyblob
+        cipher = EVP_des_ede3_cbc(); // fixme others
+
+        kb = buffer_ptr(keyblob);
+        total = buffer_len(keyblob);
+        buffer_init(&de);
+        buffer_append_space(&de, total);
+        // extra pad needed by EVP_Decrypt
+        buffer_append_space(&de, EVP_CIPHER_block_size(cipher));
+
+        EVP_CIPHER_CTX_init(&ctx);
+        EVP_DecryptInit_ex(&ctx, cipher, NULL, keybuf, key->iv);
+        EVP_DecryptUpdate(&ctx, buffer_ptr(&de), &written, kb, total);
+        decryptOK = EVP_DecryptFinal_ex(&ctx, written+(uint8_t *)buffer_ptr(&de), &total);
+        EVP_CIPHER_CTX_cleanup(&ctx);
+
+        buffer_free(keyblob); // fixme erase
+        buffer_consume_end(&de, EVP_CIPHER_block_size(cipher));
+        *keyblob = de;
+
+        memset(keybuf, 0, sizeof(keybuf));
+        memset(&md5c, 0, sizeof(md5c));
+
+        if (!decryptOK) {
+            // EVP discovered the decryption failure
+            errmsg = "Incorrect passphrase";
+            goto error;
+        }
+    }
+
+    /*
+     * Now we have a decrypted key blob, which contains an ASN.1
+     * encoded private key. We must now untangle the ASN.1.
+     *
+     * We expect the whole key blob to be formatted as a SEQUENCE
+     * (0x30 followed by a length code indicating that the rest of
+     * the blob is part of the sequence). Within that SEQUENCE we
+     * expect to see a bunch of INTEGERs. What those integers mean
+     * depends on the key type:
+     *
+     *  - For RSA, we expect the integers to be 0, n, e, d, p, q,
+     *    dmp1, dmq1, iqmp in that order. (The last three are d mod
+     *    (p-1), d mod (q-1), inverse of q mod p respectively.)
+     *
+     *  - For DSA, we expect them to be 0, p, q, g, y, x in that
+     *    order.
+     */
+    
+
+    /* Expect the SEQUENCE header. Take its absence as a failure to decrypt. */
+    if (!ber_read_id_len(keyblob, &id, &len, &flags)  ||  id != 16) {
+       errmsg = "ASN.1 decoding failure";
+       goto error;
+    }
+
+#define DECODE_INTEGER \
+    do { \
+    if (!ber_read_id_len(keyblob, &id, &len, &flags)  ||   \
+        id != 2 || \
+        buffer_len(keyblob) < len) { \
+        errmsg = "ASN.1 decoding failure"; \
+        goto error; \
+    } \
+    } while (0)
+
+#define FETCH_INTEGER(bn) \
+    if (!BN_bin2bn(buffer_ptr(keyblob), len, bn)) { \
+        errmsg = "ASN.1 decoding failure"; \
+        goto error; \
+    } \
+    buffer_consume(keyblob, len)
+
+    // Make new keys
+    result = key_new_private(key->type);
+    
+    // First integer: 0
+    DECODE_INTEGER;
+    if (len != 1 || buffer_get_char(keyblob) != 0) {
+        errmsg = "Version number mismatch";
+        goto error;
+    }
+
+    // Second integer: RSA n (pub), DSA p (pub)
+    DECODE_INTEGER;
+    if (key->type == KEY_RSA) {
+        FETCH_INTEGER(result->rsa->n);
+    } else {
+        FETCH_INTEGER(result->dsa->p);
+    }
+
+    // Third integer: RSA e (pub), DSA q (pub)
+    DECODE_INTEGER;
+    if (key->type == KEY_RSA) {
+        FETCH_INTEGER(result->rsa->e);
+    } else {
+        FETCH_INTEGER(result->dsa->q);
+    }
+
+    // Fourth integer: RSA d (priv), DSA g (pub)
+    DECODE_INTEGER;
+    if (key->type == KEY_RSA) {
+        FETCH_INTEGER(result->rsa->d);
+    } else {
+        FETCH_INTEGER(result->dsa->g);
+    }
+
+    // Fifth integer: RSA p (priv), DSA y (priv)
+    DECODE_INTEGER;
+    if (key->type == KEY_RSA) {
+        FETCH_INTEGER(result->rsa->p);
+    } else {
+        FETCH_INTEGER(result->dsa->pub_key);
+    }
+
+    // Sixth integer: RSA q (priv), DSA x (priv)
+    DECODE_INTEGER;
+    if (key->type == KEY_RSA) {
+        FETCH_INTEGER(result->rsa->q);
+    } else {
+        FETCH_INTEGER(result->dsa->priv_key);
+    }
+
+    if (key->type == KEY_RSA) {
+        // Seventh integer: RSA dmp1 (priv)
+        DECODE_INTEGER;
+        FETCH_INTEGER(result->rsa->dmp1);
+
+        // Eighth integer: RSA dmq1 (priv)
+        DECODE_INTEGER;
+        FETCH_INTEGER(result->rsa->dmq1);
+
+        // Ninth integer: RSA iqmp (priv)
+        DECODE_INTEGER;
+        FETCH_INTEGER(result->rsa->iqmp);
+    }
+
+#undef DECODE_INTEGER
+#undef FETCH_INTEGER
+
+    errmsg = NULL;                     /* no error */
+
+ error:
+    buffer_free(&key->keyblob); // fixme wipe
+    memset(key, 0, sizeof(*key));
+    arena_free(key);
+    if (errmsg && result) { key_free(result); result = NULL; }
+    return result;
+}
+
+/* ----------------------------------------------------------------------
+ * Code to read ssh.com private keys.
+ */
+
+/*
+ * The format of the base64 blob is largely ssh2-packet-formatted,
+ * except that mpints are a bit different: they're more like the
+ * old ssh1 mpint. You have a 32-bit bit count N, followed by
+ * (N+7)/8 bytes of data.
+ * 
+ * So. The blob contains:
+ * 
+ *  - uint32 0x3f6ff9eb       (magic number)
+ *  - uint32 size             (total blob size)
+ *  - string key-type         (see below)
+ *  - string cipher-type      (tells you if key is encrypted)
+ *  - string encrypted-blob
+ * 
+ * (The first size field includes the size field itself and the
+ * magic number before it. All other size fields are ordinary ssh2
+ * strings, so the size field indicates how much data is to
+ * _follow_.)
+ * 
+ * The encrypted blob, once decrypted, contains a single string
+ * which in turn contains the payload. (This allows padding to be
+ * added after that string while still making it clear where the
+ * real payload ends. Also it probably makes for a reasonable
+ * decryption check.)
+ * 
+ * The payload blob, for an RSA key, contains:
+ *  - mpint e
+ *  - mpint d
+ *  - mpint n  (yes, the public and private stuff is intermixed)
+ *  - mpint u  (presumably inverse of p mod q)
+ *  - mpint p  (p is the smaller prime)
+ *  - mpint q  (q is the larger)
+ * 
+ * For a DSA key, the payload blob contains:
+ *  - uint32 0
+ *  - mpint p
+ *  - mpint g
+ *  - mpint q
+ *  - mpint y
+ *  - mpint x
+ * 
+ * Alternatively, if the parameters are `predefined', that
+ * (0,p,g,q) sequence can be replaced by a uint32 1 and a string
+ * containing some predefined parameter specification. *shudder*,
+ * but I doubt we'll encounter this in real life.
+ * 
+ * The key type strings are ghastly. The RSA key I looked at had a
+ * type string of
+ * 
+ *   `if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}'
+ * 
+ * and the DSA key wasn't much better:
+ * 
+ *   `dl-modp{sign{dsa-nist-sha1},dh{plain}}'
+ * 
+ * It isn't clear that these will always be the same. I think it
+ * might be wise just to look at the `if-modn{sign{rsa' and
+ * `dl-modp{sign{dsa' prefixes.
+ * 
+ * Finally, the encryption. The cipher-type string appears to be
+ * either `none' or `3des-cbc'. Looks as if this is SSH2-style
+ * 3des-cbc (i.e. outer cbc rather than inner). The key is created
+ * from the passphrase by means of yet another hashing faff:
+ * 
+ *  - first 16 bytes are MD5(passphrase)
+ *  - next 16 bytes are MD5(passphrase || first 16 bytes)
+ *  - if there were more, they'd be MD5(passphrase || first 32),
+ *    and so on.
+ */
+
+
+#if 0
+// GrP fixme disabled for now
+
+#define SSHCOM_MAGIC_NUMBER 0x3f6ff9eb
+
+struct sshcom_key {
+    char comment[256];                 /* allowing any length is overkill */
+    unsigned char *keyblob;
+    int keyblob_len, keyblob_size;
+};
+
+struct sshcom_key *load_sshcom_key(char *fp)
+{
+    struct sshcom_key *ret;
+    char buffer[256];
+    int len;
+    char *errmsg, *p;
+    int headers_done;
+    char base64_bit[4];
+    int base64_chars = 0;
+
+    ret = smalloc(sizeof(*ret));
+    ret->comment[0] = '\0';
+    ret->keyblob = NULL;
+    ret->keyblob_len = ret->keyblob_size = 0;
+
+    fp = fopen(filename, "r");
+    if (!fp) {
+       errmsg = "Unable to open key file";
+       goto error;
+    }
+    if (!sgets(buffer, sizeof(buffer), &fp) ||
+       0 != strcmp(buffer, "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----\n")) {
+       errmsg = "File does not begin with ssh.com key header";
+       goto error;
+    }
+
+    headers_done = 0;
+    while (1) {
+       if (!sgets(buffer, sizeof(buffer), &fp)) {
+           errmsg = "Unexpected end of file";
+           goto error;
+       }
+        if (!strcmp(buffer, "---- END SSH2 ENCRYPTED PRIVATE KEY ----\n"))
+            break;                     /* done */
+       if ((p = strchr(buffer, ':')) != NULL) {
+           if (headers_done) {
+               errmsg = "Header found in body of key data";
+               goto error;
+           }
+           *p++ = '\0';
+           while (*p && isspace((unsigned char)*p)) p++;
+            /*
+             * Header lines can end in a trailing backslash for
+             * continuation.
+             */
+            while ((len = strlen(p)) > sizeof(buffer) - (p-buffer) -1 ||
+                   p[len-1] != '\n' || p[len-2] == '\\') {
+                if (len > (p-buffer) + sizeof(buffer)-2) {
+                    errmsg = "Header line too long to deal with";
+                    goto error;
+                }
+                if (!sgets(p+len-2, sizeof(buffer)-(p-buffer)-(len-2), &fp)) {
+                    errmsg = "Unexpected end of file";
+                    goto error;
+                }
+            }
+            p[strcspn(p, "\n")] = '\0';
+            if (!strcmp(buffer, "Comment")) {
+                /* Strip quotes in comment if present. */
+                if (p[0] == '"' && p[strlen(p)-1] == '"') {
+                    p++;
+                    p[strlen(p)-1] = '\0';
+                }
+                strncpy(ret->comment, p, sizeof(ret->comment));
+                ret->comment[sizeof(ret->comment)-1] = '\0';
+            }
+       } else {
+           headers_done = 1;
+
+           p = buffer;
+           while (isbase64(*p)) {
+                base64_bit[base64_chars++] = *p;
+                if (base64_chars == 4) {
+                    unsigned char out[3];
+
+                    base64_chars = 0;
+
+                    len = base64_decode_atom(base64_bit, out);
+
+                    if (len <= 0) {
+                        errmsg = "Invalid base64 encoding";
+                        goto error;
+                    }
+
+                    if (ret->keyblob_len + len > ret->keyblob_size) {
+                        ret->keyblob_size = ret->keyblob_len + len + 256;
+                        ret->keyblob = srealloc(ret->keyblob, ret->keyblob_size);
+                    }
+
+                    memcpy(ret->keyblob + ret->keyblob_len, out, len);
+                    ret->keyblob_len += len;
+                }
+
+               p++;
+           }
+       }
+    }
+
+    if (ret->keyblob_len == 0 || !ret->keyblob) {
+       errmsg = "Key body not present";
+       goto error;
+    }
+
+    return ret;
+
+    error:
+    if (ret) {
+       if (ret->keyblob) {
+            memset(ret->keyblob, 0, ret->keyblob_size);
+            sfree(ret->keyblob);
+        }
+        memset(&ret, 0, sizeof(ret));
+       sfree(ret);
+    }
+    return NULL;
+}
+
+int sshcom_encrypted(char *filename, char **comment)
+{
+    struct sshcom_key *key = load_sshcom_key(filename);
+    int pos, len, answer;
+
+    *comment = NULL;
+    if (!key)
+        return 0;
+
+    /*
+     * Check magic number.
+     */
+    if (GET_32BIT(key->keyblob) != 0x3f6ff9eb)
+        return 0;                      /* key is invalid */
+
+    /*
+     * Find the cipher-type string.
+     */
+    answer = 0;
+    pos = 8;
+    if (key->keyblob_len < pos+4)
+        goto done;                     /* key is far too short */
+    pos += 4 + GET_32BIT(key->keyblob + pos);   /* skip key type */
+    if (key->keyblob_len < pos+4)
+        goto done;                     /* key is far too short */
+    len = GET_32BIT(key->keyblob + pos);   /* find cipher-type length */
+    if (key->keyblob_len < pos+4+len)
+        goto done;                     /* cipher type string is incomplete */
+    if (len != 4 || 0 != memcmp(key->keyblob + pos + 4, "none", 4))
+        answer = 1;
+
+    done:
+    *comment = dupstr(key->comment);
+    memset(key->keyblob, 0, key->keyblob_size);
+    sfree(key->keyblob);
+    memset(&key, 0, sizeof(key));
+    sfree(key);
+    return answer;
+}
+
+int sshcom_read_mpint(void *data, int len, struct mpint_pos *ret)
+{
+    int bits;
+    int bytes;
+    unsigned char *d = (unsigned char *) data;
+
+    if (len < 4)
+        goto error;
+    bits = GET_32BIT(d);
+
+    bytes = (bits + 7) / 8;
+    if (len < 4+bytes)
+        goto error;
+
+    ret->start = d + 4;
+    ret->bytes = bytes;
+    return bytes+4;
+
+    error:
+    ret->start = NULL;
+    ret->bytes = -1;
+    return len;                        /* ensure further calls fail as well */
+}
+
+static int sshcom_put_mpint(void *target, void *data, int len)
+{
+    unsigned char *d = (unsigned char *)target;
+    unsigned char *i = (unsigned char *)data;
+    int bits = len * 8 - 1;
+
+    while (bits > 0) {
+       if (*i & (1 << (bits & 7)))
+           break;
+       if (!(bits-- & 7))
+           i++, len--;
+    }
+
+    PUT_32BIT(d, bits+1);
+    memcpy(d+4, i, len);
+    return len+4;
+}
+
+struct ssh2_userkey *sshcom_read(char *filename, char *passphrase)
+{
+    struct sshcom_key *key = load_sshcom_key(filename);
+    char *errmsg;
+    int pos, len;
+    const char prefix_rsa[] = "if-modn{sign{rsa";
+    const char prefix_dsa[] = "dl-modp{sign{dsa";
+    enum { RSA, DSA } type;
+    int encrypted;
+    char *ciphertext;
+    int cipherlen;
+    struct ssh2_userkey *ret = NULL, *retkey;
+    const struct ssh_signkey *alg;
+    unsigned char *blob = NULL;
+    int blobsize, publen, privlen;
+
+    if (!key)
+        return NULL;
+
+    /*
+     * Check magic number.
+     */
+    if (GET_32BIT(key->keyblob) != SSHCOM_MAGIC_NUMBER) {
+        errmsg = "Key does not begin with magic number";
+        goto error;
+    }
+
+    /*
+     * Determine the key type.
+     */
+    pos = 8;
+    if (key->keyblob_len < pos+4 ||
+        (len = GET_32BIT(key->keyblob + pos)) > key->keyblob_len - pos - 4) {
+        errmsg = "Key blob does not contain a key type string";
+        goto error;
+    }
+    if (len > sizeof(prefix_rsa) - 1 &&
+        !memcmp(key->keyblob+pos+4, prefix_rsa, sizeof(prefix_rsa) - 1)) {
+        type = RSA;
+    } else if (len > sizeof(prefix_dsa) - 1 &&
+        !memcmp(key->keyblob+pos+4, prefix_dsa, sizeof(prefix_dsa) - 1)) {
+        type = DSA;
+    } else {
+        errmsg = "Key is of unknown type";
+        goto error;
+    }
+    pos += 4+len;
+
+    /*
+     * Determine the cipher type.
+     */
+    if (key->keyblob_len < pos+4 ||
+        (len = GET_32BIT(key->keyblob + pos)) > key->keyblob_len - pos - 4) {
+        errmsg = "Key blob does not contain a cipher type string";
+        goto error;
+    }
+    if (len == 4 && !memcmp(key->keyblob+pos+4, "none", 4))
+        encrypted = 0;
+    else if (len == 8 && !memcmp(key->keyblob+pos+4, "3des-cbc", 8))
+        encrypted = 1;
+    else {
+        errmsg = "Key encryption is of unknown type";
+        goto error;
+    }
+    pos += 4+len;
+
+    /*
+     * Get hold of the encrypted part of the key.
+     */
+    if (key->keyblob_len < pos+4 ||
+        (len = GET_32BIT(key->keyblob + pos)) > key->keyblob_len - pos - 4) {
+        errmsg = "Key blob does not contain actual key data";
+        goto error;
+    }
+    ciphertext = key->keyblob + pos + 4;
+    cipherlen = len;
+    if (cipherlen == 0) {
+        errmsg = "Length of key data is zero";
+        goto error;
+    }
+
+    /*
+     * Decrypt it if necessary.
+     */
+    if (encrypted) {
+       /*
+        * Derive encryption key from passphrase and iv/salt:
+        * 
+        *  - let block A equal MD5(passphrase)
+        *  - let block B equal MD5(passphrase || A)
+        *  - block C would be MD5(passphrase || A || B) and so on
+        *  - encryption key is the first N bytes of A || B
+        */
+       struct MD5Context md5c;
+       unsigned char keybuf[32], iv[8];
+
+        if (cipherlen % 8 != 0) {
+            errmsg = "Encrypted part of key is not a multiple of cipher block"
+                " size";
+            goto error;
+        }
+
+       MD5Init(&md5c);
+       MD5Update(&md5c, passphrase, strlen(passphrase));
+       MD5Final(keybuf, &md5c);
+
+       MD5Init(&md5c);
+       MD5Update(&md5c, passphrase, strlen(passphrase));
+       MD5Update(&md5c, keybuf, 16);
+       MD5Final(keybuf+16, &md5c);
+
+       /*
+        * Now decrypt the key blob.
+        */
+        memset(iv, 0, sizeof(iv));
+       des3_decrypt_pubkey_ossh(keybuf, iv, ciphertext, cipherlen);
+
+        memset(&md5c, 0, sizeof(md5c));
+        memset(keybuf, 0, sizeof(keybuf));
+
+        /*
+         * Hereafter we return WRONG_PASSPHRASE for any parsing
+         * error. (But only if we've just tried to decrypt it!
+         * Returning WRONG_PASSPHRASE for an unencrypted key is
+         * automatic doom.)
+         */
+        if (encrypted)
+            ret = SSH2_WRONG_PASSPHRASE;
+    }
+
+    /*
+     * Strip away the containing string to get to the real meat.
+     */
+    len = GET_32BIT(ciphertext);
+    if (len > cipherlen-4) {
+        errmsg = "containing string was ill-formed";
+        goto error;
+    }
+    ciphertext += 4;
+    cipherlen = len;
+
+    /*
+     * Now we break down into RSA versus DSA. In either case we'll
+     * construct public and private blobs in our own format, and
+     * end up feeding them to alg->createkey().
+     */
+    blobsize = cipherlen + 256;
+    blob = smalloc(blobsize);
+    privlen = 0;
+    if (type == RSA) {
+        struct mpint_pos n, e, d, u, p, q;
+        int pos = 0;
+        pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &e);
+        pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &d);
+        pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &n);
+        pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &u);
+        pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &p);
+        pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &q);
+        if (!q.start) {
+            errmsg = "key data did not contain six integers";
+            goto error;
+        }
+
+        alg = &ssh_rsa;
+        pos = 0;
+        pos += put_string(blob+pos, "ssh-rsa", 7);
+        pos += put_mp(blob+pos, e.start, e.bytes);
+        pos += put_mp(blob+pos, n.start, n.bytes);
+        publen = pos;
+        pos += put_string(blob+pos, d.start, d.bytes);
+        pos += put_mp(blob+pos, q.start, q.bytes);
+        pos += put_mp(blob+pos, p.start, p.bytes);
+        pos += put_mp(blob+pos, u.start, u.bytes);
+        privlen = pos - publen;
+    } else if (type == DSA) {
+        struct mpint_pos p, q, g, x, y;
+        int pos = 4;
+        if (GET_32BIT(ciphertext) != 0) {
+            errmsg = "predefined DSA parameters not supported";
+            goto error;
+        }
+        pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &p);
+        pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &g);
+        pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &q);
+        pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &y);
+        pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &x);
+        if (!x.start) {
+            errmsg = "key data did not contain five integers";
+            goto error;
+        }
+
+        alg = &ssh_dss;
+        pos = 0;
+        pos += put_string(blob+pos, "ssh-dss", 7);
+        pos += put_mp(blob+pos, p.start, p.bytes);
+        pos += put_mp(blob+pos, q.start, q.bytes);
+        pos += put_mp(blob+pos, g.start, g.bytes);
+        pos += put_mp(blob+pos, y.start, y.bytes);
+        publen = pos;
+        pos += put_mp(blob+pos, x.start, x.bytes);
+        privlen = pos - publen;
+    }
+
+    assert(privlen > 0);              /* should have bombed by now if not */
+
+    retkey = smalloc(sizeof(struct ssh2_userkey));
+    retkey->alg = alg;
+    retkey->data = alg->createkey(blob, publen, blob+publen, privlen);
+    if (!retkey->data) {
+       sfree(retkey);
+       errmsg = "unable to create key data structure";
+       goto error;
+    }
+    retkey->comment = dupstr(key->comment);
+
+    errmsg = NULL; /* no error */
+    ret = retkey;
+
+    error:
+    if (blob) {
+        memset(blob, 0, blobsize);
+        sfree(blob);
+    }
+    memset(key->keyblob, 0, key->keyblob_size);
+    sfree(key->keyblob);
+    memset(&key, 0, sizeof(key));
+    sfree(key);
+    return ret;
+}
+
+#endif
+
+
diff --git a/ssh/keyimport.h b/ssh/keyimport.h
new file mode 100644 (file)
index 0000000..bb23d7c
--- /dev/null
@@ -0,0 +1,34 @@
+/**********
+ * Portions Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef KEYIMPORT_H
+#define KEYIMPORT_H
+
+#include "includes.h"
+#include "ssh/openssh/key.h"
+
+int openssh_encrypted(char *buffer, uint16_t bufferlen) SSH2_SEGMENT;
+Key *openssh_read(char *buffer, uint16_t bufferlen, char *passphrase) SSH2_SEGMENT;
+
+#endif
diff --git a/ssh/openssh/bufaux.c b/ssh/openssh/bufaux.c
new file mode 100644 (file)
index 0000000..45a66fc
--- /dev/null
@@ -0,0 +1,313 @@
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ * Auxiliary functions for storing and retrieving various data types to/from
+ * Buffers.
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ *
+ *
+ * SSH2 packet format added by Markus Friedl
+ * Copyright (c) 2000 Markus Friedl.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// added buffer_require_empty
+// reduce max string size to 62 KB
+// use stdint types in some places
+// use BN_is_negative
+// fix signed vs unsigned comparisons
+
+#include "includes.h"
+RCSID("$OpenBSD: bufaux.c,v 1.29 2003/04/08 20:21:28 itojun Exp $");
+
+#include "crypto/openssl/bn/bn.h"
+#include "bufaux.h"
+#include "xmalloc.h"
+#include "getput.h"
+
+void 
+buffer_require_empty(Buffer *buffer)
+{
+    if (buffer_len(buffer) != 0) {
+        fatal("buffer_require_empty: buffer not empty");
+    }
+}
+
+/*
+ * Stores an BIGNUM in the buffer with a 2-byte msb first bit count, followed
+ * by (bits+7)/8 bytes of binary data, msb first.
+ */
+void
+buffer_put_bignum(Buffer *buffer, BIGNUM *value)
+{
+       int bits = BN_num_bits(value);
+       int bin_size = (bits + 7) / 8;
+       u_char *buf = xmalloc(bin_size);
+       int oi;
+       char msg[2];
+
+       /* Get the value of in binary */
+       oi = BN_bn2bin(value, buf);
+       if (oi != bin_size)
+               fatal("buffer_put_bignum: BN_bn2bin() failed: oi %d != bin_size %d",
+                   oi, bin_size);
+
+       /* Store the number of bits in the buffer in two bytes, msb first. */
+       PUT_16BIT(msg, bits);
+       buffer_append(buffer, msg, 2);
+       /* Store the binary data. */
+       buffer_append(buffer, buf, oi);
+
+       memset(buf, 0, bin_size);
+       xfree(buf);
+}
+
+/*
+ * Retrieves an BIGNUM from the buffer.
+ */
+void
+buffer_get_bignum(Buffer *buffer, BIGNUM *value)
+{
+       unsigned int bits, bytes;
+       u_char buf[2], *bin;
+
+       /* Get the number for bits. */
+       buffer_get(buffer, buf, 2);
+       bits = GET_16BIT(buf);
+       /* Compute the number of binary bytes that follow. */
+       bytes = (bits + 7) / 8;
+       if (bytes > 8 * 1024)
+               fatal("buffer_get_bignum: cannot handle BN of size %d", bytes);
+       if (buffer_len(buffer) < bytes)
+               fatal("buffer_get_bignum: input buffer too small");
+       bin = buffer_ptr(buffer);
+       BN_bin2bn(bin, bytes, value);
+       buffer_consume(buffer, bytes);
+}
+
+/*
+ * Stores an BIGNUM in the buffer in SSH2 format.
+ */
+void
+buffer_put_bignum2(Buffer *buffer, BIGNUM *value)
+{
+       int bytes = BN_num_bytes(value) + 1;
+       u_char *buf = xmalloc(bytes);
+       int oi;
+       int hasnohigh = 0;
+
+       buf[0] = '\0';
+       /* Get the value of in binary */
+       oi = BN_bn2bin(value, buf+1);
+       if (oi != bytes-1)
+               fatal("buffer_put_bignum: BN_bn2bin() failed: oi %d != bin_size %d",
+                   oi, bytes);
+       hasnohigh = (buf[1] & 0x80) ? 0 : 1;
+       if (BN_is_negative(value)) {
+               /**XXX should be two's-complement */
+               int i, carry;
+               u_char *uc = buf;
+               logit("negativ!");
+               for (i = bytes-1, carry = 1; i>=0; i--) {
+                       uc[i] ^= 0xff;
+                       if (carry)
+                               carry = !++uc[i];
+               }
+       }
+       buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh);
+       memset(buf, 0, bytes);
+       xfree(buf);
+}
+
+/* XXX does not handle negative BNs */
+void
+buffer_get_bignum2(Buffer *buffer, BIGNUM *value)
+{
+       u_int len;
+       u_char *bin = buffer_get_string(buffer, &len);
+
+       if (len > 8 * 1024)
+               fatal("buffer_get_bignum2: cannot handle BN of size %d", len);
+       BN_bin2bn(bin, len, value);
+       xfree(bin);
+}
+/*
+ * Returns integers from the buffer (msb first).
+ */
+
+uint16_t
+buffer_get_short(Buffer *buffer)
+{
+       u_char buf[2];
+
+       buffer_get(buffer, buf, 2);
+       return GET_16BIT(buf);
+}
+
+uint32_t
+buffer_get_int(Buffer *buffer)
+{
+       u_char buf[4];
+
+       buffer_get(buffer, buf, 4);
+       return GET_32BIT(buf);
+}
+
+u_int64_t
+buffer_get_int64(Buffer *buffer)
+{
+       u_char buf[8];
+
+       buffer_get(buffer, (char *) buf, 8);
+       return GET_64BIT(buf);
+}
+
+/*
+ * Stores integers in the buffer, msb first.
+ */
+void
+buffer_put_short(Buffer *buffer, uint16_t value)
+{
+       u_char buf[2];
+
+       PUT_16BIT(buf, value);
+       buffer_append(buffer, buf, 2);
+}
+
+void
+buffer_put_int(Buffer *buffer, uint32_t value)
+{
+       u_char buf[4];
+
+       PUT_32BIT(buf, value);
+       buffer_append(buffer, buf, 4);
+}
+
+void
+buffer_put_int64(Buffer *buffer, u_int64_t value)
+{
+       char buf[8];
+
+       PUT_64BIT(buf, value);
+       buffer_append(buffer, buf, 8);
+}
+
+/*
+ * Returns an arbitrary binary string from the buffer.  The string cannot
+ * be longer than 62k.  The returned value points to memory allocated
+ * with xmalloc; it is the responsibility of the calling function to free
+ * the data.  If length_ptr is non-NULL, the length of the returned data
+ * will be stored there.  A null character will be automatically appended
+ * to the returned string, and is not counted in length.
+ */
+uint8_t *
+buffer_get_string(Buffer *buffer, uint16_t *length_ptr)
+{
+       u_char *value;
+       uint32_t len;
+
+       /* Get the length. */
+       len = buffer_get_int(buffer);
+       if (len > 62 * 1024L)
+               fatal("buffer_get_string: bad string length %u", len);
+       /* Allocate space for the string.  Add one byte for a null character. */
+       value = xmalloc(len + 1);
+       /* Get the string. */
+       buffer_get(buffer, value, len);
+       /* Append a null character to make processing easier. */
+       value[len] = 0;
+       /* Optionally return the length of the string. */
+       if (length_ptr)
+               *length_ptr = len;
+       return value;
+}
+
+/*
+ * Stores and arbitrary binary string in the buffer.
+ */
+void
+buffer_put_string(Buffer *buffer, const uint8_t *buf, uint16_t len)
+{
+       buffer_put_int(buffer, len);
+       buffer_append(buffer, buf, len);
+}
+void
+buffer_put_cstring(Buffer *buffer, const char *s)
+{
+       if (s == NULL)
+               fatal("buffer_put_cstring: s == NULL");
+       buffer_put_string(buffer, s, strlen(s));
+}
+
+/*
+ * Returns a character from the buffer (0 - 255).
+ */
+uint8_t
+buffer_get_char(Buffer *buffer)
+{
+       char ch;
+
+       buffer_get(buffer, &ch, 1);
+       return ch;
+}
+
+/*
+ * Stores a character in the buffer.
+ */
+void
+buffer_put_char(Buffer *buffer, uint8_t value)
+{
+       char ch = value;
+
+       buffer_append(buffer, &ch, 1);
+}
diff --git a/ssh/openssh/bufaux.h b/ssh/openssh/bufaux.h
new file mode 100644 (file)
index 0000000..f8730fc
--- /dev/null
@@ -0,0 +1,73 @@
+/*     $OpenBSD: bufaux.h,v 1.18 2002/04/20 09:14:58 markus Exp $      */
+
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// use stdint types everywhere
+// added buffer_require_empty
+
+#ifndef BUFAUX_H
+#define BUFAUX_H
+
+#include "buffer.h"
+#include "crypto/openssl/bn/bn.h"
+
+void    buffer_require_empty(Buffer *);
+void    buffer_put_bignum(Buffer *, BIGNUM *);
+void    buffer_put_bignum2(Buffer *, BIGNUM *);
+void   buffer_get_bignum(Buffer *, BIGNUM *);
+void   buffer_get_bignum2(Buffer *, BIGNUM *);
+
+uint16_t       buffer_get_short(Buffer *);
+void   buffer_put_short(Buffer *, uint16_t);
+
+uint32_t       buffer_get_int(Buffer *);
+void    buffer_put_int(Buffer *, uint32_t);
+
+uint64_t buffer_get_int64(Buffer *);
+void   buffer_put_int64(Buffer *, uint64_t);
+
+uint8_t    buffer_get_char(Buffer *);
+void    buffer_put_char(Buffer *, uint8_t);
+
+uint8_t *buffer_get_string(Buffer *, uint16_t *);
+void    buffer_put_string(Buffer *, const uint8_t *, uint16_t);
+void   buffer_put_cstring(Buffer *, const char *);
+
+#define buffer_skip_string(b) \
+    do { uint32_t l = buffer_get_int(b); buffer_consume(b, l); } while(0)
+
+#endif                         /* BUFAUX_H */
diff --git a/ssh/openssh/buffer.c b/ssh/openssh/buffer.c
new file mode 100644 (file)
index 0000000..4e19c99
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ * Functions for manipulating fifo buffers (that can grow if needed).
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// replace fprintf with printf
+// use stdint types everywhere
+// decrease max allocation size to 62KB
+
+
+#include "includes.h"
+RCSID("$OpenBSD: buffer.c,v 1.19 2003/09/18 07:54:48 markus Exp $");
+
+#include "xmalloc.h"
+#include "buffer.h"
+
+// 62 KB. Palm max is a little under 64 KB; this is low enough.
+#define PALM_MAX_ALLOC 63488
+
+/* Initializes the buffer structure. */
+
+void
+buffer_init(Buffer *buffer)
+{
+       const uint16_t len = 4096;
+
+       buffer->alloc = 0;
+       buffer->buf = xmalloc(len);
+       buffer->alloc = len;
+       buffer->offset = 0;
+       buffer->end = 0;
+}
+
+/* Frees any memory used for the buffer. */
+
+void
+buffer_free(Buffer *buffer)
+{
+       if (buffer->alloc > 0) {
+               memset(buffer->buf, 0, buffer->alloc);
+               buffer->alloc = 0;
+               xfree(buffer->buf);
+       }
+}
+
+/*
+ * Clears any data from the buffer, making it empty.  This does not actually
+ * zero the memory.
+ */
+
+void
+buffer_clear(Buffer *buffer)
+{
+       buffer->offset = 0;
+       buffer->end = 0;
+}
+
+/* Appends data to the buffer, expanding it if necessary. */
+
+void
+buffer_append(Buffer *buffer, const void *data, uint16_t len)
+{
+       void *p;
+       p = buffer_append_space(buffer, len);
+       memcpy(p, data, len);
+}
+
+/*
+ * Appends space to the buffer, expanding the buffer if necessary. This does
+ * not actually copy the data into the buffer, but instead returns a pointer
+ * to the allocated region.
+ */
+
+void *
+buffer_append_space(Buffer *buffer, uint16_t len)
+{
+       uint16_t newlen;
+       void *p;
+
+       if (len > PALM_MAX_ALLOC)
+               fatal("buffer_append_space: len %u not supported", len);
+
+       /* If the buffer is empty, start using it from the beginning. */
+       if (buffer->offset == buffer->end) {
+               buffer->offset = 0;
+               buffer->end = 0;
+       }
+restart:
+       /* If there is enough space to store all data, store it now. */
+       if (len < buffer->alloc - buffer->end) {
+               p = buffer->buf + buffer->end;
+               buffer->end += len;
+               return p;
+       }
+       /*
+        * If the buffer is quite empty, but all data is at the end, move the
+        * data to the beginning and retry.
+        */
+       // GrP pssh: always move data to minimize memory footprint 
+       // and prevent unnecessary "allocation too big" errors
+       if (buffer->offset > 0) {
+               memmove(buffer->buf, buffer->buf + buffer->offset,
+                       buffer->end - buffer->offset);
+               buffer->end -= buffer->offset;
+               buffer->offset = 0;
+               goto restart;
+       }
+       /* Increase the size of the buffer and retry. */
+       
+       if (len > PALM_MAX_ALLOC - buffer->alloc)
+               fatal("buffer_append_space: alloc %lu not supported",
+                   (uint32_t)buffer->alloc + len);
+       newlen = buffer->alloc + len;
+       // add 4096 extra bytes, but only up to MAX_ALLOC total
+       if (newlen <= PALM_MAX_ALLOC - 4096)
+               newlen += 4096;
+       else
+               newlen = PALM_MAX_ALLOC;
+       buffer->buf = xrealloc(buffer->buf, newlen);
+       buffer->alloc = newlen;
+       goto restart;
+       /* NOTREACHED */
+}
+
+/* Returns the number of bytes of data in the buffer. */
+
+uint16_t
+buffer_len(Buffer *buffer)
+{
+       return buffer->end - buffer->offset;
+}
+
+/* Gets data from the beginning of the buffer. */
+
+void
+buffer_get(Buffer *buffer, void *buf, uint16_t len)
+{
+       if (len > buffer->end - buffer->offset)
+               fatal("buffer_get: trying to get more bytes %d than in buffer %d",
+                   len, buffer->end - buffer->offset);
+       memcpy(buf, buffer->buf + buffer->offset, len);
+       buffer->offset += len;
+}
+
+/* Consumes the given number of bytes from the beginning of the buffer. */
+
+void
+buffer_consume(Buffer *buffer, uint16_t bytes)
+{
+       if (bytes > buffer->end - buffer->offset)
+               fatal("buffer_consume: trying to get more bytes than in buffer");
+       buffer->offset += bytes;
+}
+
+/* Consumes the given number of bytes from the end of the buffer. */
+
+void 
+buffer_consume_end(Buffer *buffer, uint16_t bytes)
+{
+       if (bytes > buffer->end - buffer->offset)
+               fatal("buffer_consume_end: trying to get more bytes than in buffer");
+       buffer->end -= bytes;
+}
+
+/* Returns a pointer to the first used byte in the buffer. */
+
+void *
+buffer_ptr(Buffer *buffer)
+{
+       return buffer->buf + buffer->offset;
+}
+
+/* Dumps the contents of the buffer to stderr. */
+
+void
+buffer_dump(Buffer *buffer)
+{
+       uint16_t i;
+       uint8_t *ucp = buffer->buf;
+
+       for (i = buffer->offset; i < buffer->end; i++) {
+               printf("%02x", ucp[i]);
+               if ((i-buffer->offset)%16==15)
+                       printf("\n");
+               else if ((i-buffer->offset)%2==1)
+                       printf(" ");
+       }
+       printf("\r\n");
+}
diff --git a/ssh/openssh/buffer.h b/ssh/openssh/buffer.h
new file mode 100644 (file)
index 0000000..ca02c54
--- /dev/null
@@ -0,0 +1,69 @@
+/*     $OpenBSD: buffer.h,v 1.11 2002/03/04 17:27:39 stevesk Exp $     */
+
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ * Code for manipulating FIFO buffers.
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// use stdint types everywhere
+
+#ifndef BUFFER_H
+#define BUFFER_H
+
+typedef struct {
+       uint8_t *buf;           /* Buffer for data. */
+       uint16_t         alloc;         /* Number of bytes allocated for data. */
+       uint16_t         offset;        /* Offset of first byte containing data. */
+       uint16_t         end;           /* Offset of last byte containing data. */
+}       Buffer;
+
+void    buffer_init(Buffer *);
+void    buffer_clear(Buffer *);
+void    buffer_free(Buffer *);
+
+uint16_t buffer_len(Buffer *);
+void   *buffer_ptr(Buffer *);
+
+void    buffer_append(Buffer *, const void *, uint16_t);
+void   *buffer_append_space(Buffer *, uint16_t);
+
+void    buffer_get(Buffer *, void *, uint16_t);
+
+void    buffer_consume(Buffer *, uint16_t);
+void    buffer_consume_end(Buffer *, uint16_t);
+
+void     buffer_dump(Buffer *);
+
+#endif                         /* BUFFER_H */
diff --git a/ssh/openssh/cipher.c b/ssh/openssh/cipher.c
new file mode 100644 (file)
index 0000000..b32027e
--- /dev/null
@@ -0,0 +1,451 @@
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ *
+ *
+ * Copyright (c) 1999 Niels Provos.  All rights reserved.
+ * Copyright (c) 1999, 2000 Markus Friedl.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// disabled most ciphers
+// disabled ssh1
+
+#include "includes.h"
+RCSID("$OpenBSD: cipher.c,v 1.65 2003/05/17 04:27:52 markus Exp $");
+
+#include "xmalloc.h"
+#include "cipher.h"
+
+#if OPENSSL_VERSION_NUMBER < 0x00906000L
+#define SSH_OLD_EVP
+#define EVP_CIPHER_CTX_get_app_data(e)          ((e)->app_data)
+#endif
+
+#if OPENSSL_VERSION_NUMBER < 0x00907000L
+extern const EVP_CIPHER *evp_rijndael(void);
+extern void ssh_rijndael_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
+#endif
+extern const EVP_CIPHER *evp_ssh1_bf(void);
+extern const EVP_CIPHER *evp_ssh1_3des(void);
+extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
+extern const EVP_CIPHER *evp_aes_128_ctr(void);
+extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
+
+struct Cipher {
+       char    *name;
+       int     number;         /* for ssh1 only */
+       u_int   block_size;
+       u_int   key_len;
+       const EVP_CIPHER        *(*evptype)(void);
+} ciphers[] = {
+       { "none",               SSH_CIPHER_NONE, 8, 0, EVP_enc_null },
+       // { "des",             SSH_CIPHER_DES, 8, 8, EVP_des_cbc },
+       // { "3des",            SSH_CIPHER_3DES, 8, 16, evp_ssh1_3des },
+       // { "blowfish",                SSH_CIPHER_BLOWFISH, 8, 32, evp_ssh1_bf },
+
+       { "3des-cbc",           SSH_CIPHER_SSH2, 8, 24, EVP_des_ede3_cbc },
+       // { "blowfish-cbc",    SSH_CIPHER_SSH2, 8, 16, EVP_bf_cbc },
+       // { "cast128-cbc",     SSH_CIPHER_SSH2, 8, 16, EVP_cast5_cbc },
+       // { "arcfour",                 SSH_CIPHER_SSH2, 8, 16, EVP_rc4 },
+#if OPENSSL_VERSION_NUMBER < 0x00907000L
+       // { "aes128-cbc",      SSH_CIPHER_SSH2, 16, 16, evp_rijndael },
+       // { "aes192-cbc",      SSH_CIPHER_SSH2, 16, 24, evp_rijndael },
+       // { "aes256-cbc",      SSH_CIPHER_SSH2, 16, 32, evp_rijndael },
+       // { "rijndael-cbc@lysator.liu.se",
+        // SSH_CIPHER_SSH2, 16, 32, evp_rijndael },
+#else
+       { "aes128-cbc",         SSH_CIPHER_SSH2, 16, 16, EVP_aes_128_cbc },
+       // { "aes192-cbc",              SSH_CIPHER_SSH2, 16, 24, EVP_aes_192_cbc },
+       // { "aes256-cbc",              SSH_CIPHER_SSH2, 16, 32, EVP_aes_256_cbc },
+       // { "rijndael-cbc@lysator.liu.se",
+       //                      SSH_CIPHER_SSH2, 16, 32, EVP_aes_256_cbc },
+#endif
+#if OPENSSL_VERSION_NUMBER >= 0x00906000L
+       // { "aes128-ctr",      SSH_CIPHER_SSH2, 16, 16, evp_aes_128_ctr },
+       // { "aes192-ctr",      SSH_CIPHER_SSH2, 16, 24, evp_aes_128_ctr },
+       // { "aes256-ctr",      SSH_CIPHER_SSH2, 16, 32, evp_aes_128_ctr },
+#endif
+
+       { NULL,                 SSH_CIPHER_ILLEGAL, 0, 0, NULL }
+};
+
+/*--*/
+
+u_int
+cipher_blocksize(Cipher *c)
+{
+       return (c->block_size);
+}
+
+u_int
+cipher_keylen(Cipher *c)
+{
+       return (c->key_len);
+}
+
+u_int
+cipher_get_number(Cipher *c)
+{
+       return (c->number);
+}
+
+u_int
+cipher_mask_ssh1(int client)
+{
+       u_int mask = 0;
+       mask |= 1 << SSH_CIPHER_3DES;           /* Mandatory */
+       mask |= 1 << SSH_CIPHER_BLOWFISH;
+       if (client) {
+               mask |= 1 << SSH_CIPHER_DES;
+       }
+       return mask;
+}
+
+Cipher *
+cipher_by_name(const char *name)
+{
+       Cipher *c;
+       for (c = ciphers; c->name != NULL; c++)
+               if (strcasecmp(c->name, name) == 0)
+                       return c;
+       return NULL;
+}
+
+Cipher *
+cipher_by_number(int id)
+{
+       Cipher *c;
+       for (c = ciphers; c->name != NULL; c++)
+               if (c->number == id)
+                       return c;
+       return NULL;
+}
+
+#define        CIPHER_SEP      ","
+int
+ciphers_valid(const char *names)
+{
+       Cipher *c;
+       char *ciphers, *cp;
+       char *p;
+
+       if (names == NULL || strcmp(names, "") == 0)
+               return 0;
+       ciphers = cp = xstrdup(names);
+       for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
+           (p = strsep(&cp, CIPHER_SEP))) {
+               c = cipher_by_name(p);
+               if (c == NULL || c->number != SSH_CIPHER_SSH2) {
+                       debug1("bad cipher %s [%s]", p, names);
+                       xfree(ciphers);
+                       return 0;
+               } else {
+                       debug3("cipher ok: %s [%s]", p, names);
+               }
+       }
+       debug3("ciphers ok: [%s]", names);
+       xfree(ciphers);
+       return 1;
+}
+
+/*
+ * Parses the name of the cipher.  Returns the number of the corresponding
+ * cipher, or -1 on error.
+ */
+
+int
+cipher_number(const char *name)
+{
+       Cipher *c;
+       if (name == NULL)
+               return -1;
+       c = cipher_by_name(name);
+       return (c==NULL) ? -1 : c->number;
+}
+
+char *
+cipher_name(int id)
+{
+       Cipher *c = cipher_by_number(id);
+       return (c==NULL) ? "<unknown>" : c->name;
+}
+
+void
+cipher_init(CipherContext *cc, Cipher *cipher,
+    const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
+    int encrypt)
+{
+       static int dowarn = 1;
+#ifdef SSH_OLD_EVP
+       EVP_CIPHER *type;
+#else
+       const EVP_CIPHER *type;
+#endif
+       int klen;
+
+       if (cipher->number == SSH_CIPHER_DES) {
+               if (dowarn) {
+                       error("Warning: use of DES is strongly discouraged "
+                           "due to cryptographic weaknesses");
+                       dowarn = 0;
+               }
+               if (keylen > 8)
+                       keylen = 8;
+       }
+       cc->plaintext = (cipher->number == SSH_CIPHER_NONE);
+
+       if (keylen < cipher->key_len)
+               fatal("cipher_init: key length %d is insufficient for %s.",
+                   keylen, cipher->name);
+       if (iv != NULL && ivlen < cipher->block_size)
+               fatal("cipher_init: iv length %d is insufficient for %s.",
+                   ivlen, cipher->name);
+       cc->cipher = cipher;
+
+       type = (*cipher->evptype)();
+
+       EVP_CIPHER_CTX_init(&cc->evp);
+#ifdef SSH_OLD_EVP
+       if (type->key_len > 0 && type->key_len != keylen) {
+               debug1("cipher_init: set keylen (%d -> %d)",
+                   type->key_len, keylen);
+               type->key_len = keylen;
+       }
+       EVP_CipherInit(&cc->evp, type, (u_char *)key, (u_char *)iv,
+           (encrypt == CIPHER_ENCRYPT));
+#else
+       if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv,
+           (encrypt == CIPHER_ENCRYPT)) == 0)
+               fatal("cipher_init: EVP_CipherInit failed for %s",
+                   cipher->name);
+       klen = EVP_CIPHER_CTX_key_length(&cc->evp);
+       if (klen > 0 && keylen != klen) {
+               debug2("cipher_init: set keylen (%d -> %d)", klen, keylen);
+               if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0)
+                       fatal("cipher_init: set keylen failed (%d -> %d)",
+                           klen, keylen);
+       }
+       if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0)
+               fatal("cipher_init: EVP_CipherInit: set key failed for %s",
+                   cipher->name);
+#endif
+}
+
+void
+cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
+{
+       if (len % cc->cipher->block_size)
+               fatal("cipher_encrypt: bad plaintext length %d", len);
+#ifdef SSH_OLD_EVP
+       EVP_Cipher(&cc->evp, dest, (u_char *)src, len);
+#else
+       if (EVP_Cipher(&cc->evp, dest, (u_char *)src, len) == 0)
+               fatal("evp_crypt: EVP_Cipher failed");
+#endif
+}
+
+void
+cipher_cleanup(CipherContext *cc)
+{
+#ifdef SSH_OLD_EVP
+       EVP_CIPHER_CTX_cleanup(&cc->evp);
+#else
+       if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
+               error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed");
+#endif
+}
+
+#if 0
+/*
+ * Selects the cipher, and keys if by computing the MD5 checksum of the
+ * passphrase and using the resulting 16 bytes as the key.
+ */
+
+void
+cipher_set_key_string(CipherContext *cc, Cipher *cipher,
+    const char *passphrase, int encrypt)
+{
+       MD5_CTX md;
+       u_char digest[16];
+
+       MD5_Init(&md);
+       MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase));
+       MD5_Final(digest, &md);
+
+       cipher_init(cc, cipher, digest, 16, NULL, 0, encrypt);
+
+       memset(digest, 0, sizeof(digest));
+       memset(&md, 0, sizeof(md));
+}
+
+/*
+ * Exports an IV from the CipherContext required to export the key
+ * state back from the unprivileged child to the privileged parent
+ * process.
+ */
+
+int
+cipher_get_keyiv_len(CipherContext *cc)
+{
+       Cipher *c = cc->cipher;
+       int ivlen;
+
+       if (c->number == SSH_CIPHER_3DES)
+               ivlen = 24;
+       else
+               ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp);
+       return (ivlen);
+}
+
+void
+cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len)
+{
+       Cipher *c = cc->cipher;
+       int evplen;
+
+       switch (c->number) {
+       case SSH_CIPHER_SSH2:
+       case SSH_CIPHER_DES:
+       case SSH_CIPHER_BLOWFISH:
+               evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
+               if (evplen == 0)
+                       return;
+               if (evplen != len)
+                       fatal("%s: wrong iv length %d != %d", __func__,
+                           evplen, len);
+#if OPENSSL_VERSION_NUMBER < 0x00907000L
+               if (c->evptype == evp_rijndael)
+                       ssh_rijndael_iv(&cc->evp, 0, iv, len);
+               else
+#endif
+               if (c->evptype == evp_aes_128_ctr)
+                       ssh_aes_ctr_iv(&cc->evp, 0, iv, len);
+               else
+                       memcpy(iv, cc->evp.iv, len);
+               break;
+       case SSH_CIPHER_3DES:
+               ssh1_3des_iv(&cc->evp, 0, iv, 24);
+               break;
+       default:
+               fatal("%s: bad cipher %d", __func__, c->number);
+       }
+}
+
+void
+cipher_set_keyiv(CipherContext *cc, u_char *iv)
+{
+       Cipher *c = cc->cipher;
+       int evplen = 0;
+
+       switch (c->number) {
+       case SSH_CIPHER_SSH2:
+       case SSH_CIPHER_DES:
+       case SSH_CIPHER_BLOWFISH:
+               evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
+               if (evplen == 0)
+                       return;
+#if OPENSSL_VERSION_NUMBER < 0x00907000L
+               if (c->evptype == evp_rijndael)
+                       ssh_rijndael_iv(&cc->evp, 1, iv, evplen);
+               else
+#endif
+               if (c->evptype == evp_aes_128_ctr)
+                       ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen);
+               else
+                       memcpy(cc->evp.iv, iv, evplen);
+               break;
+       case SSH_CIPHER_3DES:
+               ssh1_3des_iv(&cc->evp, 1, iv, 24);
+               break;
+       default:
+               fatal("%s: bad cipher %d", __func__, c->number);
+       }
+}
+
+#if OPENSSL_VERSION_NUMBER < 0x00907000L
+#define EVP_X_STATE(evp)       &(evp).c
+#define EVP_X_STATE_LEN(evp)   sizeof((evp).c)
+#else
+#define EVP_X_STATE(evp)       (evp).cipher_data
+#define EVP_X_STATE_LEN(evp)   (evp).cipher->ctx_size
+#endif
+
+int
+cipher_get_keycontext(CipherContext *cc, u_char *dat)
+{
+       Cipher *c = cc->cipher;
+       int plen = 0;
+
+       if (c->evptype == EVP_rc4) {
+               plen = EVP_X_STATE_LEN(cc->evp);
+               if (dat == NULL)
+                       return (plen);
+               memcpy(dat, EVP_X_STATE(cc->evp), plen);
+       }
+       return (plen);
+}
+
+void
+cipher_set_keycontext(CipherContext *cc, u_char *dat)
+{
+       Cipher *c = cc->cipher;
+       int plen;
+
+       if (c->evptype == EVP_rc4) {
+               plen = EVP_X_STATE_LEN(cc->evp);
+               memcpy(EVP_X_STATE(cc->evp), dat, plen);
+       }
+}
+#endif
diff --git a/ssh/openssh/cipher.h b/ssh/openssh/cipher.h
new file mode 100644 (file)
index 0000000..e30f0e6
--- /dev/null
@@ -0,0 +1,117 @@
+/*     $OpenBSD: cipher.h,v 1.33 2002/03/18 17:13:15 markus Exp $      */
+
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ *
+ * Copyright (c) 2000 Markus Friedl.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+
+#ifndef CIPHER_H
+#define CIPHER_H
+
+#include "crypto/openssl/evp/evp.h"
+/*
+ * Cipher types for SSH-1.  New types can be added, but old types should not
+ * be removed for compatibility.  The maximum allowed value is 31.
+ */
+#define SSH_CIPHER_SSH2                -3
+#define SSH_CIPHER_ILLEGAL     -2      /* No valid cipher selected. */
+#define SSH_CIPHER_NOT_SET     -1      /* None selected (invalid number). */
+#define SSH_CIPHER_NONE                0       /* no encryption */
+#define SSH_CIPHER_IDEA                1       /* IDEA CFB */
+#define SSH_CIPHER_DES         2       /* DES CBC */
+#define SSH_CIPHER_3DES                3       /* 3DES CBC */
+#define SSH_CIPHER_BROKEN_TSS  4       /* TRI's Simple Stream encryption CBC */
+#define SSH_CIPHER_BROKEN_RC4  5       /* Alleged RC4 */
+#define SSH_CIPHER_BLOWFISH    6
+#define SSH_CIPHER_RESERVED    7
+#define SSH_CIPHER_MAX         31
+
+#define CIPHER_ENCRYPT         1
+#define CIPHER_DECRYPT         0
+
+typedef struct Cipher Cipher;
+typedef struct CipherContext CipherContext;
+
+struct Cipher;
+struct CipherContext {
+       int     plaintext;
+       EVP_CIPHER_CTX evp;
+       Cipher *cipher;
+};
+
+u_int   cipher_mask_ssh1(int);
+Cipher *cipher_by_name(const char *);
+Cipher *cipher_by_number(int);
+int     cipher_number(const char *);
+char   *cipher_name(int);
+int     ciphers_valid(const char *);
+void    cipher_init(CipherContext *, Cipher *, const u_char *, u_int,
+    const u_char *, u_int, int);
+void    cipher_crypt(CipherContext *, u_char *, const u_char *, u_int);
+void    cipher_cleanup(CipherContext *);
+void    cipher_set_key_string(CipherContext *, Cipher *, const char *, int);
+u_int   cipher_blocksize(Cipher *);
+u_int   cipher_keylen(Cipher *);
+
+u_int   cipher_get_number(Cipher *);
+void    cipher_get_keyiv(CipherContext *, u_char *, u_int);
+void    cipher_set_keyiv(CipherContext *, u_char *);
+int     cipher_get_keyiv_len(CipherContext *);
+int     cipher_get_keycontext(CipherContext *, u_char *);
+void    cipher_set_keycontext(CipherContext *, u_char *);
+#endif                         /* CIPHER_H */
diff --git a/ssh/openssh/dh.c b/ssh/openssh/dh.c
new file mode 100644 (file)
index 0000000..6028727
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2000 Niels Provos.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// removed file of primes
+// moved local static data to file scope to avoid initialization problems
+// use BN_is_negative
+
+#include "includes.h"
+RCSID("$OpenBSD: dh.c,v 1.24 2003/04/08 20:21:28 itojun Exp $");
+
+#include "xmalloc.h"
+
+#include "crypto/openssl/bn/bn.h"
+#include "crypto/openssl/dh/dh.h"
+
+#include "buffer.h"
+#include "cipher.h"
+#include "kex.h"
+#include "dh.h"
+
+/* diffie-hellman-group1-sha1 */
+
+int
+dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
+{
+       int i;
+       int n = BN_num_bits(dh_pub);
+       int bits_set = 0;
+
+       if (BN_is_negative(dh_pub)) {
+               logit("invalid public DH value: negativ");
+               return 0;
+       }
+       for (i = 0; i <= n; i++)
+               if (BN_is_bit_set(dh_pub, i))
+                       bits_set++;
+       debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
+
+       /* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */
+       if (bits_set > 1 && (BN_cmp(dh_pub, dh->p) == -1))
+               return 1;
+       logit("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p));
+       return 0;
+}
+
+void
+dh_gen_key(DH *dh, int need)
+{
+       int i, bits_set = 0, tries = 0;
+
+       if (dh->p == NULL)
+               fatal("dh_gen_key: dh->p == NULL");
+       if (2*need >= BN_num_bits(dh->p))
+               fatal("dh_gen_key: group too small: %d (2*need %d)",
+                   BN_num_bits(dh->p), 2*need);
+       do {
+               if (dh->priv_key != NULL)
+                       BN_clear_free(dh->priv_key);
+               if ((dh->priv_key = BN_new()) == NULL)
+                       fatal("dh_gen_key: BN_new failed");
+               /* generate a 2*need bits random private exponent */
+               if (!BN_rand(dh->priv_key, 2*need, 0, 0))
+                       fatal("dh_gen_key: BN_rand failed");
+               if (DH_generate_key(dh) == 0)
+                       fatal("DH_generate_key");
+               for (i = 0; i <= BN_num_bits(dh->priv_key); i++)
+                       if (BN_is_bit_set(dh->priv_key, i))
+                               bits_set++;
+               debug2("dh_gen_key: priv key bits set: %d/%d",
+                   bits_set, BN_num_bits(dh->priv_key));
+               if (tries++ > 10)
+                       fatal("dh_gen_key: too many bad keys: giving up");
+       } while (!dh_pub_is_valid(dh, dh->pub_key));
+}
+
+#include "pce.h"
+
+DH *
+dh_new_group_asc(const char *gen, const char *modulus)
+{
+       DH *dh;
+        uint32_t ret = 123545;
+
+       if ((dh = DH_new()) == NULL)
+               fatal("dh_new_group_asc: DH_new");
+
+       if (BN_hex2bn(&dh->p, modulus) == 0)
+               fatal("BN_hex2bn p");
+       if (BN_hex2bn(&dh->g, gen) == 0)
+               fatal("BN_hex2bn g");
+
+       return (dh);
+}
+
+/*
+ * This just returns the group, we still need to generate the exchange
+ * value.
+ */
+
+DH *
+dh_new_group(BIGNUM *gen, BIGNUM *modulus)
+{
+       DH *dh;
+
+       if ((dh = DH_new()) == NULL)
+               fatal("dh_new_group: DH_new");
+       dh->p = modulus;
+       dh->g = gen;
+
+       return (dh);
+}
+
+static char *gen = "2", *group1 =
+    "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
+    "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
+    "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
+    "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
+    "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
+    "FFFFFFFF" "FFFFFFFF";
+
+DH *
+dh_new_group1(void)
+{
+       return (dh_new_group_asc(gen, group1));
+}
+
+/*
+ * Estimates the group order for a Diffie-Hellman group that has an
+ * attack complexity approximately the same as O(2**bits).  Estimate
+ * with:  O(exp(1.9223 * (ln q)^(1/3) (ln ln q)^(2/3)))
+ */
+
+int
+dh_estimate(int bits)
+{
+
+       if (bits < 64)
+               return (512);   /* O(2**63) */
+       if (bits < 128)
+               return (1024);  /* O(2**86) */
+       if (bits < 192)
+               return (2048);  /* O(2**116) */
+       return (4096);          /* O(2**156) */
+}
diff --git a/ssh/openssh/dh.h b/ssh/openssh/dh.h
new file mode 100644 (file)
index 0000000..aa55bb6
--- /dev/null
@@ -0,0 +1,79 @@
+/*     $OpenBSD: dh.h,v 1.7 2001/06/26 17:27:23 markus Exp $   */
+
+/*
+ * Copyright (c) 2000 Niels Provos.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// added SSHDH_SEGMENT everywhere
+
+#ifndef DH_H
+#define DH_H
+
+#include "crypto/openssl/bn/bn.h"
+#include "crypto/openssl/dh/dh.h"
+
+struct dhgroup {
+       int size;
+       BIGNUM *g;
+       BIGNUM *p;
+};
+
+DH     *choose_dh(int, int, int) SSHDH_SEGMENT;
+DH     *dh_new_group_asc(const char *, const char *) SSHDH_SEGMENT;
+DH     *dh_new_group(BIGNUM *, BIGNUM *) SSHDH_SEGMENT;
+DH     *dh_new_group1(void) SSHDH_SEGMENT;
+
+void    dh_gen_key(DH *, int) SSHDH_SEGMENT;
+int     dh_pub_is_valid(DH *, BIGNUM *) SSHDH_SEGMENT;
+
+int     dh_estimate(int) SSHDH_SEGMENT;
+
+#define DH_GRP_MIN     1024
+#define DH_GRP_MAX     8192
+
+#endif
diff --git a/ssh/openssh/getput.h b/ssh/openssh/getput.h
new file mode 100644 (file)
index 0000000..d67662f
--- /dev/null
@@ -0,0 +1,84 @@
+/*     $OpenBSD: getput.h,v 1.8 2002/03/04 17:27:39 stevesk Exp $      */
+
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ * Macros for storing and retrieving data in msb first and lsb first order.
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// use stdint types everywhere
+
+#ifndef GETPUT_H
+#define GETPUT_H
+
+/*------------ macros for storing/extracting msb first words -------------*/
+
+#define GET_64BIT(cp) (((uint64_t)(uint8_t)(cp)[0] << 56) | \
+                      ((uint64_t)(uint8_t)(cp)[1] << 48) | \
+                      ((uint64_t)(uint8_t)(cp)[2] << 40) | \
+                      ((uint64_t)(uint8_t)(cp)[3] << 32) | \
+                      ((uint64_t)(uint8_t)(cp)[4] << 24) | \
+                      ((uint64_t)(uint8_t)(cp)[5] << 16) | \
+                      ((uint64_t)(uint8_t)(cp)[6] << 8) | \
+                      ((uint64_t)(uint8_t)(cp)[7]))
+
+#define GET_32BIT(cp) (((uint32_t)(uint8_t)(cp)[0] << 24) | \
+                      ((uint32_t)(uint8_t)(cp)[1] << 16) | \
+                      ((uint32_t)(uint8_t)(cp)[2] << 8) | \
+                      ((uint32_t)(uint8_t)(cp)[3]))
+
+#define GET_16BIT(cp) (((uint32_t)(uint8_t)(cp)[0] << 8) | \
+                      ((uint32_t)(uint8_t)(cp)[1]))
+
+#define PUT_64BIT(cp, value) do { \
+  (cp)[0] = (value) >> 56; \
+  (cp)[1] = (value) >> 48; \
+  (cp)[2] = (value) >> 40; \
+  (cp)[3] = (value) >> 32; \
+  (cp)[4] = (value) >> 24; \
+  (cp)[5] = (value) >> 16; \
+  (cp)[6] = (value) >> 8; \
+  (cp)[7] = (value); } while (0)
+
+#define PUT_32BIT(cp, value) do { \
+  (cp)[0] = (value) >> 24; \
+  (cp)[1] = (value) >> 16; \
+  (cp)[2] = (value) >> 8; \
+  (cp)[3] = (value); } while (0)
+
+#define PUT_16BIT(cp, value) do { \
+  (cp)[0] = (value) >> 8; \
+  (cp)[1] = (value); } while (0)
+
+#endif                         /* GETPUT_H */
diff --git a/ssh/openssh/kex.c b/ssh/openssh/kex.c
new file mode 100644 (file)
index 0000000..9e492f3
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2000, 2001 Markus Friedl.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+
+#include "kex.h"
+#include "session.h"
+#include "crypto/openssl/bn/bn.h"
+#include "crypto/openssl/sha/sha.h"
+#include "crypto/openssl/evp/evp.h"
+#include "xmalloc.h"
+#include "buffer.h"
+#include "bufaux.h"
+
+
+static uint8_t *
+derive_key(int id, int need, 
+           uint8_t *hash, BIGNUM *shared_secret, 
+           uint8_t *session_id, int session_id_len) KEX_SEGMENT;
+
+static uint8_t *
+derive_key(int id, int need, 
+           uint8_t *hash, BIGNUM *shared_secret, 
+           uint8_t *session_id, int session_id_len)
+{
+       Buffer b;
+       const EVP_MD *evp_md = EVP_sha1();
+       EVP_MD_CTX md;
+       char c = id;
+       int have;
+       int mdsz = EVP_MD_size(evp_md);
+       u_char *digest = xmalloc(roundup(need, mdsz));
+
+       buffer_init(&b);
+       buffer_put_bignum2(&b, shared_secret);
+
+       /* K1 = HASH(K || H || "A" || session_id) */
+       EVP_DigestInit(&md, evp_md);
+       EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
+       EVP_DigestUpdate(&md, hash, mdsz);
+       EVP_DigestUpdate(&md, &c, 1);
+       EVP_DigestUpdate(&md, session_id, session_id_len);
+       EVP_DigestFinal(&md, digest, NULL);
+
+       /*
+        * expand key:
+        * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
+        * Key = K1 || K2 || ... || Kn
+        */
+       for (have = mdsz; need > have; have += mdsz) {
+               EVP_DigestInit(&md, evp_md);
+               EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
+               EVP_DigestUpdate(&md, hash, mdsz);
+               EVP_DigestUpdate(&md, digest, have);
+               EVP_DigestFinal(&md, digest + have, NULL);
+       }
+       buffer_free(&b);
+       return digest;
+}
+
+
+void kex_derive_keys(Keys *newInKeys, Keys *newOutKeys, uint16_t need, 
+                     uint8_t hash[SHA_DIGEST_LENGTH], BIGNUM *secret, 
+                     uint8_t *session_id, int session_id_len)
+{
+    int i;
+
+    // derive keys (order IS significant)
+    newOutKeys->enc.iv  = derive_key('A', need, hash, secret, 
+                                     session_id, session_id_len);
+    newInKeys->enc.iv   = derive_key('B', need, hash, secret, 
+                                     session_id, session_id_len);
+    newOutKeys->enc.key = derive_key('C', need, hash, secret, 
+                                     session_id, session_id_len);
+    newInKeys->enc.key  = derive_key('D', need, hash, secret, 
+                                     session_id, session_id_len);
+    newOutKeys->mac.key = derive_key('E', need, hash, secret, 
+                                     session_id, session_id_len);
+    newInKeys->mac.key  = derive_key('F', need, hash, secret, 
+                                     session_id, session_id_len);
+}
diff --git a/ssh/openssh/kex.h b/ssh/openssh/kex.h
new file mode 100644 (file)
index 0000000..80aa7e3
--- /dev/null
@@ -0,0 +1,47 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef KEX_H
+#define KEX_H
+
+#include "includes.h"
+
+#include "session.h"
+#include "buffer.h"
+#include "crypto/openssl/bn/bn.h"
+
+// in kex.c
+void kex_derive_keys(Keys *newInKeys, Keys *newOutKeys, uint16_t need, 
+                     uint8_t hash[SHA_DIGEST_LENGTH], BIGNUM *secret, 
+                     uint8_t *session_id, int session_id_len) KEX_SEGMENT;
+
+// in kexdh.c
+u_char *
+kex_dh_hash(char *client_version_string, char *server_version_string, 
+            Buffer *client_kexinit, Buffer *server_kexinit, 
+            u_char *serverhostkeyblob, uint16_t sbloblen, 
+            BIGNUM *client_dh_pub, BIGNUM *server_dh_pub, 
+            BIGNUM *shared_secret) KEX_SEGMENT;
+
+#endif
diff --git a/ssh/openssh/kexdh.c b/ssh/openssh/kexdh.c
new file mode 100644 (file)
index 0000000..6566406
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2001 Markus Friedl.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// replace kexinit string+len with kexinit Buffer
+// replace global data buffer with heap buffer
+
+#include "includes.h"
+RCSID("$OpenBSD: kexdh.c,v 1.19 2003/02/16 17:09:57 markus Exp $");
+
+#include "crypto/openssl/evp/evp.h"
+
+#include "buffer.h"
+#include "bufaux.h"
+#include "ssh2.h"
+#include "kex.h"
+
+u_char *
+kex_dh_hash(
+    char *client_version_string,
+    char *server_version_string,
+    Buffer *client_kexinit,
+    Buffer *server_kexinit,
+    u_char *serverhostkeyblob, uint16_t sbloblen,
+    BIGNUM *client_dh_pub,
+    BIGNUM *server_dh_pub,
+    BIGNUM *shared_secret)
+{
+       Buffer b;
+       u_char *digest;
+       const EVP_MD *evp_md = EVP_sha1();
+       EVP_MD_CTX md;
+       uint8_t *ckexinit = buffer_ptr(client_kexinit);
+       uint8_t *skexinit = buffer_ptr(server_kexinit);
+       uint16_t ckexinitlen = buffer_len(client_kexinit);
+       uint16_t skexinitlen = buffer_len(server_kexinit);
+
+        digest = arena_malloc(EVP_MD_size(evp_md));
+
+       buffer_init(&b);
+       buffer_put_cstring(&b, client_version_string);
+       buffer_put_cstring(&b, server_version_string);
+
+       // pssh: local_kexinit and remote_kexinit already include message type
+       /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
+       buffer_put_int(&b, ckexinitlen);
+       buffer_append(&b, ckexinit, ckexinitlen);
+       buffer_put_int(&b, skexinitlen);
+       buffer_append(&b, skexinit, skexinitlen);
+
+       buffer_put_string(&b, serverhostkeyblob, sbloblen);
+       buffer_put_bignum2(&b, client_dh_pub);
+       buffer_put_bignum2(&b, server_dh_pub);
+       buffer_put_bignum2(&b, shared_secret);
+
+       EVP_DigestInit(&md, evp_md);
+       EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
+       EVP_DigestFinal(&md, digest, NULL);
+
+       buffer_free(&b);
+       return digest;
+}
diff --git a/ssh/openssh/key.c b/ssh/openssh/key.c
new file mode 100644 (file)
index 0000000..e298631
--- /dev/null
@@ -0,0 +1,421 @@
+/*
+ * Copyright (c) 2000, 2001 Markus Friedl.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// disabled key fingerprinting
+// removed file I/O functions
+// removed SSH 1 keys (KEY_RSA1)
+// remove key generation and signature creation
+
+#include "includes.h"
+RCSID("$OpenBSD: key.c,v 1.54 2003/07/09 13:58:19 avsm Exp $");
+
+#include "openssl/evp/evp.h"
+#include "openssl/dsa/dsa.h"
+#include "openssl/rsa/rsa.h"
+#include "xmalloc.h"
+#include "key.h"
+#include "buffer.h"
+#include "bufaux.h"
+
+Key *
+key_new(int type)
+{
+       Key *k;
+       RSA *rsa;
+       DSA *dsa;
+       k = xmalloc(sizeof(*k));
+       k->type = type;
+       k->flags = 0;
+       k->dsa = NULL;
+       k->rsa = NULL;
+       switch (k->type) {
+       case KEY_RSA:
+               if ((rsa = RSA_new()) == NULL)
+                       fatal("key_new: RSA_new failed");
+               if ((rsa->n = BN_new()) == NULL)
+                       fatal("key_new: BN_new failed");
+               if ((rsa->e = BN_new()) == NULL)
+                       fatal("key_new: BN_new failed");
+               k->rsa = rsa;
+               break;
+       case KEY_DSA:
+               if ((dsa = DSA_new()) == NULL)
+                       fatal("key_new: DSA_new failed");
+               if ((dsa->p = BN_new()) == NULL)
+                       fatal("key_new: BN_new failed");
+               if ((dsa->q = BN_new()) == NULL)
+                       fatal("key_new: BN_new failed");
+               if ((dsa->g = BN_new()) == NULL)
+                       fatal("key_new: BN_new failed");
+               if ((dsa->pub_key = BN_new()) == NULL)
+                       fatal("key_new: BN_new failed");
+               k->dsa = dsa;
+               break;
+       case KEY_UNSPEC:
+               break;
+       default:
+               fatal("key_new: bad key type %d", k->type);
+               break;
+       }
+       return k;
+}
+
+Key *
+key_new_private(int type)
+{
+       Key *k = key_new(type);
+       switch (k->type) {
+       case KEY_RSA:
+               if ((k->rsa->d = BN_new()) == NULL)
+                       fatal("key_new_private: BN_new failed");
+               if ((k->rsa->iqmp = BN_new()) == NULL)
+                       fatal("key_new_private: BN_new failed");
+               if ((k->rsa->q = BN_new()) == NULL)
+                       fatal("key_new_private: BN_new failed");
+               if ((k->rsa->p = BN_new()) == NULL)
+                       fatal("key_new_private: BN_new failed");
+               if ((k->rsa->dmq1 = BN_new()) == NULL)
+                       fatal("key_new_private: BN_new failed");
+               if ((k->rsa->dmp1 = BN_new()) == NULL)
+                       fatal("key_new_private: BN_new failed");
+               break;
+       case KEY_DSA:
+               if ((k->dsa->priv_key = BN_new()) == NULL)
+                       fatal("key_new_private: BN_new failed");
+               break;
+       case KEY_UNSPEC:
+               break;
+       default:
+               break;
+       }
+       return k;
+}
+
+void
+key_free(Key *k)
+{
+       switch (k->type) {
+       case KEY_RSA:
+               if (k->rsa != NULL)
+                       RSA_free(k->rsa);
+               k->rsa = NULL;
+               break;
+       case KEY_DSA:
+               if (k->dsa != NULL)
+                       DSA_free(k->dsa);
+               k->dsa = NULL;
+               break;
+       case KEY_UNSPEC:
+               break;
+       default:
+               fatal("key_free: bad key type %d", k->type);
+               break;
+       }
+       xfree(k);
+}
+int
+key_equal(Key *a, Key *b)
+{
+       if (a == NULL || b == NULL || a->type != b->type)
+               return 0;
+       switch (a->type) {
+       case KEY_RSA:
+               return a->rsa != NULL && b->rsa != NULL &&
+                   BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
+                   BN_cmp(a->rsa->n, b->rsa->n) == 0;
+               break;
+       case KEY_DSA:
+               return a->dsa != NULL && b->dsa != NULL &&
+                   BN_cmp(a->dsa->p, b->dsa->p) == 0 &&
+                   BN_cmp(a->dsa->q, b->dsa->q) == 0 &&
+                   BN_cmp(a->dsa->g, b->dsa->g) == 0 &&
+                   BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0;
+               break;
+       default:
+               fatal("key_equal: bad key type %d", a->type);
+               break;
+       }
+       return 0;
+}
+
+char *
+key_type(Key *k)
+{
+       switch (k->type) {
+       case KEY_RSA:
+               return "RSA";
+               break;
+       case KEY_DSA:
+               return "DSA";
+               break;
+       }
+       return "unknown";
+}
+
+char *
+key_ssh_name(Key *k)
+{
+       switch (k->type) {
+       case KEY_RSA:
+               return "ssh-rsa";
+               break;
+       case KEY_DSA:
+               return "ssh-dss";
+               break;
+       }
+       return "ssh-unknown";
+}
+
+u_int
+key_size(Key *k)
+{
+       switch (k->type) {
+       case KEY_RSA:
+               return BN_num_bits(k->rsa->n);
+               break;
+       case KEY_DSA:
+               return BN_num_bits(k->dsa->p);
+               break;
+       }
+       return 0;
+}
+
+int
+key_type_from_name(char *name)
+{
+       if (strcmp(name, "rsa") == 0) {
+               return KEY_RSA;
+       } else if (strcmp(name, "dsa") == 0) {
+               return KEY_DSA;
+       } else if (strcmp(name, "ssh-rsa") == 0) {
+               return KEY_RSA;
+       } else if (strcmp(name, "ssh-dss") == 0) {
+               return KEY_DSA;
+       }
+       debug2("key_type_from_name: unknown key type '%s'", name);
+       return KEY_UNSPEC;
+}
+
+int
+key_names_valid2(const char *names)
+{
+       char *s, *cp, *p;
+
+       if (names == NULL || strcmp(names, "") == 0)
+               return 0;
+       s = cp = xstrdup(names);
+       for ((p = strsep(&cp, ",")); p && *p != '\0';
+           (p = strsep(&cp, ","))) {
+               switch (key_type_from_name(p)) {
+               case KEY_UNSPEC:
+                       xfree(s);
+                       return 0;
+               }
+       }
+       debug3("key names ok: [%s]", names);
+       xfree(s);
+       return 1;
+}
+
+Key *
+key_from_blob(u_char *blob, u_int blen)
+{
+       Buffer b;
+       char *ktype;
+       int rlen, type;
+       Key *key = NULL;
+
+#ifdef DEBUG_PK
+       dump_base64(stderr, blob, blen);
+#endif
+       buffer_init(&b);
+       buffer_append(&b, blob, blen);
+       ktype = buffer_get_string(&b, NULL);
+       type = key_type_from_name(ktype);
+
+       switch (type) {
+       case KEY_RSA:
+               key = key_new(type);
+               buffer_get_bignum2(&b, key->rsa->e);
+               buffer_get_bignum2(&b, key->rsa->n);
+#ifdef DEBUG_PK
+               RSA_print_fp(stderr, key->rsa, 8);
+#endif
+               break;
+       case KEY_DSA:
+               key = key_new(type);
+               buffer_get_bignum2(&b, key->dsa->p);
+               buffer_get_bignum2(&b, key->dsa->q);
+               buffer_get_bignum2(&b, key->dsa->g);
+               buffer_get_bignum2(&b, key->dsa->pub_key);
+#ifdef DEBUG_PK
+               DSA_print_fp(stderr, key->dsa, 8);
+#endif
+               break;
+       case KEY_UNSPEC:
+               key = key_new(type);
+               break;
+       default:
+               error("key_from_blob: cannot handle type %s", ktype);
+               break;
+       }
+       rlen = buffer_len(&b);
+       if (key != NULL && rlen != 0)
+               error("key_from_blob: remaining bytes in key blob %d", rlen);
+       xfree(ktype);
+       buffer_free(&b);
+       return key;
+}
+
+
+int
+key_to_blob_buffer(Key *key, Buffer *b)
+{
+       int start_len = buffer_len(b);
+
+       if (key == NULL) {
+               error("key_to_blob: key == NULL");
+               return 0;
+       }
+       switch (key->type) {
+       case KEY_DSA:
+               buffer_put_cstring(b, key_ssh_name(key));
+               buffer_put_bignum2(b, key->dsa->p);
+               buffer_put_bignum2(b, key->dsa->q);
+               buffer_put_bignum2(b, key->dsa->g);
+               buffer_put_bignum2(b, key->dsa->pub_key);
+               break;
+       case KEY_RSA:
+               buffer_put_cstring(b, key_ssh_name(key));
+               buffer_put_bignum2(b, key->rsa->e);
+               buffer_put_bignum2(b, key->rsa->n);
+               break;
+       default:
+               error("key_to_blob: unsupported key type %d", key->type);
+               return 0;
+       }
+
+       return buffer_len(b) - start_len;
+}
+
+int
+key_to_blob(Key *key, u_char **blobp, u_int *lenp)
+{
+       Buffer b;
+       int len;
+
+       if (key == NULL) {
+               error("key_to_blob: key == NULL");
+               return 0;
+       }
+       buffer_init(&b);
+
+       if (!key_to_blob_buffer(key, &b)) {
+               buffer_free(&b);
+               return 0;
+       }
+
+       len = buffer_len(&b);
+       if (lenp != NULL)
+               *lenp = len;
+       if (blobp != NULL) {
+               *blobp = xmalloc(len);
+               memcpy(*blobp, buffer_ptr(&b), len);
+       }
+       memset(buffer_ptr(&b), 0, len);
+       buffer_free(&b);
+       return len;
+}
+
+int
+key_sign(
+    Key *key,
+    u_char **sigp, u_int *lenp,
+    u_char *data, u_int datalen)
+{
+       switch (key->type) {
+       case KEY_DSA:
+               return ssh_dss_sign(key, sigp, lenp, data, datalen);
+               break;
+       case KEY_RSA:
+               return ssh_rsa_sign(key, sigp, lenp, data, datalen);
+               break;
+       default:
+               error("key_sign: illegal key type %d", key->type);
+               return -1;
+               break;
+       }
+}
+
+/*
+ * key_verify returns 1 for a correct signature, 0 for an incorrect signature
+ * and -1 on error.
+ */
+int
+key_verify(
+    Key *key,
+    u_char *signature, u_int signaturelen,
+    u_char *data, u_int datalen)
+{
+       if (signaturelen == 0)
+               return -1;
+
+       switch (key->type) {
+       case KEY_DSA:
+               return ssh_dss_verify(key, signature, signaturelen, data, datalen);
+               break;
+       case KEY_RSA:
+               return ssh_rsa_verify(key, signature, signaturelen, data, datalen);
+               break;
+       default:
+               error("key_verify: illegal key type %d", key->type);
+               return -1;
+               break;
+       }
+}
diff --git a/ssh/openssh/key.h b/ssh/openssh/key.h
new file mode 100644 (file)
index 0000000..feb700b
--- /dev/null
@@ -0,0 +1,114 @@
+/*     $OpenBSD: key.h,v 1.22 2003/06/24 08:23:46 markus Exp $ */
+
+/*
+ * Copyright (c) 2000, 2001 Markus Friedl.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// added SSH_SEGMENT everywhere
+
+#ifndef KEY_H
+#define KEY_H
+
+#include "includes.h"
+#include "crypto/openssl/dsa/dsa.h"
+#include "crypto/openssl/rsa/rsa.h"
+#include "ssh/openssh/buffer.h"
+
+typedef struct Key Key;
+enum types {
+       KEY_RSA1,
+       KEY_RSA,
+       KEY_DSA,
+       KEY_UNSPEC
+};
+enum fp_type {
+       SSH_FP_SHA1,
+       SSH_FP_MD5
+};
+enum fp_rep {
+       SSH_FP_HEX,
+       SSH_FP_BUBBLEBABBLE
+};
+
+/* key is stored in external hardware */
+#define KEY_FLAG_EXT           0x0001
+
+struct Key {
+       int      type;
+       int      flags;
+       RSA     *rsa;
+       DSA     *dsa;
+};
+
+Key    *key_new(int) SSH_SEGMENT;
+Key    *key_new_private(int) SSH_SEGMENT;
+void    key_free(Key *) SSH_SEGMENT;
+int     key_equal(Key *, Key *) SSH_SEGMENT;
+char   *key_type(Key *) SSH_SEGMENT;
+u_int   key_size(Key *) SSH_SEGMENT;
+
+int     key_type_from_name(char *) SSH_SEGMENT;
+
+Key    *key_from_blob(u_char *, u_int) SSH_SEGMENT;
+int     key_to_blob(Key *, u_char **, u_int *) SSH_SEGMENT;
+int     key_to_blob_buffer(Key *c, Buffer *b) SSH_SEGMENT;
+char   *key_ssh_name(Key *) SSH_SEGMENT;
+int     key_names_valid2(const char *) SSH_SEGMENT;
+
+int     key_sign(Key *key, u_char **sigp, u_int *lenp, u_char *data, u_int datalen) SSH_SEGMENT;
+int     key_verify(Key *, u_char *, u_int, u_char *, u_int) SSH_SEGMENT;
+
+// in ssh-dss.c
+int     ssh_dss_sign(Key *key, u_char **sigp, u_int *lenp, u_char *data, u_int datalen) SSH_SEGMENT;
+int     ssh_dss_verify(Key *, u_char *, u_int, u_char *, u_int) SSH_SEGMENT;
+
+// in ssh-rsa.c
+int     ssh_rsa_sign(Key *key, u_char **sigp, u_int *lenp, u_char *data, u_int datalen) SSH_SEGMENT;
+int     ssh_rsa_verify(Key *, u_char *, u_int, u_char *, u_int) SSH_SEGMENT;
+
+#endif
diff --git a/ssh/openssh/mac.c b/ssh/openssh/mac.c
new file mode 100644 (file)
index 0000000..f98213d
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2001 Markus Friedl.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// removed most hash algorithms
+// mac_compute allocates a buffer instead of using static data
+
+#include "includes.h"
+RCSID("$OpenBSD: mac.c,v 1.5 2002/05/16 22:02:50 markus Exp $");
+
+#include "crypto/openssl/hmac/hmac.h"
+
+#include "xmalloc.h"
+#include "getput.h"
+#include "cipher.h"
+#include "kex.h"
+#include "mac.h"
+
+struct {
+       char            *name;
+       const EVP_MD *  (*mdfunc)(void);
+       int             truncatebits;   /* truncate digest if != 0 */
+} macs[] = {
+       { "hmac-sha1",                  EVP_sha1, 0, },
+       { "hmac-sha1-96",               EVP_sha1, 96 },
+       // { "hmac-md5",                        EVP_md5, 0 },
+       // { "hmac-md5-96",             EVP_md5, 96 },
+       // { "hmac-ripemd160",          EVP_ripemd160, 0 },
+       // { "hmac-ripemd160@openssh.com",      EVP_ripemd160, 0 },
+       { NULL,                         NULL, 0 }
+};
+
+int
+mac_init(Mac *mac, char *name)
+{
+       int i;
+       for (i = 0; macs[i].name; i++) {
+               if (strcmp(name, macs[i].name) == 0) {
+                       if (mac != NULL) {
+                               mac->name = macs[i].name;
+                               mac->key = NULL;
+                               mac->enabled = 0;
+
+                               mac->md = (*macs[i].mdfunc)();
+                               mac->key_len = mac->mac_len = EVP_MD_size(mac->md);
+                               if (macs[i].truncatebits != 0)
+                                       mac->mac_len = macs[i].truncatebits/8;
+                       }
+                       debug2("mac_init: found %s", name);
+                       return (0);
+               }
+       }
+       debug2("mac_init: unknown %s", name);
+       return (-1);
+}
+
+u_char *
+mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen)
+{
+       HMAC_CTX c;
+       u_char *m;
+       u_char b[4];
+
+       if (mac->key == NULL)
+               fatal("mac_compute: no key");
+       m = xmalloc(mac->mac_len);
+       HMAC_Init(&c, mac->key, mac->key_len, mac->md);
+       PUT_32BIT(b, seqno);
+       HMAC_Update(&c, b, sizeof(b));
+       HMAC_Update(&c, data, datalen);
+       HMAC_Final(&c, m, NULL);
+       HMAC_cleanup(&c);
+       return (m);
+}
+
+/* XXX copied from ciphers_valid */
+#define        MAC_SEP ","
+int
+mac_valid(const char *names)
+{
+       char *maclist, *cp, *p;
+
+       if (names == NULL || strcmp(names, "") == 0)
+               return (0);
+       maclist = cp = xstrdup(names);
+       for ((p = strsep(&cp, MAC_SEP)); p && *p != '\0';
+           (p = strsep(&cp, MAC_SEP))) {
+               if (mac_init(NULL, p) < 0) {
+                       debug1("bad mac %s [%s]", p, names);
+                       xfree(maclist);
+                       return (0);
+               } else {
+                       debug3("mac ok: %s [%s]", p, names);
+               }
+       }
+       debug3("macs ok: [%s]", names);
+       xfree(maclist);
+       return (1);
+}
diff --git a/ssh/openssh/mac.h b/ssh/openssh/mac.h
new file mode 100644 (file)
index 0000000..d33f3db
--- /dev/null
@@ -0,0 +1,71 @@
+/*      $OpenBSD: mac.h,v 1.3 2001/06/26 17:27:24 markus Exp $   */
+/*
+ * Copyright (c) 2001 Markus Friedl.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// moved struct Mac here
+// added MAC_SEGMENT
+
+#ifndef MAC_H
+#define MAC_H
+
+#include "crypto/openssl/evp/evp.h"
+
+typedef struct {
+    char *name;
+    u_int enabled;
+    const EVP_MD *md;
+    u_int mac_len;
+    u_char *key;
+    u_int key_len;
+} Mac;
+
+int     mac_valid(const char *) MAC_SEGMENT;
+int     mac_init(Mac *, char *) MAC_SEGMENT;
+u_char *mac_compute(Mac *, u_int32_t, u_char *, int) MAC_SEGMENT;
+
+#endif
diff --git a/ssh/openssh/match.c b/ssh/openssh/match.c
new file mode 100644 (file)
index 0000000..b62fada
--- /dev/null
@@ -0,0 +1,319 @@
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ * Simple pattern matching, with '*' and '?' as wildcards.
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ */
+/*
+ * Copyright (c) 2000 Markus Friedl.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+
+#include "includes.h"
+RCSID("$OpenBSD: match.c,v 1.19 2002/03/01 13:12:10 markus Exp $");
+
+#include "match.h"
+#include "xmalloc.h"
+#include "ctype.h"
+
+/*
+ * Returns true if the given string matches the pattern (which may contain ?
+ * and * as wildcards), and zero if it does not match.
+ */
+
+int
+match_pattern(const char *s, const char *pattern)
+{
+       for (;;) {
+               /* If at end of pattern, accept if also at end of string. */
+               if (!*pattern)
+                       return !*s;
+
+               if (*pattern == '*') {
+                       /* Skip the asterisk. */
+                       pattern++;
+
+                       /* If at end of pattern, accept immediately. */
+                       if (!*pattern)
+                               return 1;
+
+                       /* If next character in pattern is known, optimize. */
+                       if (*pattern != '?' && *pattern != '*') {
+                               /*
+                                * Look instances of the next character in
+                                * pattern, and try to match starting from
+                                * those.
+                                */
+                               for (; *s; s++)
+                                       if (*s == *pattern &&
+                                           match_pattern(s + 1, pattern + 1))
+                                               return 1;
+                               /* Failed. */
+                               return 0;
+                       }
+                       /*
+                        * Move ahead one character at a time and try to
+                        * match at each position.
+                        */
+                       for (; *s; s++)
+                               if (match_pattern(s, pattern))
+                                       return 1;
+                       /* Failed. */
+                       return 0;
+               }
+               /*
+                * There must be at least one more character in the string.
+                * If we are at the end, fail.
+                */
+               if (!*s)
+                       return 0;
+
+               /* Check if the next character of the string is acceptable. */
+               if (*pattern != '?' && *pattern != *s)
+                       return 0;
+
+               /* Move to the next character, both in string and in pattern. */
+               s++;
+               pattern++;
+       }
+       /* NOTREACHED */
+}
+
+/*
+ * Tries to match the string against the
+ * comma-separated sequence of subpatterns (each possibly preceded by ! to
+ * indicate negation).  Returns -1 if negation matches, 1 if there is
+ * a positive match, 0 if there is no match at all.
+ */
+
+int
+match_pattern_list(const char *string, const char *pattern, u_int len,
+    int dolower)
+{
+       char sub[1024];
+       int negated;
+       int got_positive;
+       u_int i, subi;
+
+       got_positive = 0;
+       for (i = 0; i < len;) {
+               /* Check if the subpattern is negated. */
+               if (pattern[i] == '!') {
+                       negated = 1;
+                       i++;
+               } else
+                       negated = 0;
+
+               /*
+                * Extract the subpattern up to a comma or end.  Convert the
+                * subpattern to lowercase.
+                */
+               for (subi = 0;
+                   i < len && subi < sizeof(sub) - 1 && pattern[i] != ',';
+                   subi++, i++)
+                       sub[subi] = dolower && isupper(pattern[i]) ?
+                           tolower(pattern[i]) : pattern[i];
+               /* If subpattern too long, return failure (no match). */
+               if (subi >= sizeof(sub) - 1)
+                       return 0;
+
+               /* If the subpattern was terminated by a comma, skip the comma. */
+               if (i < len && pattern[i] == ',')
+                       i++;
+
+               /* Null-terminate the subpattern. */
+               sub[subi] = '\0';
+
+               /* Try to match the subpattern against the string. */
+               if (match_pattern(string, sub)) {
+                       if (negated)
+                               return -1;              /* Negative */
+                       else
+                               got_positive = 1;       /* Positive */
+               }
+       }
+
+       /*
+        * Return success if got a positive match.  If there was a negative
+        * match, we have already returned -1 and never get here.
+        */
+       return got_positive;
+}
+
+/*
+ * Tries to match the host name (which must be in all lowercase) against the
+ * comma-separated sequence of subpatterns (each possibly preceded by ! to
+ * indicate negation).  Returns -1 if negation matches, 1 if there is
+ * a positive match, 0 if there is no match at all.
+ */
+int
+match_hostname(const char *host, const char *pattern, u_int len)
+{
+       return match_pattern_list(host, pattern, len, 1);
+}
+
+/*
+ * returns 0 if we get a negative match for the hostname or the ip
+ * or if we get no match at all.  returns 1 otherwise.
+ */
+int
+match_host_and_ip(const char *host, const char *ipaddr,
+    const char *patterns)
+{
+       int mhost, mip;
+
+       /* negative ipaddr match */
+       if ((mip = match_hostname(ipaddr, patterns, strlen(patterns))) == -1)
+               return 0;
+       /* negative hostname match */
+       if ((mhost = match_hostname(host, patterns, strlen(patterns))) == -1)
+               return 0;
+       /* no match at all */
+       if (mhost == 0 && mip == 0)
+               return 0;
+       return 1;
+}
+
+/*
+ * match user, user@host_or_ip, user@host_or_ip_list against pattern
+ */
+int
+match_user(const char *user, const char *host, const char *ipaddr,
+    const char *pattern)
+{
+       char *p, *pat;
+       int ret;
+
+       if ((p = strchr(pattern,'@')) == NULL)
+               return match_pattern(user, pattern);
+
+       pat = xstrdup(pattern);
+       p = strchr(pat, '@');
+       *p++ = '\0';
+
+       if ((ret = match_pattern(user, pat)) == 1)
+               ret = match_host_and_ip(host, ipaddr, p);
+       xfree(pat);
+
+       return ret;
+}
+
+/*
+ * Returns first item from client-list that is also supported by server-list,
+ * caller must xfree() returned string.
+ */
+#define        MAX_PROP        40
+#define        SEP     ","
+char *
+match_list(const char *client, const char *server, u_int *next)
+{
+       char *sproposals[MAX_PROP];
+       char *c, *s, *p, *ret, *cp, *sp;
+       int i, j, nproposals;
+
+       c = cp = xstrdup(client);
+       s = sp = xstrdup(server);
+
+       for ((p = strsep(&sp, SEP)), i=0; p && *p != '\0';
+           (p = strsep(&sp, SEP)), i++) {
+               if (i < MAX_PROP)
+                       sproposals[i] = p;
+               else
+                       break;
+       }
+       nproposals = i;
+
+       for ((p = strsep(&cp, SEP)), i=0; p && *p != '\0';
+           (p = strsep(&cp, SEP)), i++) {
+               for (j = 0; j < nproposals; j++) {
+                       if (strcmp(p, sproposals[j]) == 0) {
+                               ret = xstrdup(p);
+                               if (next != NULL)
+                                       *next = (cp == NULL) ?
+                                           strlen(c) : cp - c;
+                               xfree(c);
+                               xfree(s);
+                               return ret;
+                       }
+               }
+       }
+       if (next != NULL)
+               *next = strlen(c);
+       xfree(c);
+       xfree(s);
+       return NULL;
+}
+
+// strip small from comma-separated list big, modifying big in place
+void remove_match(const char *small, char *big)
+{
+    char *bigcopy;
+    char *b;
+    char *p;
+
+    bigcopy = xstrdup(big);
+    b = bigcopy;
+    while ((p = strsep(&b, SEP))) {
+        if (0 == strcmp(p, small)) {
+            // found small at p - strip it
+            char *end = p + strlen(p) + 1;
+            p = big + (p - bigcopy);
+            end = big + (end - bigcopy);
+            memmove(p, end, 1+strlen(end));
+            break;
+        }
+    }
+    
+    xfree(bigcopy);
+}
diff --git a/ssh/openssh/match.h b/ssh/openssh/match.h
new file mode 100644 (file)
index 0000000..b46b24e
--- /dev/null
@@ -0,0 +1,52 @@
+/*     $OpenBSD: match.h,v 1.12 2002/03/01 13:12:10 markus Exp $       */
+
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// use uint16_t instead of u_int
+
+#ifndef MATCH_H
+#define MATCH_H
+
+int     match_pattern(const char *, const char *) SSH2_SEGMENT;
+int     match_pattern_list(const char *, const char *, uint16_t, int) SSH2_SEGMENT;
+int     match_hostname(const char *, const char *, uint16_t) SSH2_SEGMENT;
+int     match_host_and_ip(const char *, const char *, const char *) SSH2_SEGMENT;
+int     match_user(const char *, const char *, const char *, const char *) SSH2_SEGMENT;
+char   *match_list(const char *, const char *, uint16_t *) SSH2_SEGMENT;
+void    remove_match(const char *small, char *big) SSH2_SEGMENT;
+
+#endif
diff --git a/ssh/openssh/openbsd-compat/base64.c b/ssh/openssh/openbsd-compat/base64.c
new file mode 100644 (file)
index 0000000..0a3a47e
--- /dev/null
@@ -0,0 +1,340 @@
+/*     $OpenBSD: base64.c,v 1.4 2002/01/02 23:00:10 deraadt Exp $      */
+
+/*
+ * Copyright (c) 1996 by 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.
+ */
+
+/*
+ * Portions Copyright (c) 1995 by International Business Machines, Inc.
+ *
+ * International Business Machines, Inc. (hereinafter called IBM) grants
+ * permission under its copyrights to use, copy, modify, and distribute this
+ * Software with or without fee, provided that the above copyright notice and
+ * all paragraphs of this notice appear in all copies, and that the name of IBM
+ * not be used in connection with the marketing of any product incorporating
+ * the Software or modifications thereof, without specific, written prior
+ * permission.
+ *
+ * To the extent it has a right to do so, IBM grants an immunity from suit
+ * under its patents, if any, for the use, sale or manufacture of products to
+ * the extent that such products are used for performing Domain Name System
+ * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
+ * granted for any product per se or for any other function of any product.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// changed assert
+
+#include "includes.h"
+
+#if (!defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP)) || (!defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON))
+
+#include "ctype.h"
+
+#include "base64.h"
+
+/* XXX abort illegal in library */
+#define Assert(Cond) do {if (!(Cond)) return -1; } while (0)
+
+static const char Base64[] =
+       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static const char Pad64 = '=';
+
+/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
+   The following encoding technique is taken from RFC 1521 by Borenstein
+   and Freed.  It is reproduced here in a slightly edited form for
+   convenience.
+
+   A 65-character subset of US-ASCII is used, enabling 6 bits to be
+   represented per printable character. (The extra 65th character, "=",
+   is used to signify a special processing function.)
+
+   The encoding process represents 24-bit groups of input bits as output
+   strings of 4 encoded characters. Proceeding from left to right, a
+   24-bit input group is formed by concatenating 3 8-bit input groups.
+   These 24 bits are then treated as 4 concatenated 6-bit groups, each
+   of which is translated into a single digit in the base64 alphabet.
+
+   Each 6-bit group is used as an index into an array of 64 printable
+   characters. The character referenced by the index is placed in the
+   output string.
+
+                         Table 1: The Base64 Alphabet
+
+      Value Encoding  Value Encoding  Value Encoding  Value Encoding
+          0 A            17 R            34 i            51 z
+          1 B            18 S            35 j            52 0
+          2 C            19 T            36 k            53 1
+          3 D            20 U            37 l            54 2
+          4 E            21 V            38 m            55 3
+          5 F            22 W            39 n            56 4
+          6 G            23 X            40 o            57 5
+          7 H            24 Y            41 p            58 6
+          8 I            25 Z            42 q            59 7
+          9 J            26 a            43 r            60 8
+         10 K            27 b            44 s            61 9
+         11 L            28 c            45 t            62 +
+         12 M            29 d            46 u            63 /
+         13 N            30 e            47 v
+         14 O            31 f            48 w         (pad) =
+         15 P            32 g            49 x
+         16 Q            33 h            50 y
+
+   Special processing is performed if fewer than 24 bits are available
+   at the end of the data being encoded.  A full encoding quantum is
+   always completed at the end of a quantity.  When fewer than 24 input
+   bits are available in an input group, zero bits are added (on the
+   right) to form an integral number of 6-bit groups.  Padding at the
+   end of the data is performed using the '=' character.
+
+   Since all base64 input is an integral number of octets, only the
+         -------------------------------------------------                       
+   following cases can arise:
+   
+       (1) the final quantum of encoding input is an integral
+           multiple of 24 bits; here, the final unit of encoded
+          output will be an integral multiple of 4 characters
+          with no "=" padding,
+       (2) the final quantum of encoding input is exactly 8 bits;
+           here, the final unit of encoded output will be two
+          characters followed by two "=" padding characters, or
+       (3) the final quantum of encoding input is exactly 16 bits;
+           here, the final unit of encoded output will be three
+          characters followed by one "=" padding character.
+   */
+
+#if !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) 
+int
+b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize)
+{
+       size_t datalength = 0;
+       u_char input[3];
+       u_char output[4];
+       int i;
+
+       while (2 < srclength) {
+               input[0] = *src++;
+               input[1] = *src++;
+               input[2] = *src++;
+               srclength -= 3;
+
+               output[0] = input[0] >> 2;
+               output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+               output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
+               output[3] = input[2] & 0x3f;
+               Assert(output[0] < 64);
+               Assert(output[1] < 64);
+               Assert(output[2] < 64);
+               Assert(output[3] < 64);
+
+               if (datalength + 4 > targsize)
+                       return (-1);
+               target[datalength++] = Base64[output[0]];
+               target[datalength++] = Base64[output[1]];
+               target[datalength++] = Base64[output[2]];
+               target[datalength++] = Base64[output[3]];
+       }
+    
+       /* Now we worry about padding. */
+       if (0 != srclength) {
+               /* Get what's left. */
+               input[0] = input[1] = input[2] = '\0';
+               for (i = 0; i < srclength; i++)
+                       input[i] = *src++;
+       
+               output[0] = input[0] >> 2;
+               output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+               output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
+               Assert(output[0] < 64);
+               Assert(output[1] < 64);
+               Assert(output[2] < 64);
+
+               if (datalength + 4 > targsize)
+                       return (-1);
+               target[datalength++] = Base64[output[0]];
+               target[datalength++] = Base64[output[1]];
+               if (srclength == 1)
+                       target[datalength++] = Pad64;
+               else
+                       target[datalength++] = Base64[output[2]];
+               target[datalength++] = Pad64;
+       }
+       if (datalength >= targsize)
+               return (-1);
+       target[datalength] = '\0';      /* Returned value doesn't count \0. */
+       return (datalength);
+}
+#endif /* !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) */
+
+#if !defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON)
+
+/* skips all whitespace anywhere.
+   converts characters, four at a time, starting at (or after)
+   src from base - 64 numbers into three 8 bit bytes in the target area.
+   it returns the number of data bytes stored at the target, or -1 on error.
+ */
+
+int
+b64_pton(char const *src, u_char *target, size_t targsize)
+{
+       int tarindex, state, ch;
+       char *pos;
+
+       state = 0;
+       tarindex = 0;
+
+       while ((ch = *src++) != '\0') {
+               if (isspace(ch))        /* Skip whitespace anywhere. */
+                       continue;
+
+               if (ch == Pad64)
+                       break;
+
+               pos = strchr(Base64, ch);
+               if (pos == 0)           /* A non-base64 character. */
+                       return (-1);
+
+               switch (state) {
+               case 0:
+                       if (target) {
+                               if (tarindex >= targsize)
+                                       return (-1);
+                               target[tarindex] = (pos - Base64) << 2;
+                       }
+                       state = 1;
+                       break;
+               case 1:
+                       if (target) {
+                               if (tarindex + 1 >= targsize)
+                                       return (-1);
+                               target[tarindex]   |=  (pos - Base64) >> 4;
+                               target[tarindex+1]  = ((pos - Base64) & 0x0f)
+                                                       << 4 ;
+                       }
+                       tarindex++;
+                       state = 2;
+                       break;
+               case 2:
+                       if (target) {
+                               if (tarindex + 1 >= targsize)
+                                       return (-1);
+                               target[tarindex]   |=  (pos - Base64) >> 2;
+                               target[tarindex+1]  = ((pos - Base64) & 0x03)
+                                                       << 6;
+                       }
+                       tarindex++;
+                       state = 3;
+                       break;
+               case 3:
+                       if (target) {
+                               if (tarindex >= targsize)
+                                       return (-1);
+                               target[tarindex] |= (pos - Base64);
+                       }
+                       tarindex++;
+                       state = 0;
+                       break;
+               }
+       }
+
+       /*
+        * We are done decoding Base-64 chars.  Let's see if we ended
+        * on a byte boundary, and/or with erroneous trailing characters.
+        */
+
+       if (ch == Pad64) {              /* We got a pad char. */
+               ch = *src++;            /* Skip it, get next. */
+               switch (state) {
+               case 0:         /* Invalid = in first position */
+               case 1:         /* Invalid = in second position */
+                       return (-1);
+
+               case 2:         /* Valid, means one byte of info */
+                       /* Skip any number of spaces. */
+                       for (; ch != '\0'; ch = *src++)
+                               if (!isspace(ch))
+                                       break;
+                       /* Make sure there is another trailing = sign. */
+                       if (ch != Pad64)
+                               return (-1);
+                       ch = *src++;            /* Skip the = */
+                       /* Fall through to "single trailing =" case. */
+                       /* FALLTHROUGH */
+
+               case 3:         /* Valid, means two bytes of info */
+                       /*
+                        * We know this char is an =.  Is there anything but
+                        * whitespace after it?
+                        */
+                       for (; ch != '\0'; ch = *src++)
+                               if (!isspace(ch))
+                                       return (-1);
+
+                       /*
+                        * Now make sure for cases 2 and 3 that the "extra"
+                        * bits that slopped past the last full byte were
+                        * zeros.  If we don't check them, they become a
+                        * subliminal channel.
+                        */
+                       if (target && target[tarindex] != 0)
+                               return (-1);
+               }
+       } else {
+               /*
+                * We ended by seeing the end of the string.  Make sure we
+                * have no partial bytes lying around.
+                */
+               if (state != 0)
+                       return (-1);
+       }
+
+       return (tarindex);
+}
+
+#endif /* !defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON) */
+#endif 
diff --git a/ssh/openssh/openbsd-compat/base64.h b/ssh/openssh/openbsd-compat/base64.h
new file mode 100644 (file)
index 0000000..732c6b3
--- /dev/null
@@ -0,0 +1,65 @@
+/* $Id: base64.h,v 1.6 2003/08/29 16:59:52 mouring Exp $ */
+
+/*
+ * Copyright (c) 1996 by 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.
+ */
+
+/*
+ * Portions Copyright (c) 1995 by International Business Machines, Inc.
+ *
+ * International Business Machines, Inc. (hereinafter called IBM) grants
+ * permission under its copyrights to use, copy, modify, and distribute this
+ * Software with or without fee, provided that the above copyright notice and
+ * all paragraphs of this notice appear in all copies, and that the name of IBM
+ * not be used in connection with the marketing of any product incorporating
+ * the Software or modifications thereof, without specific, written prior
+ * permission.
+ *
+ * To the extent it has a right to do so, IBM grants an immunity from suit
+ * under its patents, if any, for the use, sale or manufacture of products to
+ * the extent that such products are used for performing Domain Name System
+ * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
+ * granted for any product per se or for any other function of any product.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#ifndef _BSD_BASE64_H
+#define _BSD_BASE64_H
+
+#include "includes.h"
+
+#ifndef HAVE___B64_NTOP
+# ifndef HAVE_B64_NTOP
+int b64_ntop(u_char const *src, size_t srclength, char *target, 
+    size_t targsize);
+# endif /* !HAVE_B64_NTOP */
+# define __b64_ntop(a,b,c,d) b64_ntop(a,b,c,d)
+#endif /* HAVE___B64_NTOP */
+
+#ifndef HAVE___B64_PTON
+# ifndef HAVE_B64_PTON
+int b64_pton(char const *src, u_char *target, size_t targsize);
+# endif /* !HAVE_B64_PTON */
+# define __b64_pton(a,b,c) b64_pton(a,b,c)
+#endif /* HAVE___B64_PTON */
+
+#endif /* _BSD_BASE64_H */
diff --git a/ssh/openssh/openbsd-compat/bsd-snprintf.c b/ssh/openssh/openbsd-compat/bsd-snprintf.c
new file mode 100644 (file)
index 0000000..e3c10d9
--- /dev/null
@@ -0,0 +1,659 @@
+/*
+ * Copyright Patrick Powell 1995
+ * This code is based on code written by Patrick Powell (papowell@astart.com)
+ * It may be used for any purpose as long as this notice remains intact
+ * on all source code distributions
+ */
+
+/**************************************************************
+ * Original:
+ * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
+ * A bombproof version of doprnt (dopr) included.
+ * Sigh.  This sort of thing is always nasty do deal with.  Note that
+ * the version here does not include floating point...
+ *
+ * snprintf() is used instead of sprintf() as it does limit checks
+ * for string length.  This covers a nasty loophole.
+ *
+ * The other functions are there to prevent NULL pointers from
+ * causing nast effects.
+ *
+ * More Recently:
+ *  Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
+ *  This was ugly.  It is still ugly.  I opted out of floating point
+ *  numbers, but the formatter understands just about everything
+ *  from the normal C string format, at least as far as I can tell from
+ *  the Solaris 2.5 printf(3S) man page.
+ *
+ *  Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1
+ *    Ok, added some minimal floating point support, which means this
+ *    probably requires libm on most operating systems.  Don't yet
+ *    support the exponent (e,E) and sigfig (g,G).  Also, fmtint()
+ *    was pretty badly broken, it just wasn't being exercised in ways
+ *    which showed it, so that's been fixed.  Also, formated the code
+ *    to mutt conventions, and removed dead code left over from the
+ *    original.  Also, there is now a builtin-test, just compile with:
+ *           gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
+ *    and run snprintf for results.
+ * 
+ *  Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
+ *    The PGP code was using unsigned hexadecimal formats. 
+ *    Unfortunately, unsigned formats simply didn't work.
+ *
+ *  Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
+ *    The original code assumed that both snprintf() and vsnprintf() were
+ *    missing.  Some systems only have snprintf() but not vsnprintf(), so
+ *    the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
+ *
+ *  Ben Lindstrom <mouring@eviladmin.org> 09/27/00 for OpenSSH
+ *    Welcome to the world of %lld and %qd support.  With other
+ *    long long support.  This is needed for sftp-server to work
+ *    right.
+ *
+ *  Ben Lindstrom <mouring@eviladmin.org> 02/12/01 for OpenSSH
+ *    Removed all hint of VARARGS stuff and banished it to the void,
+ *    and did a bit of KNF style work to make things a bit more
+ *    acceptable.  Consider stealing from mutt or enlightenment.
+ **************************************************************/
+
+#include "includes.h"
+#include "ctype.h"
+
+RCSID("$Id: bsd-snprintf.c,v 1.7 2003/05/18 14:13:39 djm Exp $");
+
+#if defined(BROKEN_SNPRINTF)           /* For those with broken snprintf() */
+# undef HAVE_SNPRINTF
+# undef HAVE_VSNPRINTF
+#endif
+
+#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
+
+static void 
+dopr(char *buffer, size_t maxlen, const char *format, va_list args) SSH_SEGMENT;
+
+static void 
+fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, 
+    int min, int max) SSH_SEGMENT;
+
+static void 
+fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base, 
+    int min, int max, int flags) SSH_SEGMENT;
+
+static long double 
+pow10(int exp) SSH_SEGMENT;
+
+static long 
+round(long double value) SSH_SEGMENT;
+
+static void 
+fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, 
+    int min, int max, int flags) SSH_SEGMENT;
+
+static void
+dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c) SSH_SEGMENT;
+
+/*
+ * dopr(): poor man's version of doprintf
+ */
+
+/* format read states */
+#define DP_S_DEFAULT 0
+#define DP_S_FLAGS   1
+#define DP_S_MIN     2
+#define DP_S_DOT     3
+#define DP_S_MAX     4
+#define DP_S_MOD     5
+#define DP_S_CONV    6
+#define DP_S_DONE    7
+
+/* format flags - Bits */
+#define DP_F_MINUS     (1 << 0)
+#define DP_F_PLUS      (1 << 1)
+#define DP_F_SPACE     (1 << 2)
+#define DP_F_NUM       (1 << 3)
+#define DP_F_ZERO      (1 << 4)
+#define DP_F_UP        (1 << 5)
+#define DP_F_UNSIGNED  (1 << 6)
+
+/* Conversion Flags */
+#define DP_C_SHORT     1
+#define DP_C_LONG      2
+#define DP_C_LDOUBLE   3
+#define DP_C_LONG_LONG 4
+
+#define char_to_int(p) (p - '0')
+#define abs_val(p) (p < 0 ? -p : p)
+
+
+static void 
+dopr(char *buffer, size_t maxlen, const char *format, va_list args)
+{
+       char *strvalue, ch;
+       long value;
+       long double fvalue;
+       int min = 0, max = -1, state = DP_S_DEFAULT, flags = 0, cflags = 0;
+       size_t currlen = 0;
+  
+       ch = *format++;
+
+       while (state != DP_S_DONE) {
+               if ((ch == '\0') || (currlen >= maxlen)) 
+                       state = DP_S_DONE;
+
+               switch(state) {
+               case DP_S_DEFAULT:
+                       if (ch == '%') 
+                               state = DP_S_FLAGS;
+                       else 
+                               dopr_outch(buffer, &currlen, maxlen, ch);
+                       ch = *format++;
+                       break;
+               case DP_S_FLAGS:
+                       switch (ch) {
+                       case '-':
+                               flags |= DP_F_MINUS;
+                               ch = *format++;
+                               break;
+                       case '+':
+                               flags |= DP_F_PLUS;
+                               ch = *format++;
+                               break;
+                       case ' ':
+                               flags |= DP_F_SPACE;
+                               ch = *format++;
+                               break;
+                       case '#':
+                               flags |= DP_F_NUM;
+                               ch = *format++;
+                               break;
+                       case '0':
+                               flags |= DP_F_ZERO;
+                               ch = *format++;
+                               break;
+                       default:
+                               state = DP_S_MIN;
+                               break;
+                       }
+                       break;
+               case DP_S_MIN:
+                       if (isdigit((unsigned char)ch)) {
+                               min = 10 * min + char_to_int (ch);
+                               ch = *format++;
+                       } else if (ch == '*') {
+                               min = va_arg (args, int);
+                               ch = *format++;
+                               state = DP_S_DOT;
+                       } else 
+                               state = DP_S_DOT;
+                       break;
+               case DP_S_DOT:
+                       if (ch == '.') {
+                               state = DP_S_MAX;
+                               ch = *format++;
+                       } else 
+                               state = DP_S_MOD;
+                       break;
+               case DP_S_MAX:
+                       if (isdigit((unsigned char)ch)) {
+                               if (max < 0)
+                                       max = 0;
+                               max = 10 * max + char_to_int(ch);
+                               ch = *format++;
+                       } else if (ch == '*') {
+                               max = va_arg (args, int);
+                               ch = *format++;
+                               state = DP_S_MOD;
+                       } else 
+                               state = DP_S_MOD;
+                       break;
+               case DP_S_MOD:
+                       switch (ch) {
+                       case 'h':
+                               cflags = DP_C_SHORT;
+                               ch = *format++;
+                               break;
+                       case 'l':
+                               cflags = DP_C_LONG;
+                               ch = *format++;
+                               if (ch == 'l') {
+                                       cflags = DP_C_LONG_LONG;
+                                       ch = *format++;
+                               }
+                               break;
+                       case 'q':
+                               cflags = DP_C_LONG_LONG;
+                               ch = *format++;
+                               break;
+                       case 'L':
+                               cflags = DP_C_LDOUBLE;
+                               ch = *format++;
+                               break;
+                       default:
+                               break;
+                       }
+                       state = DP_S_CONV;
+                       break;
+               case DP_S_CONV:
+                       switch (ch) {
+                       case 'd':
+                       case 'i':
+                               if (cflags == DP_C_SHORT) 
+                                       value = va_arg(args, int);
+                               else if (cflags == DP_C_LONG)
+                                       value = va_arg(args, long int);
+                               else if (cflags == DP_C_LONG_LONG)
+                                       value = va_arg (args, long long);
+                               else
+                                       value = va_arg (args, int);
+                               fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags);
+                               break;
+                       case 'o':
+                               flags |= DP_F_UNSIGNED;
+                               if (cflags == DP_C_SHORT)
+                                       value = va_arg(args, unsigned int);
+                               else if (cflags == DP_C_LONG)
+                                       value = va_arg(args, unsigned long int);
+                               else if (cflags == DP_C_LONG_LONG)
+                                       value = va_arg(args, unsigned long long);
+                               else
+                                       value = va_arg(args, unsigned int);
+                               fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags);
+                               break;
+                       case 'u':
+                               flags |= DP_F_UNSIGNED;
+                               if (cflags == DP_C_SHORT)
+                                       value = va_arg(args, unsigned int);
+                               else if (cflags == DP_C_LONG)
+                                       value = va_arg(args, unsigned long int);
+                               else if (cflags == DP_C_LONG_LONG)
+                                       value = va_arg(args, unsigned long long);
+                               else
+                                       value = va_arg(args, unsigned int);
+                               fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
+                               break;
+                       case 'X':
+                               flags |= DP_F_UP;
+                       case 'x':
+                               flags |= DP_F_UNSIGNED;
+                               if (cflags == DP_C_SHORT)
+                                       value = va_arg(args, unsigned int);
+                               else if (cflags == DP_C_LONG)
+                                       value = va_arg(args, unsigned long int);
+                               else if (cflags == DP_C_LONG_LONG)
+                                       value = va_arg(args, unsigned long long);
+                               else
+                                       value = va_arg(args, unsigned int);
+                               fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags);
+                               break;
+                       case 'f':
+                               if (cflags == DP_C_LDOUBLE)
+                                       fvalue = va_arg(args, long double);
+                               else
+                                       fvalue = va_arg(args, double);
+                               /* um, floating point? */
+                               fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags);
+                               break;
+                       case 'E':
+                               flags |= DP_F_UP;
+                       case 'e':
+                               if (cflags == DP_C_LDOUBLE)
+                                       fvalue = va_arg(args, long double);
+                               else
+                                       fvalue = va_arg(args, double);
+                               break;
+                       case 'G':
+                               flags |= DP_F_UP;
+                       case 'g':
+                               if (cflags == DP_C_LDOUBLE)
+                                       fvalue = va_arg(args, long double);
+                               else
+                                       fvalue = va_arg(args, double);
+                               break;
+                       case 'c':
+                               dopr_outch(buffer, &currlen, maxlen, va_arg(args, int));
+                               break;
+                       case 's':
+                               strvalue = va_arg(args, char *);
+                               if (max < 0) 
+                                       max = maxlen; /* ie, no max */
+                               fmtstr(buffer, &currlen, maxlen, strvalue, flags, min, max);
+                               break;
+                       case 'p':
+                               strvalue = va_arg(args, void *);
+                               fmtint(buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
+                               break;
+                       case 'n':
+                               if (cflags == DP_C_SHORT) {
+                                       short int *num;
+                                       num = va_arg(args, short int *);
+                                       *num = currlen;
+                               } else if (cflags == DP_C_LONG) {
+                                       long int *num;
+                                       num = va_arg(args, long int *);
+                                       *num = currlen;
+                               } else if (cflags == DP_C_LONG_LONG) {
+                                       long long *num;
+                                       num = va_arg(args, long long *);
+                                       *num = currlen;
+                               } else {
+                                       int *num;
+                                       num = va_arg(args, int *);
+                                       *num = currlen;
+                               }
+                               break;
+                       case '%':
+                               dopr_outch(buffer, &currlen, maxlen, ch);
+                               break;
+                       case 'w': /* not supported yet, treat as next char */
+                               ch = *format++;
+                               break;
+                       default: /* Unknown, skip */
+                       break;
+                       }
+                       ch = *format++;
+                       state = DP_S_DEFAULT;
+                       flags = cflags = min = 0;
+                       max = -1;
+                       break;
+               case DP_S_DONE:
+                       break;
+               default: /* hmm? */
+                       break; /* some picky compilers need this */
+               }
+       }
+       if (currlen < maxlen - 1) 
+               buffer[currlen] = '\0';
+       else 
+               buffer[maxlen - 1] = '\0';
+}
+
+static void
+fmtstr(char *buffer, size_t *currlen, size_t maxlen,
+    char *value, int flags, int min, int max)
+{
+       int cnt = 0, padlen, strln;     /* amount to pad */
+  
+       if (value == 0) 
+               value = "<NULL>";
+
+       for (strln = 0; value[strln]; ++strln); /* strlen */
+       padlen = min - strln;
+       if (padlen < 0) 
+               padlen = 0;
+       if (flags & DP_F_MINUS) 
+               padlen = -padlen; /* Left Justify */
+
+       while ((padlen > 0) && (cnt < max)) {
+               dopr_outch(buffer, currlen, maxlen, ' ');
+               --padlen;
+               ++cnt;
+       }
+       while (*value && (cnt < max)) {
+               dopr_outch(buffer, currlen, maxlen, *value++);
+               ++cnt;
+       }
+       while ((padlen < 0) && (cnt < max)) {
+               dopr_outch(buffer, currlen, maxlen, ' ');
+               ++padlen;
+               ++cnt;
+       }
+}
+
+/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
+
+static void 
+fmtint(char *buffer, size_t *currlen, size_t maxlen,
+    long value, int base, int min, int max, int flags)
+{
+       unsigned long uvalue;
+       char convert[20];
+       int signvalue = 0, place = 0, caps = 0;
+       int spadlen = 0; /* amount to space pad */
+       int zpadlen = 0; /* amount to zero pad */
+  
+       if (max < 0)
+               max = 0;
+
+       uvalue = value;
+
+       if (!(flags & DP_F_UNSIGNED)) {
+               if (value < 0) {
+                       signvalue = '-';
+                       uvalue = -value;
+               } else if (flags & DP_F_PLUS)  /* Do a sign (+/i) */
+                       signvalue = '+';
+               else if (flags & DP_F_SPACE)
+                       signvalue = ' ';
+       }
+  
+       if (flags & DP_F_UP) 
+               caps = 1; /* Should characters be upper case? */
+       do {
+               convert[place++] =
+                   (caps ? "0123456789ABCDEF" : "0123456789abcdef")
+                   [uvalue % (unsigned)base];
+               uvalue = (uvalue / (unsigned)base );
+       } while (uvalue && (place < 20));
+       if (place == 20) 
+               place--;
+       convert[place] = 0;
+
+       zpadlen = max - place;
+       spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);
+       if (zpadlen < 0)
+               zpadlen = 0;
+       if (spadlen < 0)
+               spadlen = 0;
+       if (flags & DP_F_ZERO) {
+               zpadlen = MAX(zpadlen, spadlen);
+               spadlen = 0;
+       }
+       if (flags & DP_F_MINUS) 
+               spadlen = -spadlen; /* Left Justifty */
+
+       /* Spaces */
+       while (spadlen > 0) {
+               dopr_outch(buffer, currlen, maxlen, ' ');
+               --spadlen;
+       }
+
+       /* Sign */
+       if (signvalue) 
+               dopr_outch(buffer, currlen, maxlen, signvalue);
+
+       /* Zeros */
+       if (zpadlen > 0) {
+               while (zpadlen > 0) {
+                       dopr_outch(buffer, currlen, maxlen, '0');
+                       --zpadlen;
+               }
+       }
+
+       /* Digits */
+       while (place > 0) 
+               dopr_outch(buffer, currlen, maxlen, convert[--place]);
+  
+       /* Left Justified spaces */
+       while (spadlen < 0) {
+               dopr_outch (buffer, currlen, maxlen, ' ');
+               ++spadlen;
+       }
+}
+
+static long double 
+pow10(int exp)
+{
+       long double result = 1;
+
+       while (exp) {
+               result *= 10;
+               exp--;
+       }
+  
+       return result;
+}
+
+static long 
+round(long double value)
+{
+       long intpart = value;
+
+       value -= intpart;
+       if (value >= 0.5)
+               intpart++;
+
+       return intpart;
+}
+
+static void 
+fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, 
+      int min, int max, int flags)
+{
+       char iconvert[20], fconvert[20];
+       int signvalue = 0, iplace = 0, fplace = 0;
+       int padlen = 0; /* amount to pad */
+       int zpadlen = 0, caps = 0;
+       long intpart, fracpart;
+       long double ufvalue;
+  
+       /* 
+        * AIX manpage says the default is 0, but Solaris says the default
+        * is 6, and sprintf on AIX defaults to 6
+        */
+       if (max < 0)
+               max = 6;
+
+       ufvalue = abs_val(fvalue);
+
+       if (fvalue < 0)
+               signvalue = '-';
+       else if (flags & DP_F_PLUS)  /* Do a sign (+/i) */
+               signvalue = '+';
+       else if (flags & DP_F_SPACE)
+               signvalue = ' ';
+
+       intpart = ufvalue;
+
+       /* 
+        * Sorry, we only support 9 digits past the decimal because of our 
+        * conversion method
+        */
+       if (max > 9)
+               max = 9;
+
+       /* We "cheat" by converting the fractional part to integer by
+        * multiplying by a factor of 10
+        */
+       fracpart = round((pow10 (max)) * (ufvalue - intpart));
+
+       if (fracpart >= pow10 (max)) {
+               intpart++;
+               fracpart -= pow10 (max);
+       }
+
+       /* Convert integer part */
+       do {
+               iconvert[iplace++] =
+                   (caps ? "0123456789ABCDEF" : "0123456789abcdef")
+                   [intpart % 10];
+               intpart = (intpart / 10);
+       } while(intpart && (iplace < 20));
+       if (iplace == 20) 
+               iplace--;
+       iconvert[iplace] = 0;
+
+       /* Convert fractional part */
+       do {
+               fconvert[fplace++] =
+                   (caps ? "0123456789ABCDEF" : "0123456789abcdef")
+                   [fracpart % 10];
+               fracpart = (fracpart / 10);
+       } while(fracpart && (fplace < 20));
+       if (fplace == 20) 
+               fplace--;
+       fconvert[fplace] = 0;
+
+       /* -1 for decimal point, another -1 if we are printing a sign */
+       padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); 
+       zpadlen = max - fplace;
+       if (zpadlen < 0)
+               zpadlen = 0;
+       if (padlen < 0) 
+               padlen = 0;
+       if (flags & DP_F_MINUS) 
+               padlen = -padlen; /* Left Justifty */
+
+       if ((flags & DP_F_ZERO) && (padlen > 0)) {
+               if (signvalue) {
+                       dopr_outch(buffer, currlen, maxlen, signvalue);
+                       --padlen;
+                       signvalue = 0;
+               }
+               while (padlen > 0) {
+                       dopr_outch(buffer, currlen, maxlen, '0');
+                       --padlen;
+               }
+       }
+       while (padlen > 0) {
+               dopr_outch(buffer, currlen, maxlen, ' ');
+               --padlen;
+       }
+       if (signvalue) 
+               dopr_outch(buffer, currlen, maxlen, signvalue);
+
+       while (iplace > 0) 
+               dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]);
+
+       /*
+        * Decimal point.  This should probably use locale to find the 
+        * correct char to print out.
+        */
+       dopr_outch(buffer, currlen, maxlen, '.');
+
+       while (fplace > 0) 
+               dopr_outch(buffer, currlen, maxlen, fconvert[--fplace]);
+
+       while (zpadlen > 0) {
+               dopr_outch(buffer, currlen, maxlen, '0');
+               --zpadlen;
+       }
+
+       while (padlen < 0) {
+               dopr_outch(buffer, currlen, maxlen, ' ');
+               ++padlen;
+       }
+}
+
+static void 
+dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
+{
+       if (*currlen < maxlen)
+               buffer[(*currlen)++] = c;
+}
+#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */
+
+#ifndef HAVE_VSNPRINTF
+int 
+vsnprintf(char *str, size_t count, const char *fmt, va_list args)
+{
+       str[0] = 0;
+       dopr(str, count, fmt, args);
+
+       return(strlen(str));
+}
+#endif /* !HAVE_VSNPRINTF */
+
+#ifndef HAVE_SNPRINTF
+int 
+snprintf(char *str,size_t count,const char *fmt,...)
+{
+       va_list ap;
+
+       va_start(ap, fmt);
+       (void) vsnprintf(str, count, fmt, ap);
+       va_end(ap);
+
+       return(strlen(str));
+}
+
+#endif /* !HAVE_SNPRINTF */
diff --git a/ssh/openssh/ssh-dss.c b/ssh/openssh/ssh-dss.c
new file mode 100644 (file)
index 0000000..7327dff
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2000 Markus Friedl.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// removed signature creation
+
+#include "includes.h"
+RCSID("$OpenBSD: ssh-dss.c,v 1.18 2003/02/12 09:33:04 markus Exp $");
+
+#include "openssl/bn/bn.h"
+#include "openssl/evp/evp.h"
+#include "xmalloc.h"
+#include "buffer.h"
+#include "bufaux.h"
+#include "key.h"
+
+#define INTBLOB_LEN    20
+#define SIGBLOB_LEN    (2*INTBLOB_LEN)
+
+int
+ssh_dss_sign(Key *key, u_char **sigp, u_int *lenp,
+    u_char *data, u_int datalen)
+{
+       DSA_SIG *sig;
+       const EVP_MD *evp_md = EVP_sha1();
+       EVP_MD_CTX md;
+       u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN];
+       u_int rlen, slen, len, dlen;
+       Buffer b;
+
+       if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
+               error("ssh_dss_sign: no DSA key");
+               return -1;
+       }
+       EVP_DigestInit(&md, evp_md);
+       EVP_DigestUpdate(&md, data, datalen);
+       EVP_DigestFinal(&md, digest, (unsigned int *)&dlen);
+
+       sig = DSA_do_sign(digest, dlen, key->dsa);
+       memset(digest, 'd', sizeof(digest));
+
+       if (sig == NULL) {
+               error("ssh_dss_sign: sign failed");
+               return -1;
+       }
+
+       rlen = BN_num_bytes(sig->r);
+       slen = BN_num_bytes(sig->s);
+       if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
+               error("bad sig size %u %u", rlen, slen);
+               DSA_SIG_free(sig);
+               return -1;
+       }
+       memset(sigblob, 0, SIGBLOB_LEN);
+       BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
+       BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
+       DSA_SIG_free(sig);
+
+       {
+               /* ietf-drafts */
+               buffer_init(&b);
+               buffer_put_cstring(&b, "ssh-dss");
+               buffer_put_string(&b, sigblob, SIGBLOB_LEN);
+               len = buffer_len(&b);
+               if (lenp != NULL)
+                       *lenp = len;
+               if (sigp != NULL) {
+                       *sigp = xmalloc(len);
+                       memcpy(*sigp, buffer_ptr(&b), len);
+               }
+               buffer_free(&b);
+       }
+       return 0;
+}
+int
+ssh_dss_verify(Key *key, u_char *signature, u_int signaturelen,
+    u_char *data, u_int datalen)
+{
+       DSA_SIG *sig;
+       const EVP_MD *evp_md = EVP_sha1();
+       EVP_MD_CTX md;
+       u_char digest[EVP_MAX_MD_SIZE], *sigblob;
+       uint16_t len;
+       unsigned int dlen;
+       int rlen, ret;
+       Buffer b;
+
+       if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
+               error("ssh_dss_verify: no DSA key");
+               return -1;
+       }
+
+       /* fetch signature */
+       {
+               /* ietf-drafts */
+               char *ktype;
+               buffer_init(&b);
+               buffer_append(&b, signature, signaturelen);
+               ktype = buffer_get_string(&b, NULL);
+               if (strcmp("ssh-dss", ktype) != 0) {
+                       error("ssh_dss_verify: cannot handle type %s", ktype);
+                       buffer_free(&b);
+                       xfree(ktype);
+                       return -1;
+               }
+               xfree(ktype);
+               sigblob = buffer_get_string(&b, &len);
+               rlen = buffer_len(&b);
+               buffer_free(&b);
+               if (rlen != 0) {
+                       error("ssh_dss_verify: "
+                           "remaining bytes in signature %d", rlen);
+                       xfree(sigblob);
+                       return -1;
+               }
+       }
+
+       if (len != SIGBLOB_LEN) {
+               fatal("bad sigbloblen %u != SIGBLOB_LEN", len);
+       }
+
+       /* parse signature */
+       if ((sig = DSA_SIG_new()) == NULL)
+               fatal("ssh_dss_verify: DSA_SIG_new failed");
+       if ((sig->r = BN_new()) == NULL)
+               fatal("ssh_dss_verify: BN_new failed");
+       if ((sig->s = BN_new()) == NULL)
+               fatal("ssh_dss_verify: BN_new failed");
+       BN_bin2bn(sigblob, INTBLOB_LEN, sig->r);
+       BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s);
+
+       memset(sigblob, 0, len);
+       xfree(sigblob);
+
+       /* sha1 the data */
+       EVP_DigestInit(&md, evp_md);
+       EVP_DigestUpdate(&md, data, datalen);
+       EVP_DigestFinal(&md, digest, &dlen);
+
+       ret = DSA_do_verify(digest, dlen, sig, key->dsa);
+       memset(digest, 'd', sizeof(digest));
+
+       DSA_SIG_free(sig);
+
+       debug1("ssh_dss_verify: signature %s",
+           ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error");
+       return ret;
+}
diff --git a/ssh/openssh/ssh-rsa.c b/ssh/openssh/ssh-rsa.c
new file mode 100644 (file)
index 0000000..9ea247b
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org>
+ *
+ * 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// removed signature creation
+
+#include "includes.h"
+RCSID("$OpenBSD: ssh-rsa.c,v 1.30 2003/06/18 11:28:11 markus Exp $");
+
+#include "openssl/bn/bn.h"
+#include "openssl/evp/evp.h"
+
+#include "xmalloc.h"
+#include "buffer.h"
+#include "bufaux.h"
+#include "key.h"
+
+/* Minimum modulus size (n) for RSA keys. */
+#define SSH_RSA_MINIMUM_MODULUS_SIZE    768
+
+static uint8_t *openssh_RSA_sign(u_char *hash, u_int hashlen, u_int *resultlen, RSA *rsa) SSH_SEGMENT;
+static int openssh_RSA_verify(int, u_char *, u_int, u_char *, u_int, RSA *) SSH_SEGMENT;
+
+/* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */
+int
+ssh_rsa_sign(Key *key, u_char **sigp, u_int *lenp,
+    u_char *data, u_int datalen)
+{
+       const EVP_MD *evp_md;
+       EVP_MD_CTX md;
+       u_char digest[EVP_MAX_MD_SIZE], *sig;
+       u_int slen, dlen, len;
+       Buffer b;
+
+       if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) {
+               error("ssh_rsa_sign: no RSA key");
+               return -1;
+       }
+        evp_md = EVP_sha1();
+       EVP_DigestInit(&md, evp_md);
+       EVP_DigestUpdate(&md, data, datalen);
+       EVP_DigestFinal(&md, digest, (unsigned int *)&dlen);
+
+        slen = RSA_size(key->rsa);
+       sig = openssh_RSA_sign(digest, dlen, &len, key->rsa);
+       memset(digest, 'd', sizeof(digest));
+
+       if (!sig) {
+               error("ssh_rsa_sign: RSA_sign failed");
+               return -1;
+       }
+       if (len < slen) {
+               u_int diff = slen - len;
+               debug1("slen %u > len %u", slen, len);
+               memmove(sig + diff, sig, len);
+               memset(sig, 0, diff);
+       } else if (len > slen) {
+               error("ssh_rsa_sign: slen %u slen2 %u", slen, len);
+               xfree(sig);
+               return -1;
+       }
+       /* encode signature */
+       buffer_init(&b);
+       buffer_put_cstring(&b, "ssh-rsa");
+       buffer_put_string(&b, sig, slen);
+       len = buffer_len(&b);
+       if (lenp != NULL)
+               *lenp = len;
+       if (sigp != NULL) {
+               *sigp = xmalloc(len);
+               memcpy(*sigp, buffer_ptr(&b), len);
+       }
+       buffer_free(&b);
+       memset(sig, 's', slen);
+       xfree(sig);
+
+       return 0;
+}
+
+int
+ssh_rsa_verify(Key *key, u_char *signature, u_int signaturelen,
+    u_char *data, u_int datalen)
+{
+       Buffer b;
+       const EVP_MD *evp_md;
+       EVP_MD_CTX md;
+       char *ktype;
+       u_char digest[EVP_MAX_MD_SIZE], *sigblob;
+       u_int len, dlen, modlen;
+       int rlen, ret, nid;
+
+       if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) {
+               error("ssh_rsa_verify: no RSA key");
+               return -1;
+       }
+       if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
+               error("ssh_rsa_verify: RSA modulus too small: %d < minimum %d bits",
+                   BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE);
+               return -1;
+       }
+       buffer_init(&b);
+       buffer_append(&b, signature, signaturelen);
+       ktype = buffer_get_string(&b, NULL);
+       if (strcmp("ssh-rsa", ktype) != 0) {
+               error("ssh_rsa_verify: cannot handle type %s", ktype);
+               buffer_free(&b);
+               xfree(ktype);
+               return -1;
+       }
+       xfree(ktype);
+       sigblob = buffer_get_string(&b, &len);
+       rlen = buffer_len(&b);
+       buffer_free(&b);
+       if (rlen != 0) {
+               error("ssh_rsa_verify: remaining bytes in signature %d", rlen);
+               xfree(sigblob);
+               return -1;
+       }
+       /* RSA_verify expects a signature of RSA_size */
+       modlen = RSA_size(key->rsa);
+       if (len > modlen) {
+               error("ssh_rsa_verify: len %u > modlen %u", len, modlen);
+               xfree(sigblob);
+               return -1;
+       } else if (len < modlen) {
+               u_int diff = modlen - len;
+               debug1("ssh_rsa_verify: add padding: modlen %u > len %u",
+                   modlen, len);
+               sigblob = xrealloc(sigblob, modlen);
+               memmove(sigblob + diff, sigblob, len);
+               memset(sigblob, 0, diff);
+               len = modlen;
+       }
+        nid = NID_sha1;
+        evp_md = EVP_sha1();
+       EVP_DigestInit(&md, evp_md);
+       EVP_DigestUpdate(&md, data, datalen);
+       EVP_DigestFinal(&md, digest, (unsigned int *)&dlen);
+
+       ret = openssh_RSA_verify(nid, digest, dlen, sigblob, len, key->rsa);
+       memset(digest, 'd', sizeof(digest));
+       memset(sigblob, 's', len);
+       xfree(sigblob);
+       debug1("ssh_rsa_verify: signature %scorrect", (ret==0) ? "in" : "");
+       return ret;
+}
+
+/*
+ * See:
+ * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
+ * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn
+ */
+/*
+ * id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
+ *     oiw(14) secsig(3) algorithms(2) 26 }
+ */
+static const u_char id_sha1[] = {
+       0x30, 0x21, /* type Sequence, length 0x21 (33) */
+       0x30, 0x09, /* type Sequence, length 0x09 */
+       0x06, 0x05, /* type OID, length 0x05 */
+       0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */
+       0x05, 0x00, /* NULL */
+       0x04, 0x14  /* Octet string, length 0x14 (20), followed by sha1 hash */
+};
+/*
+ * id-md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
+ *     rsadsi(113549) digestAlgorithm(2) 5 }
+ */
+static const u_char id_md5[] = {
+       0x30, 0x20, /* type Sequence, length 0x20 (32) */
+       0x30, 0x0c, /* type Sequence, length 0x09 */
+       0x06, 0x08, /* type OID, length 0x05 */
+       0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* id-md5 */
+       0x05, 0x00, /* NULL */
+       0x04, 0x10  /* Octet string, length 0x10 (16), followed by md5 hash */
+};
+
+static int
+openssh_RSA_verify(int type, u_char *hash, u_int hashlen,
+    u_char *sigbuf, u_int siglen, RSA *rsa)
+{
+       u_int ret, rsasize, oidlen = 0, hlen = 0;
+       int len;
+       const u_char *oid = NULL;
+       u_char *decrypted = NULL;
+
+       ret = 0;
+       switch (type) {
+       case NID_sha1:
+               oid = id_sha1;
+               oidlen = sizeof(id_sha1);
+               hlen = 20;
+               break;
+       case NID_md5:
+               oid = id_md5;
+               oidlen = sizeof(id_md5);
+               hlen = 16;
+               break;
+       default:
+               goto done;
+               break;
+       }
+       if (hashlen != hlen) {
+               error("bad hashlen");
+               goto done;
+       }
+       rsasize = RSA_size(rsa);
+       if (siglen == 0 || siglen > rsasize) {
+               error("bad siglen");
+               goto done;
+       }
+       decrypted = xmalloc(rsasize);
+       if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa,
+           RSA_PKCS1_PADDING)) < 0) {
+               error("RSA_public_decrypt failed");
+               goto done;
+       }
+       if (len != hlen + oidlen) {
+               error("bad decrypted len: %d != %d + %d", len, hlen, oidlen);
+               goto done;
+       }
+       if (memcmp(decrypted, oid, oidlen) != 0) {
+               error("oid mismatch");
+               goto done;
+       }
+       if (memcmp(decrypted + oidlen, hash, hlen) != 0) {
+               error("hash mismatch");
+               goto done;
+       }
+       ret = 1;
+done:
+       if (decrypted)
+               xfree(decrypted);
+       return ret;
+}
+
+
+// GrP OpenSSL's RSA_sign is too icky. Use code loosely based on PuTTY instead.
+static uint8_t *
+openssh_RSA_sign(u_char *hash, u_int hashlen, u_int *resultlen, RSA *rsa)
+{
+    BIGNUM *in, *out;
+    uint8_t *buf;
+    uint16_t buflen;
+    uint16_t i, j;
+
+    // construct bignum from padding, ASN1 tag, and the hash
+    buflen = RSA_size(rsa);
+    buf = xmalloc(buflen);
+    i = 0;
+    buf[i++] = 0;
+    buf[i++] = 1;
+    for (; i < buflen - hashlen - sizeof(id_sha1) - 1; i++) {
+        buf[i] = 0xff;
+    }
+    buf[i++] = 0x00; // end of 0xff padding
+    for (j = 0; i < buflen - hashlen; i++, j++) {
+        buf[i] = id_sha1[j];
+    }
+    for (j = 0; i < buflen; i++, j++) {
+        buf[i] = hash[j];
+    }
+
+    in = BN_bin2bn(buf, buflen, NULL);
+    xfree(buf);
+    if (!in) return NULL;
+
+    out = BN_new();
+    if (!out) {
+        BN_free(in);
+        return NULL;
+    }
+
+    // out = in^d (mod n)
+    {
+        BN_CTX *ctx = BN_CTX_new();
+        BN_MONT_CTX *mont_ctx = BN_MONT_CTX_new();
+        BN_MONT_CTX_set(mont_ctx, rsa->n, ctx);
+        
+        BN_mod_exp_mont(out, in, rsa->d, rsa->n, ctx, mont_ctx);
+        
+        BN_MONT_CTX_free(mont_ctx);
+        BN_CTX_free(ctx);
+        BN_free(in);
+    }
+    
+    // return out
+    buflen = BN_num_bytes(out);
+    buf = xmalloc(buflen);
+    BN_bn2bin(out, buf);
+    *resultlen = buflen;
+    return buf;
+}
diff --git a/ssh/openssh/uuencode.c b/ssh/openssh/uuencode.c
new file mode 100644 (file)
index 0000000..e409d8d
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2000 Markus Friedl.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// changed includes
+// removed dump_base64
+
+#include "includes.h"
+RCSID("$OpenBSD: uuencode.c,v 1.16 2002/09/09 14:54:15 markus Exp $");
+
+#include "xmalloc.h"
+#include "uuencode.h"
+#include "openbsd-compat/base64.h"
+
+int
+uuencode(u_char *src, u_int srclength,
+    char *target, size_t targsize)
+{
+       return __b64_ntop(src, srclength, target, targsize);
+}
+
+int
+uudecode(const char *src, u_char *target, size_t targsize)
+{
+       int len;
+       char *encoded, *p;
+
+       /* copy the 'readonly' source */
+       encoded = xstrdup(src);
+       /* skip whitespace and data */
+       for (p = encoded; *p == ' ' || *p == '\t'; p++)
+               ;
+       for (; *p != '\0' && *p != ' ' && *p != '\t'; p++)
+               ;
+       /* and remove trailing whitespace because __b64_pton needs this */
+       *p = '\0';
+       len = __b64_pton(encoded, target, targsize);
+       xfree(encoded);
+       return len;
+}
diff --git a/ssh/openssh/uuencode.h b/ssh/openssh/uuencode.h
new file mode 100644 (file)
index 0000000..b2f44f7
--- /dev/null
@@ -0,0 +1,58 @@
+/*     $OpenBSD: uuencode.h,v 1.9 2002/02/25 16:33:27 markus Exp $     */
+
+/*
+ * Copyright (c) 2000 Markus Friedl.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+/**********
+ * Portions Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// GrP pssh:
+// remove dump_base64
+// added SSH_SEGMENT everywhere
+
+#ifndef UUENCODE_H
+#define UUENCODE_H
+int     uuencode(u_char *, u_int, char *, size_t) SSH_SEGMENT;
+int     uudecode(const char *, u_char *, size_t) SSH_SEGMENT;
+#endif
diff --git a/ssh/packetizer.c b/ssh/packetizer.c
new file mode 100644 (file)
index 0000000..53182a5
--- /dev/null
@@ -0,0 +1,584 @@
+/**********
+ * Copyright (c) 2003-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "packetizer.h"
+
+#include "session.h"
+#include "transport.h"
+#include "connection.h"
+#include "ssh2.h"
+#include "openssh/buffer.h"
+#include "openssh/bufaux.h"
+#include "openssh/cipher.h"
+#include "openssh/mac.h"
+#include "crypto/rand.h"
+
+
+static char *chop(char *s) PACKETIZER_SEGMENT;
+static void packetizer_decrypt(ssh_session_t *ss, uint8_t *dst, uint8_t *src, uint16_t length) PACKETIZER_SEGMENT;
+static packetizer_state_t packetizer_handle_version_start(ssh_session_t *ss, Buffer *b) PACKETIZER_SEGMENT;
+static packetizer_state_t packetizer_handle_not_version(ssh_session_t *ss, Buffer *b) PACKETIZER_SEGMENT;
+static packetizer_state_t packetizer_handle_version(ssh_session_t *ss, Buffer *b) PACKETIZER_SEGMENT;
+static packetizer_state_t packetizer_handle_header(ssh_session_t *ss, Buffer *b) PACKETIZER_SEGMENT;
+static packetizer_state_t packetizer_handle_body(ssh_session_t *ss, Buffer *b) PACKETIZER_SEGMENT;
+static void packetizer_cleanup(ssh_session_t *ss) PACKETIZER_SEGMENT;
+
+
+
+/* remove newline at end of string */
+static char *chop(char *s) 
+{
+    char *t = s;
+    while (*t) {
+        if (*t == '\n' || *t == '\r') {
+            *t = '\0';
+            return s;
+        }
+        t++;
+    }
+    return s;
+}
+
+
+static void packetizer_decrypt(ssh_session_t *ss, uint8_t *dst, uint8_t *src, 
+                               uint16_t length)
+{
+    if (!ss->p.inKeys.enc.enabled) {
+        // no crypto yet
+        memcpy(dst, src, length);
+    } else {
+        cipher_crypt(&ss->p.inContext, dst, src, length);
+    }
+}
+
+extern Boolean RefreshNetLib(void); // fixme put this in a header file
+
+void packetizer_send_payload(ssh_session_t *ss, Buffer *payload)
+{
+    // fixme what about blocking write?
+    // fixme implement write queue
+    void *p;
+    uint16_t packet_length;
+    uint16_t padded_length;
+    size_t written;
+    uint8_t padding_length;
+    static Buffer packet = {0, 0, 0, 0};
+    uint8_t *macbuf = NULL;
+    Keys *keys = &ss->p.outKeys;
+    Buffer comp_buffer = {0, 0, 0, 0};
+
+    if (!packet.buf) buffer_init(&packet);
+    buffer_clear(&packet);
+
+    // compress payload before calculating lengths
+    if (keys->comp) {
+        unsigned char *newPayload;
+        size_t newLen;
+        if (keys->comp->transcode(keys->comp_ctx, 
+                                  buffer_ptr(payload), buffer_len(payload), 
+                                  &newPayload, &newLen)) 
+        {
+            comp_buffer.buf = newPayload;
+            comp_buffer.alloc = newLen;
+            comp_buffer.offset = 0;
+            comp_buffer.end = newLen;
+            payload = &comp_buffer;
+        }
+    }
+
+    padding_length = 4; // 4-byte minimum random padding
+    // length of everything but MAC must be multiple of max(8, block size)
+    padded_length = 4 + 1 + buffer_len(payload) + padding_length;
+    padding_length += ss->p.outHeaderLength - 
+        (padded_length % ss->p.outHeaderLength);
+
+    // packet_length field doesn't include itself
+    packet_length = 1 + buffer_len(payload) + padding_length;
+
+    // packet_length
+    buffer_put_int(&packet, packet_length);
+    
+    // padding_length
+    buffer_put_char(&packet, padding_length);
+
+    // payload (maybe already compressed)
+    buffer_append(&packet, buffer_ptr(payload), buffer_len(payload));
+
+    // random padding
+    p = buffer_append_space(&packet, padding_length);
+    RAND_bytes(p, padding_length);
+    
+    // compute MAC across unencrypted bytes
+    if (keys->mac.enabled) {
+        macbuf = mac_compute(&keys->mac, ss->p.seqnoOut, 
+                             buffer_ptr(&packet), buffer_len(&packet));
+    }
+
+    // encrypt
+    if (ss->p.outKeys.enc.enabled) {
+        Buffer encrypted;
+        buffer_init(&encrypted);
+        buffer_append_space(&encrypted, buffer_len(&packet));
+        cipher_crypt(&ss->p.outContext, buffer_ptr(&encrypted), 
+                     buffer_ptr(&packet), buffer_len(&packet));
+        buffer_free(&packet);
+        packet = encrypted;
+    }
+
+    // append MAC
+    if (keys->mac.enabled) {
+        buffer_append(&packet, macbuf, keys->mac.mac_len);
+        arena_free(macbuf);
+    }
+
+    packetizer_log("packetizer: sending packet (%d bytes: 4+1+%d+%d+mac)\r\n", 
+           buffer_len(&packet), buffer_len(payload), padding_length);
+
+    if (comp_buffer.buf) buffer_free(&comp_buffer);
+
+    // fixme implement write queue
+
+    // Re-open network connection (may have been disconnected after 
+    // auto power-off, for example)
+    // fixme call RefreshNetLib less often
+    if (ss->closing) {
+        // do not refresh network while closing
+    } else if (!RefreshNetLib()) {
+        ssh_kill(ss);
+        return;
+    }
+
+    // fixme this kill sometimes crashes?
+    written = write(ss->s.socket, buffer_ptr(&packet), buffer_len(&packet));
+    if (written != buffer_len(&packet)) {
+        ssh_kill(ss);
+        return;
+    }
+
+    ss->p.seqnoOut++;
+}
+
+
+void packetizer_change_crypto(ssh_session_t *ss, 
+                              Keys *newInKeys, Keys *newOutKeys)
+{
+    Enc *inEnc = &ss->p.inKeys.enc;
+    Mac *inMac = &ss->p.inKeys.mac;
+    Comp *inComp = ss->p.inKeys.comp;
+    Enc *outEnc = &ss->p.outKeys.enc;
+    Mac *outMac = &ss->p.outKeys.mac;
+    Comp *outComp = ss->p.outKeys.comp;
+
+    // cleanup old keys
+    keys_free(&ss->p.inKeys);
+    keys_free(&ss->p.outKeys);
+    cipher_cleanup(&ss->p.inContext);
+    cipher_cleanup(&ss->p.outContext);
+
+    ss->p.inKeys = *newInKeys;
+    ss->p.outKeys = *newOutKeys;
+    ss->p.inHeaderLength = MAX(8, inEnc->block_size);
+    ss->p.outHeaderLength = MAX(8, outEnc->block_size);
+
+    memset(newInKeys, 0, sizeof(*newInKeys));
+    memset(newOutKeys, 0, sizeof(*newOutKeys));
+
+    // mac
+    if (inMac->md) inMac->enabled = 1;
+    if (outMac->md) outMac->enabled = 1;
+
+    // cipher
+    if (inEnc->cipher) inEnc->enabled = 1;
+    if (outEnc->cipher) outEnc->enabled = 1;
+
+    // cipher context
+    
+    cipher_init(&ss->p.inContext, inEnc->cipher, inEnc->key, inEnc->key_len, 
+                inEnc->iv, inEnc->block_size, CIPHER_DECRYPT);
+    cipher_init(&ss->p.outContext, outEnc->cipher, outEnc->key,outEnc->key_len,
+                outEnc->iv, outEnc->block_size, CIPHER_ENCRYPT);
+
+    // compression
+    if (outComp) {
+        ss->p.outKeys.comp_ctx = outComp->init();
+    }
+    if (inComp) {
+        ss->p.inKeys.comp_ctx = inComp->init();
+    }
+}
+
+
+static packetizer_state_t 
+packetizer_handle_version_start(ssh_session_t *ss, Buffer *b)
+{
+    uint8_t *bufData = buffer_ptr(b);
+    uint16_t bufLen = buffer_len(b);
+
+    packetizer_log("waiting-for-version %s\r\n", bufData);
+
+    if (bufLen >= 4  &&  0 == strncmp(bufData, "SSH-", 4)) {
+        // leave "SSH-" in buffer for eventual version string
+        return PACKETIZER_STATE_READING_VERSION;
+    } else {
+        // leave data in buffer to act as overflow check
+        return PACKETIZER_STATE_READING_NOT_VERSION;
+    }
+}                           
+
+
+
+static packetizer_state_t 
+packetizer_handle_not_version(ssh_session_t *ss, Buffer *b)
+{
+    uint8_t *bufData = buffer_ptr(b);
+    uint16_t bufLen = buffer_len(b);
+    uint8_t *pos;
+
+    packetizer_log("reading-not-version\r\n");
+    pos = memchr(bufData, '\n', bufLen);
+    if (pos) {
+        buffer_consume(b, pos - bufData + 1); // up to and including \n
+        return PACKETIZER_STATE_WAITING_FOR_VERSION;
+    } else {
+        // leave data in buffer to act as overflow check
+        return ss->p.state;
+    }
+}
+
+
+static packetizer_state_t 
+packetizer_handle_version(ssh_session_t *ss, Buffer *b)
+{
+    uint8_t *bufData = buffer_ptr(b);
+    uint16_t bufLen = buffer_len(b);
+    uint8_t *pos;
+
+    packetizer_log("reading-version\r\n");
+    pos = memchr(bufData, '\n', bufLen);
+    if (pos) {
+        // got version
+        size_t len = pos - bufData + 1; // up to and including \n
+        ss->p.remote_version_string = arena_malloc(len + 1);
+        buffer_get(b, ss->p.remote_version_string, len);
+        ss->p.remote_version_string[len] = '\0';
+        chop(ss->p.remote_version_string);
+
+        packetizer_log("got remote version %s\r\n", 
+                       ss->p.remote_version_string);
+
+        // Check version
+        // We accept "SSH-2.0-..." or "SSH-1.99-..."
+        if (0 != strcmp(ss->p.remote_version_string, "SSH-2.0")  &&  
+            0 != strcmp(ss->p.remote_version_string, "SSH-1.99")  &&  
+            0 != strncmp(ss->p.remote_version_string, "SSH-2.0-", 8)  &&  
+            0 != strncmp(ss->p.remote_version_string, "SSH-1.99-", 9))
+        {
+            // bogus version
+            printf("unknown SSH protocol version '%s'\r\n", 
+                   ss->p.remote_version_string);
+        }
+        
+        transport_start(ss);
+        
+        return PACKETIZER_STATE_READING_PACKET_HEADER;
+    } else {
+        // leave data in buffer for eventual version string
+        return ss->p.state;
+    }
+}
+
+
+static packetizer_state_t 
+packetizer_handle_header(ssh_session_t *ss, Buffer *b)
+{
+    uint8_t *bufData = buffer_ptr(b);
+    uint16_t bufLen = buffer_len(b);
+
+    packetizer_log("reading-packet-header\r\n");
+    if (bufLen < ss->p.inHeaderLength) {
+        // wait for more data to decrypt packet size
+        return ss->p.state;
+    } else {
+        uint8_t *decrypt_dst = 
+            buffer_append_space(&ss->p.decryptedData, ss->p.inHeaderLength);
+        packetizer_decrypt(ss, decrypt_dst, bufData, ss->p.inHeaderLength);
+        buffer_consume(b, ss->p.inHeaderLength);
+        
+        ss->p.packetLength = *(uint32_t *)decrypt_dst;
+        ss->p.paddingLength = *(uint8_t *)(decrypt_dst + 4);
+
+        // max packet length specified by SSH protocol spec
+        if (ss->p.packetLength > 35000) {
+            printf("\r\npacketizer: packet too big (%lu bytes)\r\n", ss->p.packetLength);
+            ssh_kill(ss);
+            return ss->p.state;
+        }
+        
+        packetizer_log("packet length %ld padding %d\r\n", 
+                       ss->p.packetLength, ss->p.paddingLength);
+        // don't consume any decrypted data - it's need for MAC check
+        
+        // unhandled data is beginning of payload
+        return PACKETIZER_STATE_READING_PACKET_BODY;
+    }
+}
+
+
+static packetizer_state_t 
+packetizer_handle_body(ssh_session_t *ss, Buffer *b)
+{
+    Mac *mac = &ss->p.inKeys.mac;
+    Comp *comp = ss->p.inKeys.comp;
+    void *comp_ctx = ss->p.inKeys.comp_ctx;
+    Buffer comp_buffer = {0, 0, 0, 0};
+
+    uint16_t encryptedLen = ss->p.packetLength + 4 - ss->p.inHeaderLength;
+    // +4 for packet_length field, -inHeaderLength for already-decrypted block
+    // encryptedLen includes everything still encrypted, but not the MAC
+
+    packetizer_log("reading-packet-body\r\n");
+
+    if (buffer_len(b) < encryptedLen + mac->mac_len) {
+        // wait for the rest of the packet, including MAC but not including already-decrypted block
+        packetizer_log("no body (total %ld, have %d)", ss->p.packetLength + 4, buffer_len(b) + ss->p.inHeaderLength);
+        return ss->p.state;
+    } else {
+        Buffer *d = &ss->p.decryptedData;
+        uint8_t *decrypt_dst = buffer_append_space(d, encryptedLen);
+        packetizer_decrypt(ss, decrypt_dst, buffer_ptr(b), encryptedLen);
+        buffer_consume(b, encryptedLen);
+        
+        // Entire decrypted packet is now in decryptedData (d)
+        // Entire MAC is now in unhandledData (b)
+
+        // Check MAC
+        if (mac->enabled) {
+            // Compute MAC(sequence number || decrypted length+payload+padding)
+            uint8_t *macbuf = mac_compute(mac, ss->p.seqnoIn, 
+                                          buffer_ptr(d), buffer_len(d));
+            if (memcmp(macbuf, buffer_ptr(b), mac->mac_len) != 0) {
+                // MAC is wrong
+                printf("\r\npacketizer: bad MAC from server\r\n");
+                ssh_kill(ss);
+                arena_free(macbuf);
+                return ss->p.state;
+            }
+            buffer_consume(b, mac->mac_len);
+            arena_free(macbuf);
+        }
+
+        // unpack and uncompress decrypted payload
+        buffer_consume(d, 4+1);                     // leading header
+        buffer_consume_end(d, ss->p.paddingLength); // trailing random pad
+        if (comp) {
+            unsigned char *newData;
+            size_t newLen;
+            if (comp->transcode(comp_ctx, buffer_ptr(d), buffer_len(d), 
+                                &newData, &newLen)) 
+            {
+                comp_buffer.buf = newData;
+                comp_buffer.alloc = newLen;
+                comp_buffer.offset = 0;
+                comp_buffer.end = newLen;
+                buffer_clear(d);                
+                d = &comp_buffer;
+            }
+        }
+
+        transport_receive_packet(ss, d);
+        buffer_clear(d);
+        if (comp_buffer.buf) buffer_free(&comp_buffer);
+        
+        ss->p.seqnoIn++;
+
+        // NOTE state may have changed during transport or connection layer !
+        if (ss->p.state == PACKETIZER_STATE_READING_PACKET_BODY) {
+            return PACKETIZER_STATE_READING_PACKET_HEADER;
+        } else {
+            return ss->p.state;
+        }
+    }
+}
+
+
+void packetizer_receive_data(ssh_session_t *ss)
+{
+    Buffer *b = &ss->p.unhandledData;
+    packetizer_state_t prevState;
+
+    if (ss->p.state != PACKETIZER_STATE_CLOSED) {
+        uint8_t *newData;
+        int16_t newLen;
+        
+        packetizer_log("packetizer read\r\n");
+        newData = buffer_append_space(b, 4096);
+        newLen = read(ss->s.socket, newData, 4096);
+        RAND_add_net_entropy();
+        packetizer_log("read %d bytes\r\n", newLen);        
+
+        if (newLen == -1  &&  (errno == EAGAIN  ||  errno == EWOULDBLOCK)) {
+            // no data available
+            buffer_consume_end(b, 4096);
+            return;
+        }
+
+        if (newLen == 0) {
+            // socket closed
+            ssh_kill(ss);
+            return;
+        }
+
+        if (newLen < 0) {
+            printf("packetizer: read failed (return %d, errno %d)\r\n", 
+                   newLen, errno);
+            ssh_kill(ss);
+            return;
+        }
+        
+        buffer_consume_end(b, 4096 - newLen);
+    }
+
+
+    do {
+        prevState = ss->p.state;
+
+        switch (ss->p.state) {
+        case PACKETIZER_STATE_WAITING_FOR_VERSION:
+            ss->p.state = packetizer_handle_version_start(ss, b);
+            break;
+            
+        case PACKETIZER_STATE_READING_NOT_VERSION:
+            ss->p.state = packetizer_handle_not_version(ss, b);
+            break;
+            
+        case PACKETIZER_STATE_READING_VERSION:
+            ss->p.state = packetizer_handle_version(ss, b);
+            break;
+            
+        case PACKETIZER_STATE_READING_PACKET_HEADER:
+            ss->p.state = packetizer_handle_header(ss, b);
+            break;
+            
+        case PACKETIZER_STATE_READING_PACKET_BODY: 
+            ss->p.state = packetizer_handle_body(ss, b);
+            break;
+
+        case PACKETIZER_STATE_CLOSED:
+            ss->p.state = PACKETIZER_STATE_CLOSED;
+            break;
+
+        default:
+            // busted!
+            printf("packetizer: BUSTED!\r\n");
+            ssh_kill(ss);
+            break;
+        }
+    } while (ss->p.state != prevState  &&  
+             ss->p.state != PACKETIZER_STATE_CLOSED);
+}
+
+
+static void packetizer_cleanup(ssh_session_t *ss)
+{
+    if (ss->p.local_version_string) arena_free(ss->p.local_version_string);
+    if (ss->p.remote_version_string) arena_free(ss->p.remote_version_string);
+    buffer_free(&ss->p.unhandledData);
+    buffer_free(&ss->p.decryptedData);
+    keys_free(&ss->p.inKeys);
+    keys_free(&ss->p.outKeys);
+    cipher_cleanup(&ss->p.inContext);
+    cipher_cleanup(&ss->p.outContext);
+
+    memset(&ss->p, 0, sizeof(ss->p));
+    ss->p.state = PACKETIZER_STATE_CLOSED;
+}
+
+
+void packetizer_kill(ssh_session_t *ss)
+{
+    if (ss->p.state != PACKETIZER_STATE_CLOSED) {
+        packetizer_cleanup(ss);
+    }
+}
+
+
+void packetizer_close(ssh_session_t *ss)
+{
+    // clean shutdown is same as kill
+    packetizer_kill(ss);
+}
+
+
+int packetizer_is_open(ssh_session_t *ss) {
+    return (ss->p.state != PACKETIZER_STATE_STARTING  &&  
+            ss->p.state != PACKETIZER_STATE_CLOSED);
+}
+
+
+int packetizer_is_closing(ssh_session_t *ss) {
+    // packetizer is never closing
+    return 0;
+}
+
+void packetizer_start(ssh_session_t *ss, char *local_version_string)
+{
+    if (ss->p.state == PACKETIZER_STATE_STARTING) {
+        Cipher *none;
+
+        printf("Starting SSHv2 session\r\n");
+        printf("   Sending version...\r\n");
+
+        none = cipher_by_name("none");
+
+        buffer_init(&ss->p.unhandledData);
+        buffer_init(&ss->p.decryptedData);
+        
+        ss->p.inHeaderLength = 8;
+        ss->p.outHeaderLength = 8;
+        
+        ss->p.local_version_string = arena_strdup(local_version_string);
+        
+        cipher_init(&ss->p.inContext,  none, "", 0, NULL, 0, CIPHER_DECRYPT);
+        cipher_init(&ss->p.outContext, none, "", 0, NULL, 0, CIPHER_ENCRYPT);
+
+        {
+            // WARNING WARNING WARNING
+            // The client version and line terminator MUST be sent in 
+            // a single packet. The SSH server SSH-1.99-Cisco-1.25 will 
+            // kill the connection if the version and line terminator 
+            // are in separate TCP packets.
+            // The code below uses a single write() to send a single packet.
+            char *eoln = "\r\n";
+            int len = strlen(local_version_string) + strlen(eoln);
+            char *buf = arena_malloc(len + 1);
+            strcpy(buf, local_version_string);
+            strcat(buf, eoln);
+            write(ss->s.socket, buf, len);
+            arena_free(buf);
+        }
+
+        ss->p.state = PACKETIZER_STATE_WAITING_FOR_VERSION;
+    }
+}
diff --git a/ssh/packetizer.h b/ssh/packetizer.h
new file mode 100644 (file)
index 0000000..64f011a
--- /dev/null
@@ -0,0 +1,41 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef PACKETIZER_H
+#define PACKETIZER_H
+
+#include "includes.h"
+#include "session.h"
+#include "openssh/buffer.h"
+
+void packetizer_send_payload(ssh_session_t *ss, Buffer *payload) PACKETIZER_SEGMENT;
+void packetizer_change_crypto(ssh_session_t *ss, Keys *newInKeys, Keys *newOutKeys) PACKETIZER_SEGMENT;
+void packetizer_receive_data(ssh_session_t *ss) PACKETIZER_SEGMENT;
+void packetizer_start(ssh_session_t *ss, char *local_version_string) PACKETIZER_SEGMENT;
+int packetizer_is_open(ssh_session_t *ss) PACKETIZER_SEGMENT;
+int packetizer_is_closing(ssh_session_t *ss) PACKETIZER_SEGMENT;
+void packetizer_close(ssh_session_t *ss) PACKETIZER_SEGMENT;
+void packetizer_kill(ssh_session_t *ss) PACKETIZER_SEGMENT;
+
+#endif
diff --git a/ssh/session.c b/ssh/session.c
new file mode 100644 (file)
index 0000000..22576ee
--- /dev/null
@@ -0,0 +1,74 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+
+#include "session.h"
+#include "packetizer.h"
+#include "ssh2.h"
+#include "openssh/bufaux.h"
+#include "xmalloc.h"
+
+static void session_cleanup(ssh_session_t *ss) SSH_SEGMENT;
+
+static void session_cleanup(ssh_session_t *ss)
+{
+    if (ss->s.socket >= 0) {
+        close(ss->s.socket);
+        // this print must only happen once
+        printf("\r\nConnection closed.\r\n");
+    }
+    if (ss->s.hostname) arena_free(ss->s.hostname);
+    if (ss->s.hostaddr) arena_free(ss->s.hostaddr);
+
+    memset(&ss->s, 0, sizeof(ss->s));
+    ss->s.socket = -1;
+    ss->s.state = SESSION_STATE_CLOSED;
+}
+
+void session_kill(ssh_session_t *ss)
+{
+    if (ss->s.state != SESSION_STATE_CLOSED) {
+        session_cleanup(ss);
+    }
+}
+
+
+void session_close(ssh_session_t *ss)
+{
+    // clean shutdown is same as kill
+    session_kill(ss);
+}
+
+int session_is_open(ssh_session_t *ss) 
+{
+    return (ss->s.state != SESSION_STATE_STARTING  &&  
+            ss->s.state != SESSION_STATE_CLOSED);
+}
+
+int session_is_closing(ssh_session_t *ss)
+{
+    // session is never closing
+    return 0;
+}
diff --git a/ssh/session.h b/ssh/session.h
new file mode 100644 (file)
index 0000000..d573520
--- /dev/null
@@ -0,0 +1,253 @@
+/**********
+ * Copyright (c) 2003-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef SESSION_H
+#define SESSION_H
+
+#include "includes.h"
+#include "queue.h"
+#include "ssh.h"
+#include "openssh/buffer.h"
+#include "openssh/mac.h"
+#include "openssh/cipher.h"
+#include "crypto/openssl/dh/dh.h"
+#include "crypto/openssl/evp/evp.h"
+#include "sshzlib.h"
+#include "vt100/vt100.h"
+
+typedef enum {
+    SESSION_STATE_STARTING = 0, 
+    SESSION_STATE_OPEN, 
+    SESSION_STATE_CLOSED
+} session_state_t;
+
+typedef enum {
+    PACKETIZER_STATE_STARTING = 0, 
+    PACKETIZER_STATE_WAITING_FOR_VERSION, 
+    PACKETIZER_STATE_READING_NOT_VERSION, 
+    PACKETIZER_STATE_READING_VERSION, 
+    PACKETIZER_STATE_READING_PACKET_HEADER, 
+    PACKETIZER_STATE_READING_PACKET_BODY, 
+    PACKETIZER_STATE_CLOSED
+} packetizer_state_t;
+
+typedef enum {
+    TRANSPORT_STATE_STARTING = 0, 
+    TRANSPORT_STATE_WAITING_FOR_KEXINIT, 
+    TRANSPORT_STATE_WAITING_FOR_DH_REPLY, 
+    TRANSPORT_STATE_WAITING_FOR_NEWKEYS, 
+    TRANSPORT_STATE_RUNNING, 
+    TRANSPORT_STATE_CLOSED
+} transport_state_t;
+
+typedef enum {
+    // ssh-userauth
+    CONNECTION_STATE_STARTING = 0, 
+    CONNECTION_STATE_WAITING_FOR_USERAUTH_SERVICE, 
+    CONNECTION_STATE_WAITING_FOR_NONE_USERAUTH,
+
+    // password auth
+    CONNECTION_STATE_WAITING_FOR_PASSWORD, 
+    CONNECTION_STATE_WAITING_FOR_NEW_PASSWORD, 
+    CONNECTION_STATE_WAITING_FOR_PASSWORD_USERAUTH,
+
+    // publickey auth
+    CONNECTION_STATE_WAITING_FOR_PUBKEY_CHECK, 
+    CONNECTION_STATE_WAITING_FOR_PUBKEY_PASSPHRASE,
+    CONNECTION_STATE_WAITING_FOR_PUBKEY_USERAUTH, 
+
+    // keyboard-interactive auth
+    CONNECTION_STATE_WAITING_FOR_KBDINT_INFO_REQUEST, 
+    CONNECTION_STATE_WAITING_FOR_KBDINT_RESPONSES,
+    CONNECTION_STATE_WAITING_FOR_KBDINT_USERAUTH,  
+
+    // ssh-connection
+    CONNECTION_STATE_WAITING_FOR_CHANNEL_OPEN, 
+    CONNECTION_STATE_WAITING_FOR_PTY, 
+    CONNECTION_STATE_WAITING_FOR_SHELL, 
+    CONNECTION_STATE_RUNNING, 
+    CONNECTION_STATE_CLOSING, 
+    CONNECTION_STATE_CLOSED
+} connection_state_t;
+
+
+// mini state machine for publickey auth
+typedef enum {
+    PUBKEY_STARTING = 0, 
+    PUBKEY_QUERY_PHRASELESS, 
+    PUBKEY_QUERY_PHRASEFUL, 
+    PUBKEY_GET_PASSPHRASE, 
+    PUBKEY_DONE
+} pubkey_state_t;
+
+// pubkey auth and UI:
+// Prefs holds default pubkey (if any) and per-connection pubkey (if any)
+// If prefs has no pubkey, skip publickey auth.
+// If prefs has a pubkey, send a validity check to the server. 
+// If the validity check fails, present a "choose pubkey" dialog 
+//   (if still invalid, repeat until user or server gives up)
+// If the the validity check passes, present an "enter passphrase" dialog
+//   (if wrong passphrase, repeat until user gives up)
+//   (fixme can wrong passphrase be detected?)
+// If the passphrase is correct, send the signature to the server
+// If the signature is correct, we are logged in.
+// If the signature is rejected, don't try any more pubkey auth.
+
+typedef struct {
+    char    *name;
+    Cipher  *cipher;
+    int     enabled;
+    uint16_t   key_len;
+    uint16_t   block_size;
+    uint8_t  *key;
+    uint8_t  *iv;
+} Enc;
+
+typedef struct {
+    Enc enc;
+    Mac mac;
+    Comp *comp;
+    void *comp_ctx;
+} Keys;
+
+typedef struct {
+    packetizer_state_t state;
+
+    // current crypto
+    Keys inKeys;
+    Keys outKeys;
+    CipherContext inContext;
+    CipherContext outContext;
+    uint16_t inHeaderLength; // max(8, enc->block_size)
+    uint16_t outHeaderLength; // max(8, enc->block_size)
+
+    // version strings
+    char *local_version_string;
+    char *remote_version_string;
+
+    // packet counters
+    uint32_t seqnoIn;
+    uint32_t seqnoOut;
+
+    // receive buffers
+    uint8_t paddingLength;
+    uint32_t packetLength;
+    Buffer unhandledData;
+    Buffer decryptedData;
+
+    // data handler
+    // Err (*receiveData)(ssh_session_t *ss);
+} packetizer_t;
+
+typedef struct {
+    transport_state_t state;
+    uint8_t ignore_next_packet;
+
+    // DH & kex
+    uint16_t kex_key_length; 
+    DH *dh;
+    Buffer local_kexinit;  // kexinit payload sent by client
+    Buffer remote_kexinit; // kexinit payload received from server
+    int hostkey_type;      // key type for negotiated server host key algorithm
+    uint8_t *session_id;   // current session ID hash (never gets rekeyed)
+    uint16_t session_id_len;
+    int rekey;             // FALSE if the first kex is not yet complete
+
+    // pending crypto (to be used after NEWKEYS is sent)
+    Keys newInKeys;
+    Keys newOutKeys;
+
+    // pending packets (to be sent after kex or rekey is complete)
+    Buffer *packet_queue;
+    int packet_queue_used;
+    int packet_queue_allocated;
+
+    // supported algorithms (comma-separated)
+    char *supported_kex_algorithms;
+    char *supported_hostkey_algorithms;
+    char *supported_cipher_algorithms;
+    char *supported_mac_algorithms;
+    char *supported_compression_algorithms;
+} transport_t;
+
+typedef struct {
+    connection_state_t state;
+
+    uint32_t localChannel;  // sender for out, recipient for in
+    uint32_t remoteChannel; // recipient for out, sender for in
+    uint32_t receiveWindow; 
+    uint32_t sendWindow;
+    uint32_t sendMaxPacket;
+    
+    // login
+    uint8_t passwordAttempts;
+    char *untriedAuthmethods; // stuff we like and can still try
+    char *usableAuthmethods;  // stuff the server likes
+
+    // public keys
+    pubkey_state_t pubkey_state;
+    queue_t *phraseless_pubkeys;
+    queue_t *phraseful_pubkeys;
+    queue_t *good_pubkeys;
+    MemHandle current_pubkey;
+
+    // keyboard-interactive
+    char *prompt_name;
+    char *prompt_instruction;
+    prompt_t *prompt_list;
+    uint16_t prompt_count;
+
+    // channel shutdown state
+    uint8_t channelOpen;
+    uint8_t localCloseSent;
+    uint8_t remoteCloseReceived;
+} connection_t;
+
+typedef struct {
+    session_state_t state;
+
+    int socket;
+    char *hostname;
+    char *hostaddr;
+} session_t;
+
+typedef struct ssh_session_t {
+    session_t s;    // socket
+    packetizer_t p; // version exchange; read and decrypt packets
+    transport_t t;  // key exchange; connection management
+    connection_t c; // shell and user login
+
+    struct display *tty;
+    char *username;
+
+    int closing; // do not refresh network while closing
+} ssh_session_t;
+
+
+int session_is_open(ssh_session_t *ss) SSH_SEGMENT;
+int session_is_closing(ssh_session_t *ss) SSH_SEGMENT;
+void session_close(ssh_session_t *ss) SSH_SEGMENT;
+void session_kill(ssh_session_t *ss) SSH_SEGMENT;
+
+#endif
diff --git a/ssh/ssh.c b/ssh/ssh.c
new file mode 100644 (file)
index 0000000..b3e2d3a
--- /dev/null
+++ b/ssh/ssh.c
@@ -0,0 +1,587 @@
+/**********
+ * Copyright (c) 2003-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "ssh.h"
+#include "rsrc.h"
+#include "session.h"
+#include "packetizer.h"
+#include "transport.h"
+#include "connection.h"
+#include "formutils.h"
+#include "forms/publickeychoiceform.h"
+#include "forms/kbdintform.h"
+#include "forms/kbdint0form.h"
+
+#include "vt100/vt100.h"
+
+// The "current session" being processed. 
+// This is used for malloc(), printf(), etc when deep inside libraries.
+// current_ss is set by the ssh_* functions below.
+static ssh_session_t *current_ss = NULL;
+
+
+static ssh_session_t *ssh_set_current(ssh_session_t *ss)
+{
+    ssh_session_t *old_ss = current_ss;
+    current_ss = ss;
+    return old_ss;
+}
+
+
+ssh_session_t *ssh_get_current(void)
+{
+    return current_ss;
+}
+
+
+#define SSH_SET_CURRENT  ssh_session_t *old_ss = ssh_set_current(ss)
+#define SSH_RESTORE_CURRENT  ssh_set_current(old_ss)
+
+
+ssh_session_t *ssh_create(char *username, RectangleType bounds)
+{
+    ssh_session_t *ss = 
+        (ssh_session_t *)nonarena_malloc(sizeof(ssh_session_t));
+    bzero(ss, sizeof(ssh_session_t));
+    
+    ssh_set_current(ss);
+
+    ssh_log(__PRETTY_FUNCTION__);
+
+    // nonzero init
+    // make session_init() etc. functions if this gets big
+    ss->s.socket = -1;
+
+    ss->tty = vt100_new(ss, bounds);
+    ss->username = arena_strdup(username);
+
+    ssh_set_current(NULL);
+
+    return ss;
+}
+
+// initiate ordinary connection shutdown
+// The connection may not actually be closed when this function 
+// terminates, and this session must still be processed in the event loop.
+// Use ssh_is_closed() to determine when shutdown is complete.
+// Use ssh_kill() to immediately close a connection (not cleanly)
+void ssh_close(ssh_session_t *ss)
+{
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+
+    ss->closing = 1;
+
+    if (connection_is_open(ss)) connection_close(ss);
+    if (connection_is_closing(ss)) goto done;
+    
+    if (transport_is_open(ss)) transport_close(ss);
+    if (transport_is_closing(ss)) goto done;
+
+    if (packetizer_is_open(ss)) packetizer_close(ss);
+    if (packetizer_is_closing(ss)) goto done;
+
+    if (session_is_open(ss)) session_close(ss);
+    if (session_is_closing(ss)) goto done;
+
+ done:
+    SSH_RESTORE_CURRENT;
+}
+
+void ssh_kill(ssh_session_t *ss)
+{
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+
+    ss->closing = 1;
+
+    connection_kill(ss);
+    transport_kill(ss);
+    packetizer_kill(ss);
+    session_kill(ss);
+
+    SSH_RESTORE_CURRENT;
+}
+
+void ssh_free(ssh_session_t *ss)
+{
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+
+    ssh_kill(ss);
+    arena_free(ss->username);
+    vt100_free(ss->tty);
+
+    SSH_RESTORE_CURRENT;
+
+    // ss itself is not arena allocated
+    nonarena_free(ss);
+}
+
+
+int ssh_open(ssh_session_t *ss, char *hostname, int port)
+{
+    NetHostInfoBufType *remoteHost;
+    NetSocketAddrINType remoteINAddr;
+    NetSocketAddrType *remoteAddr = (NetSocketAddrType *)&remoteINAddr;
+    char on = 1;
+    int sock;
+    int err = 0;
+
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+
+    // find remote host
+    // GrP gethostbyname() is supposed to return NULL when the host is not 
+    // found, but this doesn't seem to happen on my Tungsten C running 5.2.1.
+    // Instead, it returns &AppHostInfo, which may still have a *previous* 
+    // host lookup result! 
+    h_errno = 0;
+    bzero(&AppHostInfo, sizeof(AppHostInfo));
+    remoteHost = (NetHostInfoBufType *)gethostbyname(hostname);
+    if (!remoteHost  ||  h_errno  ||  remoteHost->hostInfo.addrLen == 0) { 
+        NetworkError("The server could not be found.", h_errno);
+        err = -1; 
+        goto done; 
+    }
+    remoteINAddr.family = AF_INET;
+    remoteINAddr.port = port;
+    remoteINAddr.addr = remoteHost->address[0];
+
+    // create socket
+    sock = socket(AF_INET, SOCK_STREAM, 0);
+    if (sock < 0) { 
+        NetworkError("Could not create network socket.", errno);
+        err = -1; 
+        goto done;
+    }
+
+    // begin connecting to remote host
+    // fixme need non-blocking connect
+    err = connect(sock, remoteAddr, sizeof(remoteINAddr));
+    if (err) { 
+        NetworkError("Could not connect to server.", errno);
+        goto done;
+    }
+
+    // set socket options: non-blocking, no coalescing on send
+    setsockopt(sock, SOL_SOCKET, netSocketOptSockNonBlocking, &on, sizeof(on));
+    setsockopt(sock, netSocketOptLevelTCP, netSocketOptTCPNoDelay, &on, sizeof(on));
+
+    ss->s.socket = sock;
+    ss->s.hostname = arena_strdup(hostname);
+    ss->s.hostaddr = arena_strdup(inet_ntoa(*(struct in_addr *)&remoteINAddr.addr));
+    ss->s.state = SESSION_STATE_OPEN;
+
+    // fixme move some of the above to session.c
+
+    packetizer_start(ss, "SSH-2.0-pssh_" PSSH_UVERSION);
+
+ done:
+    SSH_RESTORE_CURRENT;
+    return err;
+}
+
+
+int ssh_is_closed(ssh_session_t *ss)
+{
+    // fixme
+    return (!ss  ||  ss->s.socket == -1);
+}
+
+
+int ssh_request_select(ssh_session_t *ss, fd_set *rfds, fd_set *wfds)
+{
+    // fixme
+    if (ss  &&  ss->s.socket >= 0) {
+        FD_SET(ss->s.socket, rfds);
+        return ss->s.socket;
+    } else {
+        return 0;
+    }
+}
+
+
+int ssh_is_selected(ssh_session_t *ss, fd_set *fds)
+{
+    if (ss  &&  ss->s.socket >= 0) {
+        return FD_ISSET(ss->s.socket, fds);
+    } else {
+        return 0;
+    }
+}
+
+
+void ssh_read(ssh_session_t *ss)
+{
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+
+    if (ss) packetizer_receive_data(ss);
+
+    SSH_RESTORE_CURRENT;
+}
+
+
+void ssh_write(ssh_session_t *ss)
+{
+    // fixme 
+    return;
+}
+
+int ssh_app_cursor_keys(ssh_session_t *ss)
+{
+    ssh_log(__PRETTY_FUNCTION__);
+    if (ss  &&  ss->tty) return vt100_app_cursor_keys(ss->tty);
+    else return 0;
+}
+
+void ssh_key(ssh_session_t *ss, char c)
+{
+    ssh_keys(ss, &c, 1);
+}
+
+void ssh_keys(ssh_session_t *ss, uint8_t *buf, uint16_t bufLen)
+{
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+    if (!ss) return;
+
+    if (connection_is_open(ss)) {
+        connection_send_data(ss, buf, bufLen);
+    }
+
+    // maybe scroll to bottom when key is pressed
+    vt100_seen_key(ss->tty);
+
+    SSH_RESTORE_CURRENT;
+}
+
+void ssh_bytes(ssh_session_t *ss, uint8_t *buf, uint16_t bufLen)
+{
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+    if (!ss) return;
+    
+    if (connection_is_open(ss)) {
+        connection_send_data(ss, buf, bufLen);
+    }
+
+    // Non-interactive input - do NOT scroll to bottom
+
+    SSH_RESTORE_CURRENT;
+}
+
+
+void ssh_receive_bytes(ssh_session_t *ss, uint8_t *buf, uint16_t bufLen)
+{
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__ " %u bytes", bufLen);
+    if (!ss) return;
+
+    if (ss->tty) {
+        EventType e = {0};
+        vt100_write(ss->tty, buf, bufLen);
+        e.eType = usrDrawVT100Event;
+        EvtAddUniqueEventToQueue(&e, 0, true);
+    }
+
+    SSH_RESTORE_CURRENT;
+}
+
+void ssh_update(ssh_session_t *ss)
+{
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+    if (!ss) return;
+
+    if (ss->tty) vt100_update(ss->tty);
+
+    ssh_log(__PRETTY_FUNCTION__ " done");
+
+    SSH_RESTORE_CURRENT;
+}
+
+
+void ssh_task(ssh_session_t *ss)
+{
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+
+    if (ss  &&  ss->tty) vt100_task(ss->tty);
+
+    ssh_log(__PRETTY_FUNCTION__ " done");
+
+    SSH_RESTORE_CURRENT;
+}
+
+void ssh_request_password(int numAttempts)
+{
+    // do NOT call ssh_use_password until next event loop!
+    FrmPopupForm(PasswordFormID);
+}
+
+void ssh_use_password(ssh_session_t *ss, char *username, char *password)
+{
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+
+    connection_use_password(ss, username, password);
+
+    SSH_RESTORE_CURRENT;
+}
+
+
+void ssh_request_passphrase(queue_t *q)
+{
+    // do NOT call ssh_use_password until next event loop!
+    PublicKeyChoiceKeys = q;
+    FrmPopupForm(PublicKeyChoiceFormID);
+}
+
+
+Boolean ssh_use_passphrase(ssh_session_t *ss, char *username, char *passphrase,
+                           MemHandle pubkey)
+{
+    Boolean ok;
+
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+
+    ok = connection_use_passphrase(ss, username, passphrase, pubkey);
+
+    SSH_RESTORE_CURRENT;
+
+    return ok;
+}
+
+
+void ssh_request_kbdint(char *name, char *instructions, 
+                        prompt_t *prompts, int prompt_count)
+{
+    if (prompt_count == 0) {
+        KbdInt0GetResponses(name, instructions);
+    } else {
+        KbdIntGetResponses(name, instructions, prompts, prompt_count);
+    }
+}
+
+
+void ssh_use_kbdint(struct ssh_session_t *ss, char **responses) 
+{
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+
+    connection_use_kbdint(ss, responses);
+
+    SSH_RESTORE_CURRENT;
+}
+
+
+void ssh_scroll(ssh_session_t *ss, int lines)
+{
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+
+    if (ss  &&  ss->tty) vt100_scroll(ss->tty, lines);
+
+    SSH_RESTORE_CURRENT;
+}
+
+int ssh_visible_height(ssh_session_t *ss) 
+{
+    int height = 0;
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+
+    if (ss  &&  ss->tty) {
+        vt100_size(ss->tty, NULL, &height, NULL);
+    }
+
+    SSH_RESTORE_CURRENT;
+
+    return height;
+}
+
+void ssh_activate(ssh_session_t *ss)
+{
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+
+    if (ss  &&  ss->tty) {
+        EventType e = {0};
+        vt100_activate(ss->tty);
+        e.eType = usrDrawVT100Event;
+        EvtAddUniqueEventToQueue(&e, 0, true);
+    }
+
+    SSH_RESTORE_CURRENT;
+}
+
+void ssh_deactivate(ssh_session_t *ss)
+{
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+
+    if (ss  &&  ss->tty) vt100_deactivate(ss->tty);
+
+    SSH_RESTORE_CURRENT;
+}
+
+void ssh_set_bounds(ssh_session_t *ss, RectangleType bounds) 
+{
+    int charsWide, charsHigh;
+
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+
+    if (ss  &&  ss->tty) {
+        // bounds is LO-RES and entire gadget area
+        vt100_set_bounds(ss->tty, bounds);
+        
+        vt100_size(ss->tty, &charsWide, &charsHigh, &bounds);
+        // bounds is now HI-RES and text area only
+        connection_use_bounds(ss, bounds, charsWide, charsHigh);
+    }
+
+    SSH_RESTORE_CURRENT;
+}
+
+void ssh_click(ssh_session_t *ss, int x, int y, int clickCount)
+{
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+
+    if (ss  &&  ss->tty) vt100_click(ss->tty, x, y, clickCount);
+
+    SSH_RESTORE_CURRENT;
+}
+
+void ssh_deselect(ssh_session_t *ss)
+{
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+
+    if (ss  &&  ss->tty) vt100_deselect(ss->tty);
+
+    SSH_RESTORE_CURRENT;
+}
+
+
+
+void ssh_copy(ssh_session_t *ss)
+{
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+
+    if (ss  &&  ss->tty) vt100_copy(ss->tty);
+
+    SSH_RESTORE_CURRENT;
+}
+
+
+void ssh_paste(ssh_session_t *ss)
+{
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+
+    if (ss  &&  ss->tty) vt100_paste(ss->tty);
+
+    SSH_RESTORE_CURRENT;
+}
+
+
+int ssh_selection_exists(struct ssh_session_t *ss) 
+{
+    int result;
+
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+
+    if (ss  &&  ss->tty) result = vt100_selection_exists(ss->tty);
+    else result = false;
+
+    SSH_RESTORE_CURRENT;
+
+    return result;
+}
+
+void ssh_size(struct ssh_session_t *ss, int *charsWide, int *charsHigh) 
+{
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+    
+    if (ss  &&  ss->tty) vt100_size(ss->tty, charsWide, charsHigh, NULL);
+    else { *charsWide = 80; *charsHigh = 40; }
+
+    SSH_RESTORE_CURRENT;
+}
+
+
+// current set of mutable prefs:
+// * font and font size
+// * font colors
+void ssh_reread_prefs(struct ssh_session_t *ss) 
+{
+    SSH_SET_CURRENT;
+
+    ssh_log(__PRETTY_FUNCTION__);
+
+    if (ss && ss->tty) {
+        int charsWide, charsHigh;
+        RectangleType bounds;
+
+        vt100_reread_prefs(ss->tty);
+
+        // send new size notification in case it changed
+        vt100_size(ss->tty, &charsWide, &charsHigh, &bounds);
+        connection_use_bounds(ss, bounds, charsWide, charsHigh);
+    }
+
+    SSH_RESTORE_CURRENT;
+}
diff --git a/ssh/ssh.h b/ssh/ssh.h
new file mode 100644 (file)
index 0000000..03a8202
--- /dev/null
+++ b/ssh/ssh.h
@@ -0,0 +1,91 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef SSH_H
+#define SSH_H
+
+#include "includes.h"
+#include "queue.h"
+
+struct ssh_session_t;
+
+typedef struct prompt_t {
+    char *msg;
+    int echo;
+} prompt_t;
+
+struct ssh_session_t *ssh_get_current(void);
+
+// ctor and dtor
+struct ssh_session_t *ssh_create(char *username, RectangleType bounds) SSH_SEGMENT;
+void ssh_free(struct ssh_session_t *ss) SSH_SEGMENT;
+
+// connection management
+int ssh_open(struct ssh_session_t *ss, char *hostname, int port) SSH_SEGMENT;
+void ssh_close(struct ssh_session_t *ss) SSH_SEGMENT;
+void ssh_kill(struct ssh_session_t *ss) SSH_SEGMENT;
+int ssh_is_closed(struct ssh_session_t *ss) SSH_SEGMENT;
+
+// data management
+int ssh_request_select(struct ssh_session_t *ss, fd_set *rfds, fd_set *wfds) SSH_SEGMENT;
+int ssh_is_selected(struct ssh_session_t *ss, fd_set *fds) SSH_SEGMENT;
+void ssh_read(struct ssh_session_t *ss) SSH_SEGMENT;
+void ssh_write(struct ssh_session_t *ss) SSH_SEGMENT;
+
+// tty management
+int ssh_app_cursor_keys(struct ssh_session_t *ss) SSH_SEGMENT; // fixme suck
+void ssh_key(struct ssh_session_t *ss, char c) SSH_SEGMENT;
+void ssh_keys(struct ssh_session_t *ss, uint8_t *buf, uint16_t bufLen) SSH_SEGMENT;
+void ssh_bytes(struct ssh_session_t *ss, uint8_t *buf, uint16_t bufLen) SSH_SEGMENT;
+void ssh_bytes_internal(struct ssh_session_t *ss, uint8_t *buf, uint16_t bufLen) SSH_SEGMENT; 
+void ssh_receive_bytes(struct ssh_session_t *ss, uint8_t *buf, uint16_t bufLen) SSH_SEGMENT;
+void ssh_update(struct ssh_session_t *ss) SSH_SEGMENT;
+void ssh_task(struct ssh_session_t *ss) SSH_SEGMENT;
+
+// password
+// connection calls request_password
+// gui calls use_password
+void ssh_request_password(int numAttempts) SSH_SEGMENT;
+void ssh_use_password(struct ssh_session_t *ss, char *username, char *password) SSH_SEGMENT;
+void ssh_request_passphrase(queue_t *q) SSH_SEGMENT;
+Boolean ssh_use_passphrase(struct ssh_session_t *ss, char *username, char *passphrase, MemHandle pubkey) SSH_SEGMENT;
+void ssh_request_kbdint(char *name, char *instructions, prompt_t *prompts, int prompt_count) SSH_SEGMENT;
+void ssh_use_kbdint(struct ssh_session_t *ss, char **responses) SSH_SEGMENT;
+
+// vt100
+void ssh_scroll(struct ssh_session_t *ss, int lines) SSH_SEGMENT;
+int ssh_visible_height(struct ssh_session_t *ss) SSH_SEGMENT;
+void ssh_activate(struct ssh_session_t *ss) SSH_SEGMENT;
+void ssh_deactivate(struct ssh_session_t *ss) SSH_SEGMENT;
+void ssh_set_bounds(struct ssh_session_t *ss, RectangleType bounds)SSH_SEGMENT;
+void ssh_click(struct ssh_session_t *ss, int x, int y, int clickCount) SSH_SEGMENT;
+int ssh_selection_exists(struct ssh_session_t *ss) SSH_SEGMENT;
+void ssh_deselect(struct ssh_session_t *ss) SSH_SEGMENT;
+void ssh_copy(struct ssh_session_t *ss) SSH_SEGMENT;
+void ssh_paste(struct ssh_session_t *ss) SSH_SEGMENT;
+void ssh_size(struct ssh_session_t *ss, int *charsWide, int *charsHigh) SSH_SEGMENT;
+
+void ssh_reread_prefs(struct ssh_session_t *ss) SSH_SEGMENT;
+
+#endif
diff --git a/ssh/ssh2.h b/ssh/ssh2.h
new file mode 100644 (file)
index 0000000..091e52b
--- /dev/null
@@ -0,0 +1,159 @@
+/*     $OpenBSD: ssh2.h,v 1.8 2002/03/04 17:27:39 stevesk Exp $        */
+
+/*
+ * Copyright (c) 2000 Markus Friedl.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+
+/*
+ * draft-ietf-secsh-architecture-05.txt
+ *
+ *   Transport layer protocol:
+ *
+ *     1-19     Transport layer generic (e.g. disconnect, ignore, debug,
+ *              etc)
+ *     20-29    Algorithm negotiation
+ *     30-49    Key exchange method specific (numbers can be reused for
+ *              different authentication methods)
+ *
+ *   User authentication protocol:
+ *
+ *     50-59    User authentication generic
+ *     60-79    User authentication method specific (numbers can be reused
+ *              for different authentication methods)
+ *
+ *   Connection protocol:
+ *
+ *     80-89    Connection protocol generic
+ *     90-127   Channel related messages
+ *
+ *   Reserved for client protocols:
+ *
+ *     128-191  Reserved
+ *
+ *   Local extensions:
+ *
+ *     192-255  Local extensions
+ */
+
+/* ranges */
+
+#define SSH2_MSG_TRANSPORT_MIN                         1
+#define SSH2_MSG_TRANSPORT_MAX                         49
+#define SSH2_MSG_USERAUTH_MIN                          50
+#define SSH2_MSG_USERAUTH_MAX                          79
+#define SSH2_MSG_CONNECTION_MIN                                80
+#define SSH2_MSG_CONNECTION_MAX                                127
+#define SSH2_MSG_RESERVED_MIN                          128
+#define SSH2_MSG_RESERVED_MAX                          191
+#define SSH2_MSG_LOCAL_MIN                             192
+#define SSH2_MSG_LOCAL_MAX                             255
+#define SSH2_MSG_MIN                                   1
+#define SSH2_MSG_MAX                                   255
+
+/* transport layer: generic */
+
+#define SSH2_MSG_DISCONNECT                            1
+#define SSH2_MSG_IGNORE                                        2
+#define SSH2_MSG_UNIMPLEMENTED                         3
+#define SSH2_MSG_DEBUG                                 4
+#define SSH2_MSG_SERVICE_REQUEST                       5
+#define SSH2_MSG_SERVICE_ACCEPT                                6
+
+/* transport layer: alg negotiation */
+
+#define SSH2_MSG_KEXINIT                               20
+#define SSH2_MSG_NEWKEYS                               21
+
+/* transport layer: kex specific messages, can be reused */
+
+#define SSH2_MSG_KEXDH_INIT                            30
+#define SSH2_MSG_KEXDH_REPLY                           31
+
+/* dh-group-exchange */
+#define SSH2_MSG_KEX_DH_GEX_REQUEST_OLD                        30
+#define SSH2_MSG_KEX_DH_GEX_GROUP                      31
+#define SSH2_MSG_KEX_DH_GEX_INIT                       32
+#define SSH2_MSG_KEX_DH_GEX_REPLY                      33
+#define SSH2_MSG_KEX_DH_GEX_REQUEST                    34
+
+/* user authentication: generic */
+
+#define SSH2_MSG_USERAUTH_REQUEST                      50
+#define SSH2_MSG_USERAUTH_FAILURE                      51
+#define SSH2_MSG_USERAUTH_SUCCESS                      52
+#define SSH2_MSG_USERAUTH_BANNER                       53
+
+/* user authentication: method specific, can be reused */
+
+#define SSH2_MSG_USERAUTH_PK_OK                                60
+#define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ             60
+#define SSH2_MSG_USERAUTH_INFO_REQUEST                 60
+#define SSH2_MSG_USERAUTH_INFO_RESPONSE                        61
+
+/* connection protocol: generic */
+
+#define SSH2_MSG_GLOBAL_REQUEST                                80
+#define SSH2_MSG_REQUEST_SUCCESS                       81
+#define SSH2_MSG_REQUEST_FAILURE                       82
+
+/* channel related messages */
+
+#define SSH2_MSG_CHANNEL_OPEN                          90
+#define SSH2_MSG_CHANNEL_OPEN_CONFIRMATION             91
+#define SSH2_MSG_CHANNEL_OPEN_FAILURE                  92
+#define SSH2_MSG_CHANNEL_WINDOW_ADJUST                 93
+#define SSH2_MSG_CHANNEL_DATA                          94
+#define SSH2_MSG_CHANNEL_EXTENDED_DATA                 95
+#define SSH2_MSG_CHANNEL_EOF                           96
+#define SSH2_MSG_CHANNEL_CLOSE                         97
+#define SSH2_MSG_CHANNEL_REQUEST                       98
+#define SSH2_MSG_CHANNEL_SUCCESS                       99
+#define SSH2_MSG_CHANNEL_FAILURE                       100
+
+/* disconnect reason code */
+
+#define SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT    1
+#define SSH2_DISCONNECT_PROTOCOL_ERROR                 2
+#define SSH2_DISCONNECT_KEY_EXCHANGE_FAILED            3
+#define SSH2_DISCONNECT_HOST_AUTHENTICATION_FAILED     4
+#define SSH2_DISCONNECT_RESERVED                       4
+#define SSH2_DISCONNECT_MAC_ERROR                      5
+#define SSH2_DISCONNECT_COMPRESSION_ERROR              6
+#define SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE          7
+#define SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8
+#define SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE                9
+#define SSH2_DISCONNECT_CONNECTION_LOST                        10
+#define SSH2_DISCONNECT_BY_APPLICATION                 11
+#define SSH2_DISCONNECT_TOO_MANY_CONNECTIONS           12
+#define SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER         13
+#define SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14
+#define SSH2_DISCONNECT_ILLEGAL_USER_NAME              15
+
+/* misc */
+
+#define SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED          1
+#define SSH2_OPEN_CONNECT_FAILED                       2
+#define SSH2_OPEN_UNKNOWN_CHANNEL_TYPE                 3
+#define SSH2_OPEN_RESOURCE_SHORTAGE                    4
+
+#define SSH2_EXTENDED_DATA_STDERR                      1
diff --git a/ssh/sshzlib.c b/ssh/sshzlib.c
new file mode 100644 (file)
index 0000000..bf72e9e
--- /dev/null
@@ -0,0 +1,141 @@
+/**********
+ * Copyright (c) 2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "sshzlib.h"
+#include "armstubs.h"
+#include "peal.h"
+
+
+static void *zlib_compress_init(void) SSH_SEGMENT;
+static void zlib_compress_cleanup(void *ctx) SSH_SEGMENT;
+static void *zlib_decompress_init(void) SSH_SEGMENT;
+static void zlib_decompress_cleanup(void *ctx) SSH_SEGMENT;
+static int zlib_compress_block(void *ctx, unsigned char *block, size_t len,
+                               unsigned char **outblock, size_t *outlen) SSH_SEGMENT;
+static int zlib_decompress_block(void *ctx, unsigned char *block, size_t len,
+                                 unsigned char **outblock, size_t *outlen) SSH_SEGMENT;
+
+static void *zlib_compress_init(void)
+{
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    compress_log(__PRETTY_FUNCTION__);
+
+    return (void *) PealCall(arm_module, sym, NULL);
+}
+
+
+static void zlib_compress_cleanup(void *ctx)
+{
+    uint32_t param[1];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    compress_log(__PRETTY_FUNCTION__);
+
+    param[0] = (uint32_t)ctx;
+    PealCall(arm_module, sym, param);
+}
+
+
+static void *zlib_decompress_init(void)
+{
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    compress_log(__PRETTY_FUNCTION__);
+
+    return (void *) PealCall(arm_module, sym, NULL);
+}
+
+
+static void zlib_decompress_cleanup(void *ctx)
+{
+    uint32_t param[1];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    compress_log(__PRETTY_FUNCTION__);
+
+    param[0] = (uint32_t)ctx;
+    PealCall(arm_module, sym, param);
+}
+
+
+static int zlib_compress_block(void *ctx, unsigned char *block, size_t len,
+                               unsigned char **outblock, size_t *outlen)
+{
+    int result;
+    uint32_t param[5];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    compress_log("%lx %lx %lx %lx %lx", ctx, block, len, outblock, outlen);
+
+    param[0] = (uint32_t)ctx;
+    param[1] = (uint32_t)block;
+    param[2] = (uint32_t)len;
+    param[3] = (uint32_t)outblock;
+    param[4] = (uint32_t)outlen;
+    result = (int) PealCall(arm_module, sym, param);
+    compress_log(__PRETTY_FUNCTION__ " done");
+    return result;
+}
+
+
+static int zlib_decompress_block(void *ctx, unsigned char *block, size_t len,
+                                 unsigned char **outblock, size_t *outlen)
+{
+    int result;
+    uint32_t param[5];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    compress_log("%lx %lx %lx %lx %lx", ctx, block, len, outblock, outlen);
+
+    param[0] = (uint32_t)ctx;
+    param[1] = (uint32_t)block;
+    param[2] = (uint32_t)len;
+    param[3] = (uint32_t)outblock;
+    param[4] = (uint32_t)outlen;
+    result = (int) PealCall(arm_module, sym, param);
+    compress_log(__PRETTY_FUNCTION__ " done");
+    return result;
+}
+
+
+const struct ssh_compress ssh_zlib_compress = {
+    zlib_compress_init,
+    zlib_compress_cleanup,
+    zlib_compress_block
+};
+
+const struct ssh_compress ssh_zlib_decompress = {
+    zlib_decompress_init,
+    zlib_decompress_cleanup,
+    zlib_decompress_block
+};
+
diff --git a/ssh/sshzlib.h b/ssh/sshzlib.h
new file mode 100644 (file)
index 0000000..7711a4d
--- /dev/null
@@ -0,0 +1,41 @@
+/**********
+ * Copyright (c) 2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef SSHZLIB_H
+#define SSHZLIB_H
+
+#include "includes.h"
+
+typedef const struct ssh_compress {
+    void *(*init) (void);
+    void (*cleanup) (void *);
+    int (*transcode) (void *, unsigned char *block, size_t len,
+                     unsigned char **outblock, size_t *outlen);
+} Comp;
+
+
+extern const struct ssh_compress ssh_zlib_compress;
+extern const struct ssh_compress ssh_zlib_decompress;
+
+#endif
diff --git a/ssh/transport.c b/ssh/transport.c
new file mode 100644 (file)
index 0000000..f028346
--- /dev/null
@@ -0,0 +1,1044 @@
+/**********
+ * Copyright (c) 2003-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+/*
+ * Copyright (c) 2001 Markus Friedl.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+
+#include "includes.h"
+#include "transport.h"
+
+#include "session.h"
+#include "connection.h"
+#include "packetizer.h"
+#include "ssh2.h"
+#include "keyfile.h"
+#include "data/prefs.h"
+#include "openssh/buffer.h"
+#include "openssh/bufaux.h"
+#include "openssh/dh.h"
+#include "openssh/kex.h"
+#include "openssh/key.h"
+#include "openssh/match.h"
+#include "crypto/rand.h"
+
+static int enc_init(Enc *enc, char *cipher) TRANSPORT_SEGMENT;
+static int comp_init(Comp **comp, void **comp_ctx, char *compression) TRANSPORT_SEGMENT;
+static int decomp_init(Comp **comp, void **comp_ctx, char *compression) TRANSPORT_SEGMENT;
+static int same_preferred_algorithm(char *alg1, char *alg2) TRANSPORT_SEGMENT;
+static void transport_set_supported_algorithms(ssh_session_t *ss) TRANSPORT_SEGMENT;
+static void transport_free_supported_algorithms(ssh_session_t *ss) TRANSPORT_SEGMENT;
+static uint16_t transport_choose_kex_key_length(ssh_session_t *ss) TRANSPORT_SEGMENT;
+static void transport_send_kexinit(ssh_session_t *ss) TRANSPORT_SEGMENT;
+static void transport_send_dh_init(ssh_session_t *ss, BIGNUM *publicKey) TRANSPORT_SEGMENT;
+static void transport_send_newkeys(ssh_session_t *ss) TRANSPORT_SEGMENT;
+static void transport_send_unimplemented(ssh_session_t *ss, uint32_t seq) TRANSPORT_SEGMENT;
+static void transport_send_disconnect(ssh_session_t *ss, uint32_t code, char *str) TRANSPORT_SEGMENT;
+static int transport_handle_kexinit_kex(ssh_session_t *ss, Buffer *packet, int *guessedWrong) TRANSPORT_SEGMENT;
+static int transport_handle_kexinit_server_host_key(ssh_session_t *ss, Buffer *packet, int *guessedWrong) TRANSPORT_SEGMENT;
+static int transport_handle_kexinit_cipher(ssh_session_t *ss, Buffer *packet) TRANSPORT_SEGMENT;
+static int transport_handle_kexinit_mac(ssh_session_t *ss, Buffer *packet) TRANSPORT_SEGMENT;
+static int transport_handle_kexinit_compression(ssh_session_t *ss, Buffer *packet) TRANSPORT_SEGMENT;
+static int transport_handle_kexinit_languages(ssh_session_t *ss, Buffer *packet) TRANSPORT_SEGMENT;
+static transport_state_t transport_handle_ignore(ssh_session_t *ss, Buffer *packet) TRANSPORT_SEGMENT;
+static transport_state_t transport_handle_debug(ssh_session_t *ss, Buffer *packet) TRANSPORT_SEGMENT;
+static transport_state_t transport_handle_disconnect(ssh_session_t *ss, Buffer *packet) TRANSPORT_SEGMENT;
+static transport_state_t transport_handle_unimplemented(ssh_session_t *ss, Buffer *packet) TRANSPORT_SEGMENT;
+static transport_state_t transport_handle_kexinit(ssh_session_t *ss, Buffer *packet) TRANSPORT_SEGMENT;
+static transport_state_t transport_handle_dh_reply(ssh_session_t *ss, Buffer *packet) TRANSPORT_SEGMENT;
+static transport_state_t transport_handle_newkeys(ssh_session_t *ss, Buffer *packet) TRANSPORT_SEGMENT;
+static transport_state_t transport_handle_re_kexinit(ssh_session_t *ss, Buffer *packet) TRANSPORT_SEGMENT;
+static transport_state_t transport_state_waiting_for_kexinit(ssh_session_t *ss, uint8_t msg, Buffer *packet) TRANSPORT_SEGMENT;
+static transport_state_t transport_state_waiting_for_dh_reply(ssh_session_t *ss, uint8_t msg, Buffer *packet) TRANSPORT_SEGMENT;
+static transport_state_t transport_state_waiting_for_newkeys(ssh_session_t *ss, uint8_t msg, Buffer *packet) TRANSPORT_SEGMENT;
+static transport_state_t transport_state_running(ssh_session_t *ss, uint8_t msg, Buffer *packet) TRANSPORT_SEGMENT;
+static void transport_cleanup(ssh_session_t *ss) TRANSPORT_SEGMENT;
+static void transport_send_queued_payloads(struct ssh_session_t *ss) TRANSPORT_SEGMENT;
+
+static int 
+enc_init(Enc *enc, char *cipher)
+{
+    enc->cipher = cipher_by_name(cipher);
+    if (!enc->cipher) return -1;
+    enc->name = cipher_name(cipher_get_number(enc->cipher)); // fixme lame
+    enc->enabled = 0;
+    enc->iv = NULL;
+    enc->key = NULL;
+    enc->key_len = cipher_keylen(enc->cipher);
+    enc->block_size = cipher_blocksize(enc->cipher);
+    transport_log("init cipher done", cipher);
+    return 0;
+}
+
+static int 
+comp_init(Comp **comp, void **comp_ctx, char *name)
+{
+    if (0 == strcmp(name, "zlib")) {
+        *comp = &ssh_zlib_compress;
+        *comp_ctx = (*comp)->init();
+        return 0;
+    } else if (0 == strcmp(name, "none")) {
+        *comp = NULL;
+        *comp_ctx = NULL;
+        return 0;
+    } else {
+        return -1;
+    }
+}
+
+static int 
+decomp_init(Comp **comp, void **comp_ctx, char *name)
+{
+    if (0 == strcmp(name, "zlib")) {
+        *comp = &ssh_zlib_decompress;
+        *comp_ctx = (*comp)->init();
+        return 0;
+    } else if (0 == strcmp(name, "none")) {
+        *comp = NULL;
+        *comp_ctx = NULL;
+        return 0;
+    } else {
+        return -1;
+    }
+}
+
+// also called by packetizer
+void keys_free(Keys *keys)
+{
+    if (keys->enc.iv)   xfree(keys->enc.iv);
+    if (keys->enc.key)  xfree(keys->enc.key);
+    if (keys->mac.key)  xfree(keys->mac.key);    
+    if (keys->comp  &&  keys->comp_ctx) keys->comp->cleanup(keys->comp_ctx);
+}
+
+// return TRUE iff the first algorithm name in each of 
+// algorithm lists alg1 and alg2 are the same
+static int same_preferred_algorithm(char *alg1, char *alg2)
+{
+    char *end1, *end2;
+    uint16_t len1, len2;
+    
+    end1 = strchr(alg1, ',');
+    if (end1) len1 = end1 - alg1;
+    else len1 = strlen(alg1);
+
+    end2 = strchr(alg2, ',');
+    if (end2) len2 = end2 - alg2;
+    else len2 = strlen(alg2);
+
+    if (len1 != len2) return 0;
+    else return (0 == strncmp(alg1, alg2, len1));
+}
+
+
+static void transport_set_supported_algorithms(ssh_session_t *ss)
+{
+    char *buf;
+
+    // fixme update here for more algorithms
+    ss->t.supported_kex_algorithms = 
+        arena_strdup("diffie-hellman-group1-sha1");
+    ss->t.supported_hostkey_algorithms = 
+        arena_strdup("ssh-rsa,ssh-dss");
+    ss->t.supported_mac_algorithms = 
+        arena_strdup("hmac-sha1");
+
+    // cipher
+    buf = arena_calloc(1+strlen("aes128-cbc,")+strlen("3des-cbc,"));
+    if (PrefsGetInt(prefCipherAES128CBC, 1)) strcat(buf, "aes128-cbc,");
+    if (PrefsGetInt(prefCipher3DESCBC, 1)) strcat(buf, "3des-cbc,");
+    // use 3des if nothing is specified
+    if (strlen(buf) == 0) strcat(buf, "3des-cbc,");
+    buf[strlen(buf)-1] = '\0'; // squish trailing comma
+    ss->t.supported_cipher_algorithms = buf;
+
+    // compression
+    if (PrefsGetInt(prefCompressZLib, defaultCompressZLib)) {
+        // zlib preferred
+        ss->t.supported_compression_algorithms = arena_strdup("zlib,none");
+    } else {
+        // no zlib preferred, but still allow it if required by server
+        ss->t.supported_compression_algorithms = arena_strdup("none, zlib");
+    }
+}
+
+
+static void transport_free_supported_algorithms(ssh_session_t *ss)
+{
+    if (ss->t.supported_kex_algorithms) 
+        arena_free(ss->t.supported_kex_algorithms);
+    if (ss->t.supported_hostkey_algorithms) 
+        arena_free(ss->t.supported_hostkey_algorithms);
+    if (ss->t.supported_cipher_algorithms) 
+        arena_free(ss->t.supported_cipher_algorithms);
+    if (ss->t.supported_mac_algorithms) 
+        arena_free(ss->t.supported_mac_algorithms);
+    if (ss->t.supported_compression_algorithms) 
+        arena_free(ss->t.supported_compression_algorithms);
+}
+
+
+static uint16_t transport_choose_kex_key_length(ssh_session_t *ss)
+{
+    // find longest key needed
+    uint16_t need = 0;
+    need = MAX(need, ss->t.newInKeys.enc.key_len);
+    need = MAX(need, ss->t.newInKeys.enc.block_size);
+    need = MAX(need, ss->t.newInKeys.mac.key_len);
+    need = MAX(need, ss->t.newOutKeys.enc.key_len);
+    need = MAX(need, ss->t.newOutKeys.enc.block_size);
+    need = MAX(need, ss->t.newOutKeys.mac.key_len);
+    return need;
+}
+
+
+static void transport_send_kexinit(ssh_session_t *ss)
+{
+    int i;
+    void *p;
+    Buffer *payload = &ss->t.local_kexinit;
+    if (!payload->buf) buffer_init(payload);
+    buffer_clear(payload);
+
+    // msg
+    buffer_put_char(payload, SSH2_MSG_KEXINIT);
+
+    // 16-byte random cookie
+    p = buffer_append_space(payload, 16);
+    RAND_bytes(p, 16);
+    
+    // kex_algorithms
+    buffer_put_cstring(payload, ss->t.supported_kex_algorithms);
+    
+    // server_host_key_algorithms
+    buffer_put_cstring(payload, ss->t.supported_hostkey_algorithms);
+
+    // encryption_algorithms (2-way)
+    buffer_put_cstring(payload, ss->t.supported_cipher_algorithms);
+    buffer_put_cstring(payload, ss->t.supported_cipher_algorithms);
+
+    // mac_algorithms (2-way)
+    buffer_put_cstring(payload, ss->t.supported_mac_algorithms);
+    buffer_put_cstring(payload, ss->t.supported_mac_algorithms);
+
+    // compression (2-way)
+    buffer_put_cstring(payload, ss->t.supported_compression_algorithms);
+    buffer_put_cstring(payload, ss->t.supported_compression_algorithms);
+
+    // languages (2-way)
+    buffer_put_cstring(payload, "");
+    buffer_put_cstring(payload, "");
+
+    // first-kex-packet-follows
+    buffer_put_char(payload, 0);
+
+    // 4-byte reserved
+    buffer_put_int(payload, 0);
+
+    packetizer_send_payload(ss, payload);
+
+    // DO NOT clear payload here - local_kexinit points to it for DH later
+
+    transport_log("transport: sent kexinit\r\n");
+}
+
+
+static void transport_send_dh_init(ssh_session_t *ss, BIGNUM *publicKey)
+{
+    Buffer payload;
+
+    if (!ss->t.rekey) printf("   Exchanging keys...\r\n");
+
+    buffer_init(&payload);
+    buffer_put_char(&payload, SSH2_MSG_KEXDH_INIT);
+    buffer_put_bignum2(&payload, publicKey);
+    packetizer_send_payload(ss, &payload);
+    buffer_free(&payload);
+    transport_log("transport: sent dh-init\r\n");
+}
+
+
+static void transport_send_newkeys(ssh_session_t *ss)
+{
+    Buffer packet;
+    buffer_init(&packet);
+    buffer_put_char(&packet, SSH2_MSG_NEWKEYS);
+    packetizer_send_payload(ss, &packet);
+    buffer_free(&packet);
+    transport_log("transport: sent newkeys\r\n");
+}
+
+
+static void transport_send_unimplemented(ssh_session_t *ss, uint32_t seq)
+{
+    Buffer packet;
+    buffer_init(&packet);
+    buffer_put_char(&packet, SSH2_MSG_UNIMPLEMENTED);
+    buffer_put_int(&packet, seq);
+    packetizer_send_payload(ss, &packet);
+    buffer_free(&packet);
+    transport_log("transport (state %d): sent unimplemented\r\n", ss->t.state);
+}
+
+
+static void transport_send_disconnect(ssh_session_t *ss, 
+                                      uint32_t code, char *str)
+{
+    Buffer packet;
+    buffer_init(&packet);
+    buffer_put_char(&packet, SSH2_MSG_DISCONNECT);
+    buffer_put_int(&packet, code);
+    buffer_put_cstring(&packet, str);
+    buffer_put_cstring(&packet, ""); // language
+    packetizer_send_payload(ss, &packet);
+    buffer_free(&packet);
+    transport_log("transport (state %d): sent disconnect\r\n", ss->t.state);
+}
+
+
+static int 
+transport_handle_kexinit_kex(ssh_session_t *ss, Buffer *packet, int *guessedWrong)
+{
+    uint16_t len;
+    uint8_t *str = NULL;
+    char *kex_name = NULL;
+
+    // kex_algorithms
+    str = buffer_get_string(packet, &len);
+    kex_name = match_list(ss->t.supported_kex_algorithms, str, NULL);
+    if (!kex_name) {
+        // server doesn't support our kex algorithm - bail
+        printf("\r\ntransport: No acceptable key exchange algorithm (server offered '%s', pssh supports '%s')\r\n", str, ss->t.supported_kex_algorithms);
+        arena_free(str);
+        return 0;
+    } else {
+        // kex kex_name OK
+    }
+
+    // Check for incorrect algorithm guess
+    if (! same_preferred_algorithm(ss->t.supported_kex_algorithms, str)) {
+        *guessedWrong = 1;
+    }
+
+    if (kex_name) arena_free(kex_name);
+    if (str) arena_free(str);
+    return 1;
+}
+    
+
+
+static int 
+transport_handle_kexinit_server_host_key(ssh_session_t *ss, Buffer *packet, int *guessedWrong)
+{
+    uint16_t len;
+    uint8_t *str = NULL;
+    char *hostkey_name = NULL;
+
+    // server_host_key_algorithms
+    str = buffer_get_string(packet, &len);
+    hostkey_name = match_list(ss->t.supported_hostkey_algorithms, str, NULL);
+    if (!hostkey_name) {
+        // server doesn't support our host key algorithm - bail
+        printf("\r\ntransport: No acceptable host key algorithm (server offered '%s', pssh supports '%s')\r\n", str, ss->t.supported_hostkey_algorithms);
+        arena_free(str);
+        return 0;
+    }
+    else {
+        // server host key algorithm ok
+        ss->t.hostkey_type = key_type_from_name(hostkey_name);
+    }
+
+    // Check for incorrect algorithm guess
+    if (! same_preferred_algorithm(ss->t.supported_hostkey_algorithms, str)) {
+        *guessedWrong = 1;
+    }
+
+    if (hostkey_name) arena_free(hostkey_name);
+    if (str) arena_free(str);
+    return 1;
+}
+
+
+static int 
+transport_handle_kexinit_cipher(ssh_session_t *ss, Buffer *packet)
+{
+    uint16_t len;
+    uint8_t *str = NULL;
+    char *cipher_name = NULL;
+
+    // encryption_algorithm (client to server)
+    str = buffer_get_string(packet, &len);
+    cipher_name = match_list(ss->t.supported_cipher_algorithms, str, NULL);
+    if (!cipher_name) {
+        // server doesn't support our ciphers - bail
+        printf("\r\ntransport: No acceptable cipher (server offered '%s', pssh supports '%s')\r\n", str, ss->t.supported_cipher_algorithms);
+        arena_free(str);
+        return 0;
+    }
+    else {
+        // cipher cipher_name OK
+        if (!ss->t.rekey) printf("%s", cipher_name);
+        if (enc_init(&ss->t.newOutKeys.enc, cipher_name) < 0) {
+            fatal("transport: failed to init cipher '%s' (out)", cipher_name);
+        }
+    }
+
+    if (cipher_name) { arena_free(cipher_name); cipher_name = NULL; }
+    if (str) { arena_free(str); str = NULL; }
+
+
+    // encryption_algorithm (server to client)
+    str = buffer_get_string(packet, &len);
+    cipher_name = match_list(ss->t.supported_cipher_algorithms, str, NULL);
+    if (!cipher_name) {
+        printf("\r\ntransport: No acceptable cipher (server offered '%s', pssh supports '%s')\r\n", str, ss->t.supported_cipher_algorithms);
+        arena_free(str);
+        return 0;
+    }
+    else {
+        // cipher cipher_name OK
+        if (enc_init(&ss->t.newInKeys.enc, cipher_name) < 0) {
+            fatal("transport: failed to init cipher '%s' (in)", cipher_name);
+        }
+    }
+
+    if (cipher_name) arena_free(cipher_name);
+    if (str) arena_free(str);
+    return 1;
+}
+
+
+static int 
+transport_handle_kexinit_mac(ssh_session_t *ss, Buffer *packet)
+{
+    uint16_t len;
+    uint8_t *str = NULL;
+    char *mac_name = NULL;
+
+    // mac_algorithm (client to server)
+    str = buffer_get_string(packet, &len);
+    mac_name = match_list(ss->t.supported_mac_algorithms, str, NULL);
+    if (!mac_name) {
+        // server doesn't support our MAC algorithm
+        printf("\r\ntransport: No acceptable MAC algorithm (server offered '%s', pssh supports '%s')\r\n", str, ss->t.supported_mac_algorithms);
+        arena_free(str);
+        return 0;
+    }
+    else {
+        // MAC mac_name OK
+        if (!ss->t.rekey) printf(" %s", mac_name);
+        if (mac_init(&ss->t.newOutKeys.mac, mac_name) < 0) {
+            fatal("transport: failed to init mac '%s' (out)", mac_name);
+        }
+    }
+
+    if (mac_name) { arena_free(mac_name); mac_name = NULL; }
+    if (str) { arena_free(str); str = NULL; }
+
+
+    // mac_algorithm (server to client)
+    str = buffer_get_string(packet, &len);
+    mac_name = match_list(ss->t.supported_mac_algorithms, str, NULL);
+    if (!mac_name) {
+        // server doesn't support our MAC algorithm
+        printf("\r\ntransport: No acceptable MAC algorithm (server offered '%s', pssh supports '%s')\r\n", str, ss->t.supported_mac_algorithms);
+        arena_free(str);
+        return 0;
+    }
+    else {
+        // MAC mac_name OK
+        if (mac_init(&ss->t.newInKeys.mac, mac_name) < 0) {
+            fatal("transport: failed to init mac '%s' (in)", mac_name);
+        }
+    }
+
+    if (mac_name) { arena_free(mac_name); mac_name = NULL; }
+    if (str) { arena_free(str); str = NULL; }
+    return 1;
+}
+
+
+static int 
+transport_handle_kexinit_compression(ssh_session_t *ss, Buffer *packet)
+{
+    uint16_t len;
+    uint8_t *str;
+    char *compress_name;
+    // compression_algorithm (client to server)
+    str = buffer_get_string(packet, &len);
+    compress_name = match_list(ss->t.supported_compression_algorithms, str, NULL);
+    if (!compress_name) {
+        // server doesn't support our compression algorithm
+        printf("\r\ntransport: No acceptable compression algorithm (server offered '%s', pssh supports '%s')\r\n", str, ss->t.supported_compression_algorithms);
+        arena_free(str);
+        return 0;
+    }
+    else {
+        // compress compress_name OK
+        if (!ss->t.rekey  &&  0 != strcmp(compress_name, "none")) {
+            printf(" %s", compress_name);
+        }
+        if (comp_init(&ss->t.newOutKeys.comp, &ss->t.newOutKeys.comp_ctx, compress_name) < 0) {
+            fatal("transport: failed to init compression '%s' (out)", compress_name);
+        }
+    }
+
+    if (compress_name) { arena_free(compress_name); compress_name = NULL; }
+    if (str) { arena_free(str); str = NULL; }
+
+
+    // compression_algorithm (server to client)
+    str = buffer_get_string(packet, &len);
+    compress_name = match_list(ss->t.supported_compression_algorithms, str, NULL);
+    if (!compress_name) {
+        // server doesn't support our compression algorithm
+        printf("\r\ntransport: No acceptable compression algorithm (server offered '%s', pssh supports '%s')\r\n", str, ss->t.supported_compression_algorithms);
+        arena_free(str);
+        return 0;
+    }
+    else {
+        // compression compress_name OK
+        if (decomp_init(&ss->t.newInKeys.comp, &ss->t.newInKeys.comp_ctx, compress_name) < 0) {
+            fatal("transport: failed to init compression '%s' (in)", compress_name);
+        }
+    }
+
+    if (compress_name) { arena_free(compress_name); compress_name = NULL; }
+    if (str) { arena_free(str); str = NULL; }
+    return 1;
+}
+
+
+static int 
+transport_handle_kexinit_languages(ssh_session_t *ss, Buffer *packet)
+{
+    uint16_t len;
+    uint8_t *str;
+
+    // languages (2-way) (ignore completely)
+    str = buffer_get_string(packet, &len);
+    arena_free(str);
+    str = buffer_get_string(packet, &len);
+    arena_free(str);
+    return 1;
+}
+
+
+
+static transport_state_t 
+transport_handle_ignore(ssh_session_t *ss, Buffer *packet)
+{
+    /* WARNING WARNING WARNING
+       Some SSH servers (including SSH-1.99-Cisco-1.25) send 
+       ignore packets that don't conform to draft-ietf-secsh-transport-17.
+       OpenSSH and PuTTY both truly ignore these packets. 
+    uint16_t len;
+    uint8_t *str = buffer_get_string(packet, &len);
+    buffer_require_empty(packet);
+    arena_free(str);
+    */
+    return ss->t.state;
+}
+
+
+static transport_state_t 
+transport_handle_debug(ssh_session_t *ss, Buffer *packet)
+{
+    uint16_t len, languageLen;
+    uint8_t alwaysDisplay = buffer_get_char(packet);
+    uint8_t *str = buffer_get_string(packet, &len);
+    uint8_t *languageStr = buffer_get_string(packet, &languageLen);
+    buffer_require_empty(packet);
+
+    if (alwaysDisplay) {
+        transport_log("transport: received debug (display): '%s'\r\n", str);
+    } else {
+        transport_log("transport: received debug (don't display): '%s'\r\n", str);
+    }
+
+    arena_free(str);
+    arena_free(languageStr);
+    return ss->t.state;
+}
+
+
+static transport_state_t 
+transport_handle_disconnect(ssh_session_t *ss, Buffer *packet)
+{
+    uint16_t len;
+    uint32_t code = buffer_get_int(packet);
+    uint8_t *str = buffer_get_string(packet, &len);
+
+    // don't bother reading language, we're about to die anyway
+    // don't bother verifying empty, we're about to die anyway
+
+    printf("transport: received disconnect (reason %ld '%s')\r\n", code, str);
+
+    ssh_kill(ss);
+    return ss->t.state;
+}
+
+
+static transport_state_t 
+transport_handle_unimplemented(ssh_session_t *ss, Buffer *packet)
+{
+    // Currently, all client-sent messages are required to be implemented 
+    // by ssh spec. If that isn't true later, we could implement some sort 
+    // of transport_expect_unimplemented function that specifies a callback.
+
+    // don't bother requiring empty packet, we're about to die anyway
+    printf("transport (state %d): received unimplemented\r\n", ss->t.state);
+    ssh_kill(ss);
+    return ss->t.state;
+}
+
+
+static transport_state_t 
+transport_handle_kexinit(ssh_session_t *ss, Buffer *packet)
+{
+    int algOK;
+    uint8_t guess;
+    int guessedWrong;
+    Buffer *rkex = &ss->t.remote_kexinit;
+
+    // save kexinit packet for DH
+    if (!rkex->buf) buffer_init(rkex);
+    buffer_clear(rkex);
+    // prepend message field (but not length field!)
+    buffer_put_char(rkex, SSH2_MSG_KEXINIT);
+    buffer_append(rkex, buffer_ptr(packet), buffer_len(packet));
+
+    buffer_consume(packet, 16); // 16-byte random cookie
+
+    // Assume remote's protocol guess is correct, if any
+    // Guess is WRONG if best kex or best server_host_key algorithms differ
+    guessedWrong = 0;
+
+    // read and check algorithms offered by server
+    if (!ss->t.rekey) printf("(");
+    algOK = 1;
+    if (algOK) algOK = transport_handle_kexinit_kex(ss, packet, &guessedWrong);
+    if (algOK) algOK = transport_handle_kexinit_server_host_key(ss, packet, &guessedWrong);
+    if (algOK) algOK = transport_handle_kexinit_cipher(ss, packet);
+    if (algOK) algOK = transport_handle_kexinit_mac(ss, packet);
+    if (algOK) algOK = transport_handle_kexinit_compression(ss, packet);
+    if (algOK) algOK = transport_handle_kexinit_languages(ss, packet);
+    if (!algOK) {
+        ssh_kill(ss);
+        return ss->t.state;
+    }
+    if (!ss->t.rekey) printf(")\r\n");
+
+
+    buffer_get(packet, &guess, 1); // first_kex_packet_follows
+    buffer_get_int(packet);        // unused reserved
+    buffer_require_empty(packet);
+
+    if (guess) {
+        printf("transport: remote sent guessed packet\r\n");
+        if (guessedWrong) {
+            // the next packet used the wrong algorithm
+            printf("transport: guessed packet is WRONG\r\n");
+            ss->t.ignore_next_packet = 1;
+        } else {
+            // the next packet is useful
+            printf("transport: guessed packet is CORRECT\r\n");
+        }
+    }
+
+    // choose kex key length based on negotiated ciphers and MACs
+    ss->t.kex_key_length = transport_choose_kex_key_length(ss);
+
+    // start diffie-hellman key exchange
+    // Derived from part of OpenSSH's kexdh_client()
+
+    if (!ss->t.rekey) printf("   Generating key...\r\n");
+
+    ss->t.dh = dh_new_group1();
+    transport_log("new group1 done");
+    dh_gen_key(ss->t.dh, ss->t.kex_key_length * 8);
+    transport_log("gen key done");
+    transport_send_dh_init(ss, ss->t.dh->pub_key);
+    transport_log("transport_handle_kexinit done");
+    return TRANSPORT_STATE_WAITING_FOR_DH_REPLY;
+}
+
+
+// Derived from part of OpenSSH's kexdh_client()
+static transport_state_t 
+transport_handle_dh_reply(ssh_session_t *ss, Buffer *packet)
+{
+    BIGNUM *dh_server_pub = NULL, *shared_secret = NULL;
+    DH *dh = ss->t.dh;
+    Key *server_host_key;
+    uint8_t *server_host_key_blob, *signature;
+    uint8_t *kbuf, *hash;
+    uint16_t klen, kout, slen, sbloblen;
+
+    /* key, cert */
+    server_host_key_blob = buffer_get_string(packet, &sbloblen);
+    server_host_key = key_from_blob(server_host_key_blob, sbloblen);
+    if (server_host_key == NULL)
+        fatal("cannot decode server_host_key_blob");
+    if (server_host_key->type != ss->t.hostkey_type)
+        fatal("type mismatch for decoded server_host_key_blob");
+    if (!check_host_key(ss->s.hostname, ss->s.hostaddr, server_host_key)) {
+        printf("   Server host key rejected.\r\n");
+        ssh_kill(ss);
+        return ss->t.state;
+    }
+
+    if (!ss->t.rekey) printf("   Calculating shared secret...\r\n");
+
+    /* DH parameter f, server public DH key */
+    dh_server_pub = BN_new();
+    buffer_get_bignum2(packet, dh_server_pub);
+
+    /* signed H */
+    signature = buffer_get_string(packet, &slen);
+    buffer_require_empty(packet);
+
+    if (!dh_pub_is_valid(dh, dh_server_pub)) 
+        fatal("bad server public DH value");
+
+    klen = DH_size(dh);
+    kbuf = arena_malloc(klen);
+    kout = DH_compute_key(kbuf, dh_server_pub, dh);
+    transport_log("computed shared secret");
+    shared_secret = BN_new();
+    BN_bin2bn(kbuf, kout, shared_secret);
+    memset(kbuf, 0, klen);
+    arena_free(kbuf);
+
+    /* calc and verify H */
+    hash = kex_dh_hash(
+                       ss->p.local_version_string, 
+                       ss->p.remote_version_string, 
+                       &ss->t.local_kexinit, 
+                       &ss->t.remote_kexinit, 
+                       server_host_key_blob, sbloblen, 
+                       dh->pub_key, 
+                       dh_server_pub, 
+                       shared_secret
+                       );
+    arena_free(server_host_key_blob);
+    BN_clear_free(dh_server_pub);
+    DH_free(dh); ss->t.dh = dh = NULL;
+
+    if (key_verify(server_host_key, signature, slen, hash, 20) != 1)
+        fatal("key_verify failed for server_host_key");
+    key_free(server_host_key);
+
+    arena_free(signature);
+    
+    /* save session id (which does not get replaced during rekey) */
+    if (ss->t.session_id == NULL) {
+        ss->t.session_id_len = SHA_DIGEST_LENGTH;
+        ss->t.session_id = arena_malloc(SHA_DIGEST_LENGTH);
+        memcpy(ss->t.session_id, hash, SHA_DIGEST_LENGTH);
+    }
+
+    transport_log("deriving keys");
+    kex_derive_keys(&ss->t.newInKeys, &ss->t.newOutKeys, ss->t.kex_key_length, 
+                    hash, shared_secret, ss->t.session_id, SHA_DIGEST_LENGTH);
+    transport_log("derived keys");
+    BN_clear_free(shared_secret);
+    arena_free(hash);
+
+    // send NEWKEYS and wait for remote's NEWKEYS
+    transport_send_newkeys(ss);
+    transport_log("sent newkeys");
+    return TRANSPORT_STATE_WAITING_FOR_NEWKEYS;
+}
+
+
+static transport_state_t 
+transport_handle_newkeys(ssh_session_t *ss, Buffer *packet)
+{
+    buffer_require_empty(packet);
+    transport_log("changing crypto");
+    packetizer_change_crypto(ss, &ss->t.newInKeys, &ss->t.newOutKeys);
+    transport_log("changed crypto");
+    connection_start(ss); // ok if it's already been started
+    transport_log("connection started");
+    ss->t.rekey = true; // first kex definitely complete
+    return TRANSPORT_STATE_RUNNING;
+}
+
+
+static transport_state_t 
+transport_handle_re_kexinit(ssh_session_t *ss, Buffer *packet)
+{
+    // server requested rekey (we never request it)
+    transport_send_kexinit(ss);
+    return transport_handle_kexinit(ss, packet);
+}
+
+
+static transport_state_t 
+transport_state_waiting_for_kexinit(ssh_session_t *ss, 
+                                    uint8_t msg, Buffer *packet) 
+{
+    if (msg == SSH2_MSG_KEXINIT) {
+        return transport_handle_kexinit(ss, packet);
+    } else {
+        transport_send_unimplemented(ss, ss->p.seqnoIn);
+        return ss->t.state;
+    }
+}
+
+
+static transport_state_t 
+transport_state_waiting_for_dh_reply(ssh_session_t *ss, 
+                                     uint8_t msg, Buffer *packet) 
+{
+    if (msg == SSH2_MSG_KEXDH_REPLY) {
+        return transport_handle_dh_reply(ss, packet);
+    } else {
+        transport_send_unimplemented(ss, ss->p.seqnoIn);
+        return ss->t.state;
+    }
+}
+
+static transport_state_t 
+transport_state_waiting_for_newkeys(ssh_session_t *ss, 
+                                    uint8_t msg, Buffer *packet) 
+{
+    if (msg == SSH2_MSG_NEWKEYS) {
+        return transport_handle_newkeys(ss, packet);
+    } else {
+        // MUST NOT accept anything other than anytime and newkeys messages
+        ssh_kill(ss);
+        return ss->t.state;
+    }
+}
+
+static transport_state_t 
+transport_state_running(ssh_session_t *ss, 
+                        uint8_t msg, Buffer *packet) 
+{
+    if (msg == SSH2_MSG_KEXINIT) {
+        return transport_handle_re_kexinit(ss, packet);
+    } 
+    else if ((msg >= SSH2_MSG_CONNECTION_MIN  &&  
+              msg <= SSH2_MSG_CONNECTION_MAX)  ||  
+             (msg >= SSH2_MSG_USERAUTH_MIN  &&  
+              msg <= SSH2_MSG_USERAUTH_MAX)  ||
+             msg == SSH2_MSG_SERVICE_ACCEPT) 
+    {
+        // fixme SERVICE_ACCEPT should be moved from connection to transport
+        connection_receive_packet(ss, msg, packet);
+        // NOTE state may have changed during connection_handle_packet !
+        return ss->t.state;
+    }  
+    else {
+        transport_send_unimplemented(ss, ss->p.seqnoIn);
+        return ss->t.state;
+    }
+}
+
+
+void transport_receive_packet(ssh_session_t *ss, Buffer *packet)
+{
+    uint8_t msg;
+
+    if (ss->t.ignore_next_packet) {
+        // Throw this packet away (bad algorithm guess during kexinit)
+        ss->t.ignore_next_packet = 0;
+        return;
+    }
+
+    buffer_get(packet, &msg, 1);
+
+    transport_log("transport (state %d): got %d\r\n", ss->t.state, msg);
+
+    switch (msg) {
+    case SSH2_MSG_IGNORE:
+        ss->t.state = transport_handle_ignore(ss, packet);
+        break;
+    case SSH2_MSG_DEBUG:
+        ss->t.state = transport_handle_debug(ss, packet);
+        break;
+    case SSH2_MSG_DISCONNECT:
+        ss->t.state = transport_handle_disconnect(ss, packet);
+        break;
+    case SSH2_MSG_UNIMPLEMENTED:
+        ss->t.state = transport_handle_unimplemented(ss, packet);
+        break;
+
+    default: 
+        switch (ss->t.state) {
+        case TRANSPORT_STATE_WAITING_FOR_KEXINIT:
+            ss->t.state = transport_state_waiting_for_kexinit(ss, msg, packet);
+            break;
+        case TRANSPORT_STATE_WAITING_FOR_DH_REPLY:
+            ss->t.state = transport_state_waiting_for_dh_reply(ss, msg,packet);
+            break;
+        case TRANSPORT_STATE_WAITING_FOR_NEWKEYS:
+            ss->t.state = transport_state_waiting_for_newkeys(ss, msg, packet);
+            break;
+        case TRANSPORT_STATE_RUNNING:
+            ss->t.state = transport_state_running(ss, msg, packet);
+            break;
+        case TRANSPORT_STATE_CLOSED:
+            printf("transport: packet (type %d) sent to closed state (%d %d %d %d)\r\n", msg, ss->s.state, ss->p.state, ss->t.state, ss->c.state);
+            ssh_kill(ss);
+            break;
+        default:
+            printf("transport: BUSTED\r\n");
+            ssh_kill(ss);
+            break;
+        }
+        break;
+    }
+
+    // Send queued packets (if any) when RUNNING
+    if (ss->t.state == TRANSPORT_STATE_RUNNING) {
+        transport_send_queued_payloads(ss);
+    }
+}
+
+
+void transport_start(ssh_session_t *ss)
+{
+    if (ss->t.state == TRANSPORT_STATE_STARTING) {
+        transport_set_supported_algorithms(ss);
+
+        printf("   Negotiating algorithms... ");
+        transport_send_kexinit(ss);
+        ss->t.state = TRANSPORT_STATE_WAITING_FOR_KEXINIT;
+    }
+}
+
+
+static void transport_cleanup(ssh_session_t *ss)
+{
+    if (ss->t.dh) DH_free(ss->t.dh);
+    if (ss->t.session_id) arena_free(ss->t.session_id); 
+    if (ss->t.packet_queue) arena_free(ss->t.packet_queue);
+    buffer_free(&ss->t.remote_kexinit);
+    buffer_free(&ss->t.local_kexinit);
+    keys_free(&ss->t.newInKeys);
+    keys_free(&ss->t.newOutKeys);
+    transport_free_supported_algorithms(ss);
+    
+    memset(&ss->t, 0, sizeof(ss->t));
+    ss->t.state = TRANSPORT_STATE_CLOSED;
+}
+
+
+void transport_kill(ssh_session_t *ss)
+{
+    if (ss->t.state != TRANSPORT_STATE_CLOSED) {
+        transport_cleanup(ss);
+    }
+}
+
+
+void transport_close(ssh_session_t *ss)
+{
+    if (ss->t.state != TRANSPORT_STATE_CLOSED  &&  
+        ss->t.state != TRANSPORT_STATE_STARTING) 
+    {
+        transport_send_disconnect(ss, 0, "");
+        transport_kill(ss);
+    }
+    ss->t.state = TRANSPORT_STATE_CLOSED;
+}
+
+
+int transport_is_open(ssh_session_t *ss) {
+    return (ss->t.state != TRANSPORT_STATE_STARTING  &&  
+            ss->t.state != TRANSPORT_STATE_CLOSED);
+}
+
+
+int transport_is_closing(ssh_session_t *ss) {
+    // transport is never closing
+    return 0;
+}
+
+
+// Used by connection layer and vt100
+// Queues packets for later transmission if transport is not RUNNING
+// (i.e. before startup and during kex and rekey)
+// Discards packets send when transport is CLOSED.
+void transport_send_payload(ssh_session_t *ss, Buffer *payload)
+{
+    if (ss->t.state == TRANSPORT_STATE_CLOSED) {
+        // throw it away
+        return;
+    }
+    else if (ss->t.state == TRANSPORT_STATE_RUNNING) {
+        // send immediately
+        packetizer_send_payload(ss, payload);
+    }
+    else {
+        // copy payload and send later
+        Buffer *b;
+        if (ss->t.packet_queue_used == ss->t.packet_queue_allocated) {
+            ss->t.packet_queue_allocated = ss->t.packet_queue_allocated*2 + 1;
+            ss->t.packet_queue = arena_realloc(ss->t.packet_queue, 
+                                               ss->t.packet_queue_allocated * 
+                                               sizeof(Buffer));
+        }
+        b = &ss->t.packet_queue[ss->t.packet_queue_used++];
+        buffer_init(b);
+        buffer_append(b, buffer_ptr(payload), buffer_len(payload));
+    }
+}
+
+
+static void transport_send_queued_payloads(struct ssh_session_t *ss)
+{
+    if (ss->t.packet_queue_used > 0) {
+        int i;
+        for (i = 0; i < ss->t.packet_queue_used; i++) {
+            Buffer *b = &ss->t.packet_queue[i];
+            packetizer_send_payload(ss, b);
+            buffer_free(b);
+        }
+        ss->t.packet_queue_used = 0;
+    }
+}
diff --git a/ssh/transport.h b/ssh/transport.h
new file mode 100644 (file)
index 0000000..7a993a7
--- /dev/null
@@ -0,0 +1,43 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef TRANSPORT_H
+#define TRANSPORT_H
+
+#include "includes.h"
+#include "session.h"
+#include "openssh/buffer.h"
+
+void transport_receive_packet(ssh_session_t *ss, Buffer *packet) TRANSPORT_SEGMENT;
+void transport_start(ssh_session_t *ss) TRANSPORT_SEGMENT;
+int transport_is_open(ssh_session_t *ss) TRANSPORT_SEGMENT;
+int transport_is_closing(ssh_session_t *ss) TRANSPORT_SEGMENT;
+void transport_close(ssh_session_t *ss) TRANSPORT_SEGMENT;
+void transport_kill(ssh_session_t *ss) TRANSPORT_SEGMENT;
+
+void transport_send_payload(ssh_session_t *ss, Buffer *payload) TRANSPORT_SEGMENT;
+
+void keys_free(Keys *keys);
+
+#endif
diff --git a/util/armstubs.c b/util/armstubs.c
new file mode 100644 (file)
index 0000000..250a479
--- /dev/null
@@ -0,0 +1,67 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "pce.h"
+#include "armstubs.h"
+
+#include "peal.h"
+
+#include "ssh/ssh.h"
+#include "data/prefs.h"
+
+PealModule *arm_module = NULL;
+
+int init_arm(void)
+{
+    if (!arm_module) {
+        uintptr_t *addr;
+        // Initialize ARM code resource
+        arm_module = PealLoadFromResources('armc', 1000);
+        if (!arm_module) return 0;
+
+        // store some 68K function pointers in ARM globals
+
+#define SAVE(fn) \
+        addr = (uintptr_t *)PealLookupSymbol(arm_module, #fn "_68K"); \
+        if (!addr) fatal("no ARM symbol %s", #fn "_68K"); \
+        *addr = ByteSwap32(&fn)
+
+        SAVE(arena_malloc);
+        SAVE(arena_free);
+        SAVE(arena_calloc);
+        SAVE(arena_realloc);
+
+        SAVE(PrefsInit);
+        SAVE(PrefsGetInt);
+        SAVE(PrefsGetString);
+        SAVE(PrefsPutInt);
+        SAVE(PrefsPutString);
+
+        SAVE(assert_failed);
+        SAVE(fatal);
+        SAVE(ssh_bytes);
+    }
+    return 1;
+}
diff --git a/util/armstubs.h b/util/armstubs.h
new file mode 100644 (file)
index 0000000..43854cc
--- /dev/null
@@ -0,0 +1,36 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef ARMSTUBS_H
+#define ARMSTUBS_H
+
+#include <stdint.h>
+#include "peal.h"
+
+extern PealModule *arm_module;
+
+int init_arm(void);
+
+#endif
+
diff --git a/util/assert.h b/util/assert.h
new file mode 100644 (file)
index 0000000..c231a33
--- /dev/null
@@ -0,0 +1,32 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef ASSERT_H
+#define ASSERT_H
+
+#include "includes.h"
+
+#define assert(c) do { if (!(c)) fatal("assertion failed (file %s line %d)", __FILE__, __LINE__); } while (0)
+
+#endif
diff --git a/util/ctype.h b/util/ctype.h
new file mode 100644 (file)
index 0000000..a1b2581
--- /dev/null
@@ -0,0 +1,91 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+// ctype.h replacement
+
+#ifndef CTYPE_H
+#define CTYPE_H
+
+static inline int isdigit(unsigned char c);
+static inline int isxdigit(unsigned char c);
+static inline int iscntrl(unsigned char c);
+static inline int isprint(unsigned char c);
+static inline int isspace(unsigned char c);
+static inline int isupper(unsigned char c);
+
+static inline unsigned char tolower(unsigned char c);
+static inline unsigned char toupper(unsigned char c);
+
+
+static inline int isdigit(unsigned char c) {
+    return (c >= '0'  &&  c <= '9');
+}
+
+
+static inline int isxdigit(unsigned char c) {
+    return ((c >= '0'  &&  c <= '9')  ||  
+            (c >= 'a'  &&  c <= 'f')  ||  
+            (c >= 'A'  &&  c <= 'F'));
+}
+
+
+static inline int iscntrl(unsigned char c) {
+    return (c <= 037  ||  c == 0177);
+}
+
+
+static inline int isprint(unsigned char c) {
+    return (c >= 040  &&  c <= 0176);
+}
+
+
+static inline int isspace(unsigned char c) {
+    return (c == '\t'  ||  c == '\n'  ||  c == '\v'  ||  
+            c == '\f'  ||  c == '\r'  ||  c == ' ');
+}
+
+
+static inline int isupper(unsigned char c) {
+    return (c >= 'A'  &&  c <= 'Z');
+}
+
+
+static inline unsigned char tolower(unsigned char c) {
+    if (c >= 'A'  &&  c <= 'Z') {
+        return c - 'A' + 'a';
+    } else {
+        return c;
+    }
+}
+
+static inline unsigned char toupper(unsigned char c) {
+    if (c >= 'a'  &&  c <= 'a') {
+        return c - 'a' + 'A';
+    } else {
+        return c;
+    }
+}
+
+
+#endif
diff --git a/util/formutils.c b/util/formutils.c
new file mode 100644 (file)
index 0000000..0a24d4d
--- /dev/null
@@ -0,0 +1,357 @@
+/**********
+ * Copyright (c) 2003-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "formutils.h"
+#include "rsrc/rsrc.h"
+#include <PalmOSGlue.h>
+
+void *PrvGetObjectByID(UInt16 id)
+{
+    FormPtr frmP = FrmGetActiveForm();
+    return FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, id));
+}
+
+UInt16 PrvGetObjectIndexByID(UInt16 id)
+{
+    FormPtr frmP = FrmGetActiveForm();
+    return FrmGetObjectIndex(frmP, id);
+}
+
+Err PrvRemoveObjectByID(UInt16 id)
+{
+    FormPtr frmP = FrmGetActiveForm();
+    return FrmRemoveObject(&frmP, FrmGetObjectIndex(frmP, id));
+}
+
+void PrvShowObjectByID(UInt16 id)
+{
+    FormPtr frmP = FrmGetActiveForm();
+    FrmShowObject(frmP, FrmGetObjectIndex(frmP, id));
+}
+
+void PrvHideObjectByID(UInt16 id)
+{
+    FormPtr frmP = FrmGetActiveForm();
+    FrmHideObject(frmP, FrmGetObjectIndex(frmP, id));
+}
+
+void PrvSetObjectVisibilityByID(UInt16 id, Boolean show) 
+{
+    FormPtr frmP = FrmGetActiveForm();
+    UInt16 index = FrmGetObjectIndex(frmP, id);
+    if (show) FrmShowObject(frmP, index);
+    else FrmHideObject(frmP, index);
+}
+
+Boolean PrvObjectVisibleByID(UInt16 id)
+{
+    FormPtr frmP = FrmGetActiveForm();
+    return FrmGlueGetObjectUsable(frmP, FrmGetObjectIndex(frmP, id));
+}
+
+void PrvGetObjectBoundsByID(UInt16 id, RectangleType *bounds)
+{
+    FormPtr frmP = FrmGetActiveForm();
+    FrmGetObjectBounds(frmP, FrmGetObjectIndex(frmP, id), bounds);
+}
+
+void PrvSetObjectBoundsByID(UInt16 id, const RectangleType *bounds)
+{
+    FormPtr frmP = FrmGetActiveForm();
+    FrmSetObjectBounds(frmP, FrmGetObjectIndex(frmP, id), bounds);
+}
+
+void PrvSetObjectHeightByID(UInt16 id, Coord height)
+{
+    RectangleType bounds;
+    FormPtr frmP = FrmGetActiveForm();
+    UInt16 index = FrmGetObjectIndex(frmP, id);
+    
+    FrmGetObjectBounds(frmP, index, &bounds);
+    bounds.extent.y = height;
+    FrmSetObjectBounds(frmP, index, &bounds);
+}
+
+void PrvSetFocusByID(UInt16 id)
+{
+    FormPtr frmP = FrmGetActiveForm();
+    SetFocusEventType e = {0};
+    e.eType = usrSetFocusEvent;
+    e.data.focus.id = id;
+    e.data.focus.form = frmP;
+    EvtAddUniqueEventToQueue((EventPtr)&e, 0, true);
+}
+
+void PrvReallySetFocus(FormPtr frmP, EventPtr e)
+{
+    SetFocusEventType *fe = (SetFocusEventType *)e;
+    if (frmP == fe->data.focus.form) {
+        FrmSetFocus(frmP, FrmGetObjectIndex(frmP, fe->data.focus.id));
+    }
+}
+
+void PrvCopyFieldContents(UInt16 id, char *dst)
+{
+    FieldPtr fldP = (FieldPtr) PrvGetObjectByID(id);
+    MemHandle h = FldGetTextHandle(fldP);
+    if (h) {
+        StrCopy(dst, MemHandleLock(h));
+        MemHandleUnlock(h);
+    } else {
+        StrCopy(dst, "");
+    }
+}
+
+Int16 PrvGetControlValue(UInt16 id)
+{
+    FormPtr frmP = FrmGetActiveForm();
+    UInt16 index = FrmGetObjectIndex(frmP, id);
+    return FrmGetControlValue(frmP, index);
+}
+
+void PrvSetControlValue(UInt16 id, Int16 value)
+{
+    FormPtr frmP = FrmGetActiveForm();
+    UInt16 index = FrmGetObjectIndex(frmP, id);
+    FrmSetControlValue(frmP, index, value);
+}
+
+const char *PrvGetControlLabel(UInt16 id)
+{
+    FormPtr frmP = FrmGetActiveForm();
+    UInt16 index = FrmGetObjectIndex(frmP, id);
+    ControlType *ctl = FrmGetObjectPtr(frmP, index);
+    return CtlGetLabel(ctl);
+}
+
+void PrvSetControlLabel(UInt16 id, const char *label)
+{
+    FormPtr frmP = FrmGetActiveForm();
+    UInt16 index = FrmGetObjectIndex(frmP, id);
+    ControlType *ctl = FrmGetObjectPtr(frmP, index);
+    CtlSetLabel(ctl, label);
+}
+
+void PrvSetControlEnabled(UInt16 id, Boolean usable)
+{
+    FormPtr frmP = FrmGetActiveForm();
+    UInt16 index = FrmGetObjectIndex(frmP, id);
+    ControlType *ctl = FrmGetObjectPtr(frmP, index);
+    CtlSetEnabled(ctl, usable);
+}
+
+Boolean PrvGetControlEnabled(UInt16 id)
+{
+    FormPtr frmP = FrmGetActiveForm();
+    UInt16 index = FrmGetObjectIndex(frmP, id);
+    ControlType *ctl = FrmGetObjectPtr(frmP, index);
+    return CtlEnabled(ctl);
+}
+
+void PrvSetControlGraphics(UInt16 id, UInt16 bitmapID, UInt16 selectedBitmapID)
+{
+    FormPtr frmP = FrmGetActiveForm();
+    UInt16 index = FrmGetObjectIndex(frmP, id);
+    ControlType *ctl = FrmGetObjectPtr(frmP, index);
+    CtlSetGraphics(ctl, bitmapID, selectedBitmapID);
+}
+
+void PrvDrawControl(UInt16 id) 
+{
+    FormPtr frmP = FrmGetActiveForm();
+    UInt16 index = FrmGetObjectIndex(frmP, id);
+    ControlType *ctl = FrmGetObjectPtr(frmP, index);
+    CtlDrawControl(ctl);
+}
+
+
+Err PrvStoreFieldToRecord(FieldPtr fld, void *recordP, UInt32 *offset)
+{
+    Err err = 0;
+    char *str;
+
+    FldReleaseFocus(fld);
+    FldCompactText(fld);
+    str = FldGetTextPtr(fld);
+    if (str) {
+        // store length byte, string, null char
+        // length byte includes null char
+        char len = 1+StrLen(str);
+        err = DmSet(recordP, *offset, 1, len);
+        if (!err) err = DmWrite(recordP, 1+*offset, str, len);
+        if (!err) *offset += 1+len;
+    } else {
+        err = DmSet(recordP, *offset, 1, 0);
+        if (!err) *offset += 1;
+    }
+    return err;
+}
+
+
+Boolean PrvSetFieldToValue(FieldPtr fld, char *str)
+{
+    MemHandle textH;
+
+    // kill old field contents, if any
+    textH = FldGetTextHandle(fld);
+    FldSetTextHandle(fld, NULL);
+    if (textH) MemHandleFree(textH);
+
+    // make new handle for field contents
+    textH = MemHandleNew(1+StrLen(str));
+    if (!textH) return false;
+
+    // set default value
+    StrCopy(MemHandleLock(textH), str);
+    MemHandleUnlock(textH);
+
+    FldSetTextHandle(fld, textH);
+    return true;
+}
+
+Boolean PrvSetFieldToValueByID(UInt16 id, char *str)
+{
+    return PrvSetFieldToValue(PrvGetObjectByID(id), str);
+}
+
+void PrvFieldSelectAll(UInt16 id) 
+{
+    FieldPtr field = PrvGetObjectByID(id);
+    UInt16 end = FldGetTextLength(field);
+    FldSetSelection(field, 0, end);
+}
+
+void PrvScrollField(UInt16 fldID, EventPtr e)
+{
+    Int16 delta = e->data.sclRepeat.newValue - e->data.sclRepeat.value;
+    WinDirectionType dir;
+
+    if (delta > 0) {
+        dir = winDown;
+    } else {
+        delta = -delta;
+        dir = winUp;
+    }
+
+    FldScrollField(PrvGetObjectByID(fldID), delta, dir);
+    PrvUpdateScrollbarForField(fldID, e->data.sclRepeat.scrollBarID);
+}
+
+
+void PrvUpdateScrollbarForField(UInt16 fldID, UInt16 sclID)
+{
+    FieldPtr fldP = PrvGetObjectByID(fldID);
+    ScrollBarPtr sclP = PrvGetObjectByID(sclID);
+    Int16 scrollPos;
+    Int16 textHeight;
+    Int16 fieldHeight;
+    Int16 maxValue;
+
+    FldGetScrollValues(fldP, &scrollPos, &textHeight, &fieldHeight); 
+
+    if (textHeight > fieldHeight) 
+        maxValue = textHeight - fieldHeight;
+    else if (scrollPos) 
+        maxValue = scrollPos;
+    else 
+        maxValue = 0;
+
+    SclSetScrollBar(sclP, scrollPos, 0, maxValue,fieldHeight-1); 
+}
+
+
+void NetworkError(char *msg, Err err)
+{
+    if (err != netErrUserCancel) {
+        char errbuf[256];
+        SysErrString(err, errbuf, sizeof(errbuf));
+        errbuf[255] = '\0';
+        FrmCustomAlert(NetworkErrorAlertID, msg, "", errbuf);
+    }
+}
+
+
+// After screen size change, resize a table to an integer number 
+// of rows, and resize a scrollbar to match it.
+// columnIndex is the (zero-based) table column to absorb any width change.
+void PrvResizeTableAndScrollbar(FormPtr frmP, Int16 dh, Int16 dv, 
+                                Int16 columnIndex, Int16 *realExtent, 
+                                UInt16 tableIndex, UInt16 scrollbarIndex)
+{
+    TablePtr table;
+    Coord rowHeight;
+    Coord columnWidth;
+    RectangleType tblBounds, sclBounds;
+
+    table = FrmGetObjectPtr(frmP, tableIndex);
+    TblGetBounds(table, &tblBounds);
+    if (*realExtent == -1) *realExtent = tblBounds.extent.y;
+    columnWidth = TblGetColumnWidth(table, columnIndex);
+    rowHeight = TblGetRowHeight(table, 0);
+    tblBounds.extent.x += dh;
+    *realExtent += dv;
+    tblBounds.extent.y = *realExtent - (*realExtent % rowHeight);
+    TblSetBounds(table, &tblBounds);
+    TblSetColumnWidth(table, columnIndex, columnWidth+dh);
+    
+    FrmGetObjectBounds(frmP, scrollbarIndex, &sclBounds);
+    sclBounds.topLeft.x += dh;
+    sclBounds.extent.y = tblBounds.extent.y;
+    FrmSetObjectBounds(frmP, scrollbarIndex, &sclBounds);
+}
+
+
+void PrvResizeFieldAndScrollbar(FormPtr frmP, Int16 dh, Int16 dv, 
+                                UInt16 fieldIndex, UInt16 scrollbarIndex) 
+{
+    FieldPtr field;
+    Coord rowHeight;
+    RectangleType fldBounds, sclBounds;
+
+    field = FrmGetObjectPtr(frmP, fieldIndex);
+    FrmGetObjectBounds(frmP, fieldIndex, &fldBounds);
+    fldBounds.extent.x += dh;
+    fldBounds.extent.y += dv;
+    FrmSetObjectBounds(frmP, fieldIndex, &fldBounds);
+    FldRecalculateField(field, false);
+    
+    FrmGetObjectBounds(frmP, scrollbarIndex, &sclBounds);
+    sclBounds.extent.y = fldBounds.extent.y;
+    sclBounds.extent.x += dh;
+    FrmSetObjectBounds(frmP, scrollbarIndex, &sclBounds);
+    PrvUpdateScrollbarForField(FrmGetObjectId(frmP, fieldIndex), 
+                               FrmGetObjectId(frmP, scrollbarIndex));
+}
+
+void PrvMoveObject(FormPtr frmP, UInt16 id, Int16 dh, Int16 dv)
+{
+    RectangleType bounds;
+    UInt16 index = FrmGetObjectIndex(frmP, id);
+
+    FrmGetObjectBounds(frmP, index, &bounds);
+    bounds.topLeft.x += dh;
+    bounds.topLeft.y += dv;
+    FrmSetObjectBounds(frmP, index, &bounds);
+}
diff --git a/util/formutils.h b/util/formutils.h
new file mode 100644 (file)
index 0000000..f073ac5
--- /dev/null
@@ -0,0 +1,70 @@
+/**********
+ * Copyright (c) 2003-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef FORMUTILS_H
+#define FORMUTILS_H
+
+#include "includes.h"
+
+void *PrvGetObjectByID(UInt16 id) FORMS_SEGMENT;
+UInt16 PrvGetObjectIndexByID(UInt16 id) FORMS_SEGMENT;
+Err PrvRemoveObjectByID(UInt16 id) FORMS_SEGMENT;
+void PrvShowObjectByID(UInt16 id) FORMS_SEGMENT;
+void PrvHideObjectByID(UInt16 id) FORMS_SEGMENT;
+void PrvSetObjectVisibilityByID(UInt16 id, Boolean show) FORMS_SEGMENT;
+Boolean PrvObjectVisibleByID(UInt16 id) FORMS_SEGMENT;
+void PrvGetObjectBoundsByID(UInt16 id, RectangleType *bounds) FORMS_SEGMENT;
+void PrvSetObjectBoundsByID(UInt16 id, const RectangleType *bounds) FORMS_SEGMENT;
+void PrvSetObjectHeightByID(UInt16 id, Coord height) FORMS_SEGMENT;
+
+void PrvSetFocusByID(UInt16 id) FORMS_SEGMENT;
+void PrvReallySetFocus(FormPtr frmP, EventPtr e) FORMS_SEGMENT;
+Int16 PrvGetControlValue(UInt16 id) FORMS_SEGMENT;
+void PrvSetControlValue(UInt16 id, Int16 value) FORMS_SEGMENT;
+const char *PrvGetControlLabel(UInt16 id) FORMS_SEGMENT;
+void PrvSetControlLabel(UInt16 id, const char *label) FORMS_SEGMENT;
+void PrvSetControlEnabled(UInt16 id, Boolean usable) FORMS_SEGMENT;
+Boolean PrvGetControlEnabled(UInt16 id) FORMS_SEGMENT;
+void PrvSetControlGraphics(UInt16 id, UInt16 bitmapID, UInt16 selectedBitmapID) FORMS_SEGMENT;
+void PrvDrawControl(UInt16 id) FORMS_SEGMENT;
+
+void PrvCopyFieldContents(UInt16 id, char *dst) FORMS_SEGMENT;
+Err PrvStoreFieldToRecord(FieldPtr fld, void *recordP, UInt32 *offset) FORMS_SEGMENT;
+Boolean PrvSetFieldToValue(FieldPtr fld, char *str) FORMS_SEGMENT;
+Boolean PrvSetFieldToValueByID(UInt16 id, char *str) FORMS_SEGMENT;
+void PrvFieldSelectAll(UInt16 id) FORMS_SEGMENT;
+
+void PrvScrollField(UInt16 fldID, EventPtr e) FORMS_SEGMENT;
+void PrvUpdateScrollbarForField(UInt16 fldID, UInt16 sclID) FORMS_SEGMENT;
+
+void NetworkError(char *msg, Err err) FORMS_SEGMENT;
+
+void PrvResizeTableAndScrollbar(FormPtr frmP, Int16 dh, Int16 dv, 
+                                Int16 columnIndex, Int16 *realExtent, 
+                                UInt16 tableIndex, UInt16 scrollbarIndex) FORMS_SEGMENT;
+void PrvResizeFieldAndScrollbar(FormPtr frmP, Int16 dh, Int16 dv, 
+                                UInt16 tableIndex, UInt16 scrollbarIndex) FORMS_SEGMENT;
+void PrvMoveObject(FormPtr frmP, UInt16 id, Int16 dh, Int16 dv) FORMS_SEGMENT;
+
+#endif
diff --git a/util/includes.h b/util/includes.h
new file mode 100644 (file)
index 0000000..7e4d5ba
--- /dev/null
@@ -0,0 +1,206 @@
+/**********
+ * Copyright (c) 2003-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef INCLUDES_H
+#define INCLUDES_H
+
+
+#define CRYPTO_SEGMENT  __attribute__ ((section ("crypto")))
+#define CRYPTO2_SEGMENT  __attribute__ ((section ("crypto2")))
+#define VT100_SEGMENT   __attribute__ ((section ("vt100")))
+#define TERMINAL_SEGMENT   __attribute__ ((section ("terminal")))
+#define SSH_SEGMENT     __attribute__ ((section ("ssh")))
+#define FORMS_SEGMENT   __attribute__ ((section ("forms")))
+#define SSH2_SEGMENT __attribute__ ((section ("ssh2")))
+// no relation to ssh2 protocol
+
+
+#define PACKETIZER_SEGMENT SSH2_SEGMENT
+#define CONNECTION_SEGMENT SSH_SEGMENT
+#define TRANSPORT_SEGMENT SSH2_SEGMENT
+#define KEX_SEGMENT SSH_SEGMENT
+#define SSHDH_SEGMENT SSH_SEGMENT
+#define MAC_SEGMENT SSH_SEGMENT
+
+#define OPENSSL_SEGMENT CRYPTO_SEGMENT
+#define SHA_SEGMENT CRYPTO_SEGMENT
+#define SHA2_SEGMENT CRYPTO_SEGMENT
+#define AES_SEGMENT CRYPTO_SEGMENT
+#define DES_SEGMENT CRYPTO_SEGMENT
+#define EVP_SEGMENT CRYPTO_SEGMENT
+#define DH_SEGMENT CRYPTO_SEGMENT
+#define HMAC_SEGMENT CRYPTO_SEGMENT
+
+#define RSA_SEGMENT CRYPTO2_SEGMENT
+#define DSA_SEGMENT CRYPTO2_SEGMENT
+#define FORTUNA_SEGMENT CRYPTO2_SEGMENT
+#define RAND_SEGMENT CRYPTO2_SEGMENT
+#define MD5_SEGMENT CRYPTO2_SEGMENT
+
+#define DATA_SEGMENT CRYPTO2_SEGMENT
+#define HOSTKEYS_SEGMENT DATA_SEGMENT
+#define CONNECTIONLIST_SEGMENT DATA_SEGMENT
+#define PUBLICKEYS_SEGMENT DATA_SEGMENT
+#define RECORDLIST_SEGMENT DATA_SEGMENT
+
+#define PUTTY_SEGMENT VT100_SEGMENT
+#define CHARSET_SEGMENT VT100_SEGMENT
+
+#define RESIZE_SECTION FORMS_SEGMENT
+#define DIA_SECTION FORMS_SEGMENT
+
+// Palm headers
+#include <PalmOS.h>
+#include <sys_types.h>
+#include <sys_socket.h>
+#include <unix_stdio.h>
+#include <stdint.h>
+#include "stdlib.h"
+
+// undo definition from FloatMgr.h
+#undef BIG_ENDIAN
+#define BIG_ENDIAN 4321
+#define LITTLE_ENDIAN 1234
+#define BYTE_ORDER BIG_ENDIAN
+
+// undo definitions from unix_string.h
+#undef strcpy
+#undef strncpy
+#undef strcmp
+#undef strcat
+#undef strlen
+#undef strchr
+#undef strstr
+#undef memcpy
+#undef memset
+#undef memcmp
+#undef index
+
+// prototypes for gcc builtins
+extern char *strcpy(char *dst, const char *src);
+extern char *strncpy(char *dst, const char *src, size_t len);
+extern size_t strlen(const char *s);
+extern char *strchr(const char *s, int c);
+extern char *strrchr(const char *s, int c);
+extern char *strstr(const char *big, const char *little);
+extern void *memcpy(void *dst, const void *src, size_t len);
+extern void *memset(void *b, int c, size_t len);
+extern int strncmp(const char *s1, const char *s2, size_t len);
+extern void *memmove(void *dst, const void *src, size_t len);
+extern char *strcat(char *s, const char *append);
+extern char *strncat(char *s, const char *append, size_t count);
+
+
+
+
+// #define RCSID(str) static const char *rcs = str
+#define RCSID(str) /* */
+
+#ifndef MAX
+# define MAX(a,b) (((a)>(b))?(a):(b))
+# define MIN(a,b) (((a)<(b))?(a):(b))
+#endif
+
+#ifndef roundup
+# define roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
+#endif
+
+
+extern void complain(char *s);
+extern void complain_int(char *err, uint32_t i);
+
+static inline void noop() { }
+
+// Define the following as debug_printf to get logging
+
+// OpenSSH (fixme move somewhere else)
+#define log noop
+#define logit noop
+#define debug1 noop
+#define debug2 noop
+#define debug3 noop
+#define error fatal
+
+// not OpenSSH
+#define ssh_log noop
+#define transport_log noop
+#define packetizer_log noop
+#define connection_log noop
+#define fortuna_log noop
+#define rand_log noop
+#define vt100_log noop
+#define kbdint_log noop
+#define compress_log noop
+
+
+typedef uint32_t u_int32_t;
+typedef uint64_t u_int64_t;
+typedef uint16_t wchar_t;
+typedef int32_t ssize_t;
+
+// custom event types
+#define usrNetEvent (sysEventFirstUserEvent+0)
+#define usrDrawVT100Event (sysEventFirstUserEvent+1)
+#define usrDrawCloseBoxEvent (sysEventFirstUserEvent+2)
+#define usrSetScrollBarEvent (sysEventFirstUserEvent+3)
+#define usrSetFocusEvent (sysEventFirstUserEvent+4)
+
+typedef struct {
+    eventsEnum eType;
+    Boolean penDown;
+    UInt8 tapCount;
+    Int16 screenX;
+    Int16 screenY;
+    union {
+        struct _GenericEventType generic;
+        struct {
+            void *frontend;
+            int16_t total;
+            int16_t start;
+            int16_t page;
+        } sbar;
+    } data;
+} SetScrollBarEventType;
+
+typedef struct {
+    eventsEnum eType;
+    Boolean penDown;
+    UInt8 tapCount;
+    Int16 screenX;
+    Int16 screenY;
+    union {
+        struct _GenericEventType generic;
+        struct {
+            UInt16 id;
+            FormPtr form;
+        } focus;
+    } data;
+} SetFocusEventType;
+
+
+// prototypes for main.c
+
+Boolean ApplicationHandleEvent(EventPtr e) FORMS_SEGMENT;
+
+#endif
diff --git a/util/limits.h b/util/limits.h
new file mode 100644 (file)
index 0000000..e534db0
--- /dev/null
@@ -0,0 +1,31 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef LIMITS_H
+#define LIMITS_H
+
+// GrP Palm int is 16-bit
+#define INT_MAX 32767
+
+#endif
diff --git a/util/oem/PalmChars.h b/util/oem/PalmChars.h
new file mode 100644 (file)
index 0000000..efb1610
--- /dev/null
@@ -0,0 +1,144 @@
+/******************************************************************************
+ *
+ * Copyright (c) 1994-2002 Palm, Inc. or its subsidiaries.
+ * All rights reserved.
+ *
+ * File: PalmChars.h
+ *
+ * Release: 
+ *
+ * Description:
+ *      Header file for all Palm Devices
+ *      Contains Palm-specific vchrs
+ *
+ *****************************************************************************/
+
+#ifndef __PALMCHARS_H__
+#define __PALMCHARS_H__
+
+#include <Chars.h>
+
+#if (vchrPalmMin != 0x0500) || (vchrPalmMax != 0x05FF)
+#error "please check Palm vchr range or update the above assertion"
+#endif
+
+#define vchrSilkClock           (vchrPalmMin + 0)
+#define vchrClock               (vchrPalmMin + 1)
+
+#define vchrPopupBrightness     (vchrPalmMin + 2)
+
+#define vchrNavChange           (vchrPalmMin + 3)
+#define vchrNavReserved0        (vchrPalmMin + 4)
+#define vchrNavReserved1        (vchrPalmMin + 5)
+#define vchrNavReserved2        (vchrPalmMin + 6)
+#define vchrNavReserved3        (vchrPalmMin + 7)
+
+#define keyBitNavLeft           0x01000000
+#define keyBitNavRight          0x02000000
+#define keyBitNavSelect         0x04000000
+#define keyBitNavLRS            0x07000000
+
+#define navBitUp                0x0001
+#define navBitDown              0x0002
+#define navBitLeft              0x0004
+#define navBitRight             0x0008
+#define navBitSelect            0x0010
+#define navBitsAll              0x001F
+
+#define navChangeUp             0x0100
+#define navChangeDown           0x0200
+#define navChangeLeft           0x0400
+#define navChangeRight          0x0800
+#define navChangeSelect         0x1000
+#define navChangeBitsAll        0x1F00
+
+#define navFtrCreator           'fway'
+#define navFtrVersion           0
+
+#define navVersion              0x00010000      /* header version 1.0 */
+
+
+// A macro to use for apps that support navigation using the 5-way.
+// This macro will let you test whether an event was generated by the 5-way.
+// For applications that treat up and down hard buttons differently than up and
+// down on the 5-way, this macro can be used to determine which action to take
+// if NavKeyPressed returns true for Up or Down.
+//
+// Usage:      if (IsFiveWayNavEvent(eventP))
+//
+#define IsFiveWayNavEvent(eventP)                                                                                                                                              \
+       (                                                                                                                                                                                                                               \
+                ((eventP)->data.keyDown.chr == vchrPageUp ||                                                                                           \
+                 (eventP)->data.keyDown.chr == vchrPageDown ||                                                                                         \
+                 (eventP)->data.keyDown.chr == vchrNavChange)                                                                                          \
+       &&                                                                                                                                                                                                                              \
+                (((eventP)->data.keyDown.keyCode & (navBitsAll | navChangeBitsAll)) != 0)                      \
+       )
+
+
+// A macro to use for apps that support navigation using the 5-way.
+// By using this macro, we have consistent behavior in all our apps
+// when it comes to how it handles multiple simultaneous button presses.
+//
+// Usage:      if (NavSelectPressed(eventP))
+//
+// Only act when the select button is released, and only if none of the
+// direction buttons are down (or being released) at the time, and only if the select
+// button has not been held down long enough to start repeating. By ignoring repeat
+// events for the select button, we ensure that the launcher will be run if the select
+// button is held down. By waiting until the button is released, we ensure that the
+// select action is not taken before the launcher is run.
+#define NavSelectPressed(eventP)                                                                                                                                                       \
+       (                                                                                                                                                                                                                               \
+               IsFiveWayNavEvent(eventP)                                                                                                                                                       \
+       &&                                                                                                                                                                                                                              \
+               (((eventP)->data.keyDown.modifiers & autoRepeatKeyMask) == 0)                                                   \
+       &&                                                                                                                                                                                                                              \
+               (((eventP)->data.keyDown.keyCode & (navBitsAll | navChangeBitsAll)) ==                          \
+                                                                                                                                                navChangeSelect)                                               \
+       )
+
+
+// A macro to use for apps that support navigation using the 5-way.
+// By using this macro, we have consistent behavior in all our apps
+// when it comes to how it handles multiple simultaneous button presses.
+// You can use this macro even if the device does not have a 5-way controller.
+//
+// Usage:      if (NavDirectionPressed(eventP, Left))
+//                     if (NavDirectionPressed(eventP, Right))
+//                     if (NavDirectionPressed(eventP, Up))                    - also works without 5-way
+//                     if (NavDirectionPressed(eventP, Down))                  - also works without 5-way
+//
+// Act only when one direction is pressed without any other direction (or select) being
+// down at the time. Repeat if the button is held down, but not if other buttons are
+// pressed.
+#define NavDirectionPressed(eventP, nav)                                                                                                                                               \
+       (IsFiveWayNavEvent(eventP)                                                                                                                                                              \
+               ? (((eventP)->data.keyDown.modifiers & autoRepeatKeyMask)                                                               \
+                       ? (((eventP)->data.keyDown.keyCode & (navBitsAll | navChangeBitsAll)) ==                \
+                                               (navBit ## nav))                                                                                                                                                \
+                       : (((eventP)->data.keyDown.keyCode & (navBitsAll | navChangeBitsAll)) ==                \
+                                               (navBit ## nav | navChange ## nav)))                                                                                    \
+               : (((eventP)->data.keyDown.chr == vchrPageUp && navBit ## nav == navBitUp) ||           \
+                       ((eventP)->data.keyDown.chr == vchrPageDown && navBit ## nav == navBitDown))    \
+       )
+
+
+// A macro to use for apps that support navigation using the 5-way.
+// By using this macro, we have consistent behavior in all our apps
+// when it comes to how it handles multiple simultaneous button presses.
+// You can use this macro even if the device does not have a 5-way controller.
+//
+// Usage:      if (NavKeyPressed(eventP, Select))
+//                     if (NavKeyPressed(eventP, Left))
+//                     if (NavKeyPressed(eventP, Right))
+//                     if (NavKeyPressed(eventP, Up))                  - also works without 5-way
+//                     if (NavKeyPressed(eventP, Down))                        - also works without 5-way
+//
+#define NavKeyPressed(eventP, nav)                                                                                                                                             \
+       ((navBit ## nav == navBitSelect)                                                                                                                                                \
+               ? NavSelectPressed(eventP)                                                                                                                                                      \
+               : NavDirectionPressed(eventP, nav)                                                                                                                              \
+       )
+
+#endif /* __PALMCHARS_H__ */
diff --git a/util/oem/SonyChars.h b/util/oem/SonyChars.h
new file mode 100644 (file)
index 0000000..763dbd4
--- /dev/null
@@ -0,0 +1,198 @@
+/******************************************************************************
+ *                                                                            *
+ *            (C) Copyright 2000-2002, Sony Corporation                       *
+ *                                                                            *
+ *----------------------------------------------------------------------------*
+ *                                                                            *
+ *    <IDENTIFICATION>                                                        *
+ *       file name    : $Workfile: SonyChars.h $
+ *                                                                            *
+ *    <PROFILE>                                                               *
+ *       Sony-specific Virtual character definition                           *
+ *                                                                            *
+ *    <HISTORY>                                                               *
+ *       Started on   : 00/11/28                                              *
+ *       Last Modified: $Date: 2004/02/22 10:07:01 $
+ *                                                                            *
+ ******************************************************************************/
+/* this file is best viewed by setting TAB-stop as 3 */
+
+#ifndef __SONYCHARS_H__
+#define __SONYCHARS_H__
+
+/******************************************************************************
+ *     Min/Max                                                                *
+ ******************************************************************************/
+#if defined(vchrSonyMin) || defined(vchrSonyMax)
+       #undef vchrSonyMax
+       #undef vchrSonyMin
+#endif
+
+#define vchrSonyMin                            (0x1700)
+#define vchrSonyMax                            (0x17FF)                        /* 256 command keys */
+
+/******************************************************************************
+ *     Chars                                                                  *
+ ******************************************************************************/
+/***** Jog *****/
+       /* Developers are encouraged to use those chars */
+#define vchrJogUp                                      (0x1700)
+#define vchrJogDown                            (0x1701)
+#define vchrJogPushRepeat              (0x1702)
+#define vchrJogPushedUp                        (0x1703)
+#define vchrJogPushedDown              (0x1704)
+#define vchrJogPush                            (0x1705)
+#define vchrJogRelease                 (0x1706)
+#define vchrJogBack                            (0x1707)                /* added @ 2001 */
+#define vchrJogLeft                            (0x1708)                /* added @ 2003 */
+#define vchrJogRight                           (0x1709)                /* added @ 2003 */
+
+/*** re-define old key names ***/
+       /* Developpers are encouraged not to use those obsolete chars */
+#define vchrJogPressRepeat             vchrJogPushRepeat
+#define vchrJogPageUp                  vchrJogPushedUp
+#define vchrJogPageDown                        vchrJogPushedDown
+#define vchrJogPress                           vchrJogPush     
+
+/* movement & chars */
+/*
+        Up     PushedUp
+        A        A
+        |        |
+        |      --
+        |    --
+           --
+         ---------> Push/PushRepeat
+Release <---------
+           --
+        |    --
+        |      --
+        |        |
+        V        V
+       Down    PushedDown
+
+
+        -----------> Back
+*/
+/*** Access macros ***/
+       /* eP must be EventPtr */
+#define SonyKeyIsJog(eP)       \
+       (((eP->data.keyDown.chr >= vchrJogUp)   \
+                && (eP->data.keyDown.chr <= vchrJogRight))? true: false) 
+
+/*** Others ***/
+#define vchrRmcKeyPush                 (0x170A)
+#define vchrRmcKeyRelease              (0x170B)
+       /* each remocon-key is identified with keyCode field */
+       /* autoRepeat modifier is set when KeyPush is repeated */
+
+#define vchrCapture                            (0x170C)
+#define vchrVoiceRec                           (0x170D)
+
+#define vchrAdapterInt                 (0x170E)
+#define vchrExtCnt                             vchrAdapterInt
+
+#define vchrSonySysNotify              (0x170F)
+
+#define vchrSilkResize                 (0x1710)
+#define vchrSilkLoader                 (0x1711)
+#define vchrSilkChangeSlkw             (0x1712)
+
+#define vchrVolumeDialog               (0x1713)
+#define vchrBatteryDialog              (0x1714)
+#define vchrMediaInfoDialog    (0x1715)
+#define vchrHwrKbdHelpDialog   (0x1716)
+#define vchrGraffitiDialog             (0x1717)
+#define vchrStatusDialog               (0x1718)
+
+#define vchrCapFullRelease             vchrCapture
+#define vchrCapHalfRelease             (0x171A)
+#define vchrCapCancel                  (0x171B)
+       /* CapHalRelease is enqueued when Capture button is half-pressed. */
+       /* CapCancel is enqueued when Capture button is released after half-pressed,
+            not thoroughly pressed. */
+       /* CapHalfRelease and CapCancel are paired. */
+       /* When pushing Capture button thoroughly, only CapFullRelease is enqueued
+            and CapHalfRelease is not enqueued ahead of CapFullRelease.
+          Allowable gap between CapHalf and CapFull must be under 50msec.
+          When CapFullRelease is emitted, CapCancel is not enqueued. */
+
+#define vchrCamStateChange             (0x171C)
+       /* enqueued when camera internal state is changed, like AF begins, AF locks,
+            Exposure begins, Exposure ends,... 
+          Those states are identified by keyCode field */
+
+#define vchrHomePush                   (0x171D)
+#define vchrGraffitiDialogPush (0x171E)
+#define vchrInputDialog                        (0x171F)
+
+#define vchrHWKeyboardPush             (0x1720)
+#define vchrHWKeyboardRelease  (0x1721)
+
+#define vchrSonyShortcut               (0x1722)                // Debug use-only
+
+#define vchrBatteryAlert               (0x1723)
+
+#define        vchrCloseDialog                 (0x1724)                // close dialog
+#define        vchrDeviceMgr                   (0x1725)
+
+#define        vchrHibernation                 (0x1726)                // enter hibernation
+
+/******************************************************************************
+ *     KeyCodes                                                               *
+ ******************************************************************************/
+/*** vchrSonySysNotify ***/
+#define keyCodeNotifyNull                      (0x0000)
+#define keyCodeNotifyHoldMask          (0x0100)
+#define keyCodeNotifyHoldOn            (keyCodeNotifyHoldMask + 0x0001)
+#define keyCodeNotifyHoldOff           (keyCodeNotifyHoldMask + 0x0002)
+#define keyCodeNotifyHoldAlert (keyCodeNotifyHoldMask + 0x0003)
+
+/*** vchrRmcKeyPushed/vchrRmcKeyReleased ***/
+#define keyCodeRmcPlay                 (3303)
+#define keyCodeRmcFRPlay               (3098)
+#define keyCodeRmcFFPlay               (2498)
+#define keyCodeRmcStop                 (1993)
+#define keyCodeRmcVolDown              (1856)
+#define keyCodeRmcVolUp                        (1713)
+
+/*** vchrCamStateChange ***/
+#define keyCodeCamUnknown              (0)
+#define keyCodeCamAFStart              (1)
+#define keyCodeCamAFEnd                        (2)
+#define keyCodeCamExpStart             (3)
+#define keyCodeCamExpEnd               (4)
+
+/*** vchrSilkChangeSlkw ***/
+#define keyCodeSilkDef                 (0)
+#define keyCodeSilkInputDef    (1)
+#define keyCodeSilkPrev                        (2)
+#define keyCodeSilkFwd                 (3)
+#define keyCodeSilkBack                        (4)
+
+/*** vchrMediaInfoDialog ***/
+// keyCode is slotRefNum
+
+/*** vchrSonyShortcut ***/
+#define keyCodeSCVersionSony   (0x0001)                // Version
+#define keyCodeSCSilkMgr               (0x0002)                // Resize Speed (High/Low/None)
+#define keyCodeSCCpuConfig             (0x0003)                // Cpu Config Set (Level0/1/2...)
+#define keyCodeSCCpuConfig2    (0x0004)                // Cpu Config Get
+#define keyCodeSCDeviceReset   (0x0005)                // DeviceReset
+#define keyCodeSCIllegalBattery        (0x0006)                // Illegal battery
+#define keyCodeSCTraceInit             (0x0007)                // Call HostTraceInit
+#define keyCodeSCTraceClose    (0x0008)                // Call HostTraceClose
+#define keyCodeSCBackupStorage (0x0009)                // backup storage heap
+#define keyCodeSCRestoreStorage        (0x000a)                // restore storage heap
+#define keyCodeSCNANDFormat        (0x000b)            // Enable NAND Format
+
+       /* Option Set */        /* those options are all able to be On/Off(default) */
+#define keyCodeSCOptionSet0    (0x0010)                // 0:
+               // those codes from Set0 thru Get0 are reserved for SetX
+       /* Option Get */
+#define keyCodeSCOptionGet0    (0x0020)                // Get option bitfield
+               // those codes from Get0 thru Get are reserved for GetX
+#define keyCodeSCOptionGet             (0x0030)                // Get option bitfield
+
+#endif // __SONYCHARS_H__
+
diff --git a/util/oem/SonyErrorBase.h b/util/oem/SonyErrorBase.h
new file mode 100644 (file)
index 0000000..604c2de
--- /dev/null
@@ -0,0 +1,59 @@
+/******************************************************************************
+ *                                                                            *
+ *            (C) Copyright 2000-2002, Sony Corporation                       *
+ *                                                                            *
+ *----------------------------------------------------------------------------*
+ *                                                                            *
+ *    <IDENTIFICATION>                                                        *
+ *       file name    : $Workfile: SonyErrorBase.h $
+ *                                                                            *
+ *    <PROFILE>                                                               *
+ *       The defines of error base in sony CLIE system                        *
+ *                                                                            *
+ *    <HISTORY>                                                               *
+ *       Started on   : 00/10/30                                              *
+ *       Last Modified: $Date: 03/06/17 17:21 $
+ *                                                                            *
+ ******************************************************************************/
+/* this file is best viewed by setting TAB-stop as 3 */
+
+#ifndef __SONYERRORBASE_H__
+#define __SONYERRORBASE_H__
+
+#include <ErrorBase.h>
+#include <SonyTypes.h>
+
+// error code
+#define sonyErrorClass                         (oemErrorClass)
+#define sonySysErrorClass                      (sonyErrorClass | 0x000)
+#define sonyVFSErrorClass                      (sonyErrorClass | 0x100)
+#define sonyHRErrorClass                       (sonyErrorClass | 0x200)
+#ifndef _BUILD_FOR_PALMOS_5_
+#define sonyMsaErrorClass                      (sonyErrorClass | 0x300)
+#endif
+#ifndef _FOR_SDK_
+#define sonyMMInfoErrorClass           (sonyErrorClass | 0x340)
+#endif
+#define sonyRmcErrorClass                      (sonyErrorClass | 0x400)
+#define sonyScsiErrorClass                     (sonyErrorClass | 0x500)
+#ifndef _FOR_SDK_
+#define        sonyUSBDevErrorClass            (sonyErrorClass | 0x540)
+#define        sonyUSBHostErrorClass           (sonyErrorClass | 0x580)
+#define        sonyUSBOTGErrorClass            (sonyErrorClass | 0x5C0)
+#endif
+#define sonyIrcErrorClass                      (sonyErrorClass | 0x600)
+#define        sonyUSBPrtClsErrorClass         (sonyErrorClass | 0x640)
+#define        sonyPrintMgrErrorClass          (sonyErrorClass | 0x680)
+#define        sonyPrintDrvErrorClass          (sonyErrorClass | 0x6C0)
+#define sonySilkErrorClass                     (sonyErrorClass | 0x700)
+#define        sonyVOutErrorClass              (sonyErrorClass | 0x740)
+#define        sonyUsbCamVdClDrvErrClass (sonyErrorClass | 0x780)
+#define        sonyCamLibErrClass              (sonyErrorClass | 0x7C0)
+
+#ifndef _BUILD_FOR_PALMOS_5_
+#define sonyCapErrorClass                      (sonyErrorClass | 0x800)
+#endif
+#define sonyJpegErrorClass                     (sonyErrorClass | 0x900)
+#define sonyCFLibErrorClass                    (sonyErrorClass | 0x9C0)
+#endif // __SONYERRORBASE_H__
+
diff --git a/util/oem/SonyHRLib.h b/util/oem/SonyHRLib.h
new file mode 100644 (file)
index 0000000..062ff7f
--- /dev/null
@@ -0,0 +1,447 @@
+/******************************************************************************\r
+ *                                                                            *\r
+ *            (C) Copyright 2000-2002, Sony Corporation                       *\r
+ *                                                                            *\r
+ *----------------------------------------------------------------------------*\r
+ *                                                                            *\r
+ *    <IDENTIFICATION>                                                        *\r
+ *       file name    : $Workfile: SonyHRLib.h $\r
+ *                                                                            *\r
+ *    <PROFILE>                                                               *\r
+ *       High Resolution APIs                                                 *\r
+ *                                                                            *\r
+ *    <HISTORY>                                                               *\r
+ *       Started on   : 01/01/17                                              *\r
+ *       Last Modified: $Date: 2005/05/15 09:06:04 $\r
+ *       Ver 0.10 : 2000/12/17                                                *\r
+ *                                                                            *\r
+ ******************************************************************************/\r
+/* this file is best viewed by setting TAB-stop as 3 */\r
+\r
+#ifndef __SONYHIGHRESLIB_H__\r
+#define __SONYHIGHRESLIB_H__\r
+\r
+#include <SonySystemResources.h>\r
+#include <SonyErrorBase.h>\r
+\r
+// BUILDING_APPLICATION\r
+#if BUILDING_APP_OR_LIB_HIGH_RES || CPU_TYPE != CPU_68K\r
+       // direct link to library code\r
+       #define HR_TRAP(trapNum)\r
+#else\r
+       // else someone else is including this public header file; use traps\r
+       #define HR_TRAP(trapNum)        SYS_TRAP(trapNum)\r
+#endif\r
+\r
+/********************************************************************\r
+ * define SCREEN SIZE\r
+ ********************************************************************/\r
\r
+#define hrWidth                        320\r
+#define hrHeight                       320\r
+#define stdWidth                       160\r
+#define stdHeight                      160\r
+\r
+/********************************************************************\r
+ * define hrErrorClass\r
+ ********************************************************************/\r
\r
+#define hrErrNone                       0\r
+#define hrErrorClass           (sonyHRErrorClass)\r
+#define hrErrParam             (hrErrorClass | 1)\r
+#define hrErrNotOpen           (hrErrorClass | 2)\r
+#define hrErrStillOpen (hrErrorClass | 3)\r
+#define hrErrNoGlobals (hrErrorClass | 4)\r
+#define hrErrMemory            (hrErrorClass | 5)\r
+#define hrErrNoFeature (hrErrorClass | 6)\r
+\r
+/********************************************************************\r
+ * define VERSION Info\r
+ ********************************************************************/\r
+#define HR_VERSION_SUPPORT_FNTSIZE     (0x200)\r
+\r
+/********************************************************************\r
+ * define High Resolution Font\r
+ ********************************************************************/\r
+\r
+enum hrFontID {\r
+       hrTinyFont = 0x00,\r
+       hrTinyBoldFont,\r
+       hrSmallFont,\r
+       hrSmallSymbolFont,\r
+       hrSmallSymbol11Font,\r
+       hrSmallSymbol7Font,\r
+       hrSmallLedFont,\r
+       hrSmallBoldFont,\r
+       hrStdFont,\r
+       hrBoldFont,\r
+       hrLargeFont,\r
+       hrSymbolFont,\r
+       hrSymbol11Font,\r
+       hrSymbol7Font,\r
+       hrLedFont,\r
+       hrLargeBoldFont,\r
+       hrFntAppFontCustomBase = 0x80\r
+};\r
+\r
+typedef enum hrFontID HRFontID;\r
+\r
+#if CPU_TYPE == CPU_68K\r
+/********************************************************************\r
+ * define HRTrapNumEnum\r
+ ********************************************************************/\r
+\r
+typedef enum tagHRTrapNumEnum\r
+{\r
+       HRTrapGetAPIVersion = sysLibTrapCustom,\r
+       HRTrapWinClipRectangle,\r
+       HRTrapWinCopyRectangle,\r
+       HRTrapWinCreateBitmapWindow,\r
+       HRTrapWinCreateOffscreenWindow,\r
+       HRTrapWinCreateWindow,\r
+       HRTrapWinDisplayToWindowPt,\r
+       HRTrapWinDrawBitmap,\r
+       HRTrapWinDrawChar,\r
+       HRTrapWinDrawChars,\r
+       HRTrapWinDrawGrayLine,\r
+       HRTrapWinDrawGrayRectangleFrame,\r
+       HRTrapWinDrawInvertedChars,\r
+       HRTrapWinDrawLine,\r
+       HRTrapWinDrawPixel,\r
+       HRTrapWinDrawRectangle,\r
+       HRTrapWinDrawRectangleFrame,\r
+       HRTrapWinDrawTruncChars,\r
+       HRTrapWinEraseChars,\r
+       HRTrapWinEraseLine,\r
+       HRTrapWinErasePixel,\r
+       HRTrapWinEraseRectangle,\r
+       HRTrapWinEraseRectangleFrame,\r
+       HRTrapWinFillLine,\r
+       HRTrapWinFillRectangle,\r
+       HRTrapWinGetClip,\r
+       HRTrapWinGetDisplayExtent,\r
+       HRTrapWinGetFramesRectangle,\r
+       HRTrapWinGetPixel,\r
+       HRTrapWinGetWindowBounds,\r
+       HRTrapWinGetWindowExtent,\r
+       HRTrapWinGetWindowFrameRect,\r
+       HRTrapWinInvertChars,\r
+       HRTrapWinInvertLine,\r
+       HRTrapWinInvertPixel,\r
+       HRTrapWinInvertRectangle,\r
+       HRTrapWinInvertRectangleFrame,\r
+       HRTrapWinPaintBitmap,\r
+       HRTrapWinPaintChar,\r
+       HRTrapWinPaintChars,\r
+       HRTrapWinPaintLine,\r
+       HRTrapWinPaintLines,\r
+       HRTrapWinPaintPixel,\r
+       HRTrapWinPaintPixels,\r
+       HRTrapWinPaintRectangle,\r
+       HRTrapWinPaintRectangleFrame,\r
+       HRTrapWinRestoreBits,\r
+       HRTrapWinSaveBits,\r
+       HRTrapWinScreenMode,\r
+       HRTrapWinScrollRectangle,\r
+       HRTrapWinSetClip,\r
+       HRTrapWinSetWindowBounds,\r
+       HRTrapWinWindowToDisplayPt,\r
+       HRTrapBmpBitsSize,\r
+       HRTrapBmpSize,\r
+       HRTrapBmpCreate,\r
+       HRTrapFntGetFont,\r
+       HRTrapFntSetFont,\r
+       HRTrapFontSelect,\r
+       HRTrapSystem,\r
+       HRTrapWinGetPixelRGB,\r
+       HRTrapGetInfo,\r
+       HRTrapFntBaseLine,\r
+       HRTrapFntCharHeight,\r
+       HRTrapFntLineHeight,\r
+       HRTrapFntAverageCharWidth,\r
+       HRTrapFntCharWidth,\r
+       HRTrapFntWCharWidth,\r
+       HRTrapFntCharsWidth,\r
+       HRTrapFntWidthToOffset,\r
+       HRTrapFntCharsInWidth,\r
+       HRTrapFntDescenderHeight,\r
+       HRTrapFntLineWidth,\r
+       HRTrapFntWordWrap,\r
+       HRTrapFntWordWrapReverseNLines,\r
+       HRTrapFntGetScrollValues\r
+\r
+} HRTrapNumEnum;\r
+#endif\r
+\r
+\r
+/********************************************************************\r
+ * API Prototypes\r
+ ********************************************************************/\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/********************************************************************\r
+ * Standard library open, close, sleep and wake functions\r
+ ********************************************************************/\r
+\r
+extern Err     HROpen(UInt16 refNum)           HR_TRAP(sysLibTrapOpen);\r
+\r
+extern Err     HRClose(UInt16 refNum)          HR_TRAP(sysLibTrapClose);\r
+\r
+extern Err     HRSleep(UInt16 refNum)          HR_TRAP(sysLibTrapSleep);\r
+\r
+extern Err     HRWake(UInt16 refNum)           HR_TRAP(sysLibTrapWake);\r
+\r
+\r
+/********************************************************************\r
+ * Custom library API functions\r
+ ********************************************************************/\r
+\r
+extern Err     HRGetAPIVersion(UInt16 refNum, UInt16 *versionP)\r
+       HR_TRAP(HRTrapGetAPIVersion);\r
+\r
+extern void HRWinClipRectangle(UInt16 refNum, RectangleType *rP)\r
+       HR_TRAP(HRTrapWinClipRectangle);\r
+\r
+extern void HRWinCopyRectangle(UInt16 refNum, WinHandle srcWin, WinHandle dstWin, RectangleType *srcRect, Coord destX, Coord destY, WinDrawOperation mode)\r
+       HR_TRAP(HRTrapWinCopyRectangle);\r
+\r
+extern WinHandle HRWinCreateBitmapWindow(UInt16 refNum, BitmapType *bitmapP, UInt16 *error)\r
+       HR_TRAP(HRTrapWinCreateBitmapWindow);\r
+\r
+extern WinHandle HRWinCreateOffscreenWindow(UInt16 refNum, Coord width, Coord height, WindowFormatType format, UInt16 *error)\r
+       HR_TRAP(HRTrapWinCreateOffscreenWindow);\r
+\r
+extern WinHandle HRWinCreateWindow(UInt16 refNum, RectangleType *bounds, FrameType frame, Boolean modal, Boolean focusable, UInt16 *error)\r
+       HR_TRAP(HRTrapWinCreateWindow);\r
+\r
+extern void HRWinDisplayToWindowPt(UInt16 refNum, Coord *extentX, Coord *extentY)\r
+       HR_TRAP(HRTrapWinDisplayToWindowPt);\r
+\r
+extern void HRWinDrawBitmap(UInt16 refNum, BitmapPtr bitmapP, Coord x, Coord Y)\r
+       HR_TRAP(HRTrapWinDrawBitmap);\r
+\r
+extern void HRWinDrawChar(UInt16 refNum, WChar theChar, Coord x, Coord Y)\r
+       HR_TRAP(HRTrapWinDrawChar);\r
+\r
+extern void HRWinDrawChars(UInt16 refNum, const Char *chars, Int16 len, Coord x, Coord y)\r
+       HR_TRAP(HRTrapWinDrawChars);\r
+\r
+extern void HRWinDrawGrayLine(UInt16 refNum, Coord x1, Coord y1, Coord x2, Coord y2)\r
+       HR_TRAP(HRTrapWinDrawGrayLine);\r
+\r
+extern void HRWinDrawGrayRectangleFrame(UInt16 refNum, FrameType frame, RectangleType *rP)\r
+       HR_TRAP(HRTrapWinDrawGrayRectangleFrame);\r
+\r
+extern void HRWinDrawInvertedChars(UInt16 refNum, const Char *chars, Int16 len, Coord x, Coord y)\r
+       HR_TRAP(HRTrapWinDrawInvertedChars);\r
+\r
+extern void HRWinDrawLine(UInt16 refNum, Coord x1, Coord y1, Coord x2, Coord y2)\r
+       HR_TRAP(HRTrapWinDrawLine);\r
+\r
+extern void HRWinDrawPixel(UInt16 refNum, Coord x, Coord y)\r
+       HR_TRAP(HRTrapWinDrawPixel);\r
+\r
+extern void HRWinDrawRectangle(UInt16 refNum, RectangleType *rP, UInt16 cornerDiam)\r
+       HR_TRAP(HRTrapWinDrawRectangle);\r
+\r
+extern void HRWinDrawRectangleFrame(UInt16 refNum, FrameType frame, RectangleType *rP)\r
+       HR_TRAP(HRTrapWinDrawRectangleFrame);\r
+\r
+extern void HRWinDrawTruncChars(UInt16 refNum, const Char *chars, Int16 len, Coord x, Coord y, Coord maxWidth)\r
+       HR_TRAP(HRTrapWinDrawTruncChars);\r
+\r
+extern void HRWinEraseChars(UInt16 refNum, const Char *chars, Int16 len, Coord x, Coord y)\r
+       HR_TRAP(HRTrapWinEraseChars);\r
+\r
+extern void HRWinEraseLine(UInt16 refNum, Coord x1, Coord y1, Coord x2, Coord y2)\r
+       HR_TRAP(HRTrapWinEraseLine);\r
+\r
+extern void HRWinErasePixel(UInt16 refNum, Coord x, Coord y)\r
+       HR_TRAP(HRTrapWinErasePixel);\r
+\r
+extern void HRWinEraseRectangle(UInt16 refNum, RectangleType *rP, UInt16 cornerDiam)\r
+       HR_TRAP(HRTrapWinEraseRectangle);\r
+\r
+extern void HRWinEraseRectangleFrame(UInt16 refNum, FrameType frame, RectangleType *rP)\r
+       HR_TRAP(HRTrapWinEraseRectangleFrame);\r
+\r
+extern void HRWinFillLine(UInt16 refNum, Coord x1, Coord y1, Coord x2, Coord y2)\r
+       HR_TRAP(HRTrapWinFillLine);\r
+\r
+extern void HRWinFillRectangle(UInt16 refNum, RectangleType *rP, UInt16 cornerDiam)\r
+       HR_TRAP(HRTrapWinFillRectangle);\r
+\r
+extern void HRWinGetClip(UInt16 refNum, RectangleType *rP)\r
+       HR_TRAP(HRTrapWinGetClip);\r
+\r
+extern void HRWinGetDisplayExtent(UInt16 refNum, Coord *extentX, Coord *extentY)\r
+       HR_TRAP(HRTrapWinGetDisplayExtent);\r
+\r
+extern void HRWinGetFramesRectangle(UInt16 refNum, FrameType frame, RectangleType *rP, RectangleType *obscuredRectP)\r
+       HR_TRAP(HRTrapWinGetFramesRectangle);\r
+\r
+extern IndexedColorType HRWinGetPixel(UInt16 refNum, Coord x, Coord y)\r
+       HR_TRAP(HRTrapWinGetPixel);\r
+\r
+extern void HRWinGetWindowBounds(UInt16 refNum, RectangleType *rP)\r
+       HR_TRAP(HRTrapWinGetWindowBounds);\r
+\r
+extern void HRWinGetWindowExtent(UInt16 refNum, Coord *extentX, Coord *extentY)\r
+       HR_TRAP(HRTrapWinGetWindowExtent);\r
+\r
+extern void HRWinGetWindowFrameRect(UInt16 refNum, WinHandle winHandle, RectangleType *rP)\r
+       HR_TRAP(HRTrapWinGetWindowFrameRect);\r
+\r
+extern void HRWinInvertChars(UInt16 refNum, const Char *chars, Int16 len, Coord x, Coord y)\r
+       HR_TRAP(HRTrapWinInvertChars);\r
+\r
+extern void HRWinInvertLine(UInt16 refNum, Coord x1, Coord y1, Coord x2, Coord y2)\r
+       HR_TRAP(HRTrapWinInvertLine);\r
+\r
+extern void HRWinInvertPixel(UInt16 refNum, Coord x, Coord y)\r
+       HR_TRAP(HRTrapWinInvertPixel);\r
+\r
+extern void HRWinInvertRectangle(UInt16 refNum, RectangleType *rP, UInt16 cornerDiam)\r
+       HR_TRAP(HRTrapWinInvertRectangle);\r
+\r
+extern void HRWinInvertRectangleFrame(UInt16 refNum, FrameType frame, RectangleType *rP)\r
+       HR_TRAP(HRTrapWinInvertRectangleFrame);\r
+\r
+extern void HRWinPaintBitmap(UInt16 refNum, BitmapType *bitmapP, Coord x, Coord y)\r
+       HR_TRAP(HRTrapWinPaintBitmap);\r
+\r
+extern void HRWinPaintChar(UInt16 refNum, WChar theChar, Coord x, Coord y)\r
+       HR_TRAP(HRTrapWinPaintChar);\r
+\r
+extern void HRWinPaintChars(UInt16 refNum, const Char *chars, Int16 len, Coord x, Coord y)\r
+       HR_TRAP(HRTrapWinPaintChars);\r
+\r
+extern void HRWinPaintLine(UInt16 refNum, Coord x1, Coord y1, Coord x2, Coord y2)\r
+       HR_TRAP(HRTrapWinPaintLine);\r
+\r
+extern void HRWinPaintLines(UInt16 refNum, UInt16 numLines, WinLineType lines[])\r
+       HR_TRAP(HRTrapWinPaintLines);\r
+\r
+extern void HRWinPaintPixel(UInt16 refNum, Coord x, Coord y)\r
+       HR_TRAP(HRTrapWinPaintPixel);\r
+\r
+extern void HRWinPaintPixels(UInt16 refNum, UInt16 numPoints, PointType pts[])\r
+       HR_TRAP(HRTrapWinPaintPixels);\r
+\r
+extern void HRWinPaintRectangle(UInt16 refNum, RectangleType *rP, UInt16 cornerDiam)\r
+       HR_TRAP(HRTrapWinPaintRectangle);\r
+\r
+extern void HRWinPaintRectangleFrame(UInt16 refNum, FrameType frame, RectangleType *rP)\r
+       HR_TRAP(HRTrapWinPaintRectangleFrame);\r
+\r
+extern void HRWinRestoreBits(UInt16 refNum, WinHandle winHandle, Coord destX, Coord destY)\r
+       HR_TRAP(HRTrapWinRestoreBits);\r
+\r
+extern WinHandle HRWinSaveBits(UInt16 refNum, RectangleType *sourceP, UInt16 *error)\r
+       HR_TRAP(HRTrapWinSaveBits);\r
+\r
+extern Err HRWinScreenMode(UInt16 refNum, WinScreenModeOperation operation, UInt32 *widthP, UInt32 *heightP, UInt32 *depthP, Boolean *enableColorP)\r
+       HR_TRAP(HRTrapWinScreenMode);\r
+\r
+extern void HRWinScrollRectangle(UInt16 refNum, RectangleType *rP, WinDirectionType direction, Coord distance, RectangleType *vacatedP)\r
+       HR_TRAP(HRTrapWinScrollRectangle);\r
+\r
+extern void HRWinSetClip(UInt16 refNum, RectangleType *rP)\r
+       HR_TRAP(HRTrapWinSetClip);\r
+\r
+extern void HRWinSetWindowBounds(UInt16 refNum, WinHandle winHandle, RectangleType *rP)\r
+       HR_TRAP(HRTrapWinSetWindowBounds);\r
+\r
+extern void HRWinWindowToDisplayPt(UInt16 refNum, Coord *extentX, Coord *extentY)\r
+       HR_TRAP(HRTrapWinWindowToDisplayPt);\r
+\r
+extern Err HRWinGetPixelRGB(UInt16 refNum, Coord x, Coord y, RGBColorType *rgbP)\r
+       HR_TRAP(HRTrapWinGetPixelRGB);\r
+\r
+\r
+\r
+extern UInt32 HRBmpBitsSize(UInt16 refNum, BitmapType *bitmapP)\r
+       HR_TRAP(HRTrapBmpBitsSize);\r
+\r
+extern UInt32 HRBmpSize(UInt16 refNum, BitmapType *bitmapP)\r
+       HR_TRAP(HRTrapBmpSize);\r
+\r
+extern BitmapType *HRBmpCreate(UInt16 refNum, Coord width, Coord height, UInt8 depth, ColorTableType *colortableP, UInt16 *error)\r
+       HR_TRAP( HRTrapBmpCreate);\r
+\r
+\r
+\r
+extern HRFontID HRFntGetFont(UInt16 refNum)\r
+       HR_TRAP(HRTrapFntGetFont);\r
+\r
+extern HRFontID HRFntSetFont(UInt16 refNum, HRFontID font)\r
+       HR_TRAP(HRTrapFntSetFont);\r
+\r
+extern HRFontID HRFontSelect(UInt16 refNum, HRFontID font)\r
+       HR_TRAP(HRTrapFontSelect);\r
+\r
+extern Int16 HRFntBaseLine (UInt16 refNum)\r
+       HR_TRAP(HRTrapFntBaseLine);\r
+\r
+extern Int16 HRFntCharHeight (UInt16 refNum)\r
+       HR_TRAP(HRTrapFntCharHeight);\r
+\r
+extern Int16 HRFntLineHeight (UInt16 refNum)\r
+       HR_TRAP(HRTrapFntLineHeight);\r
+\r
+extern Int16 HRFntAverageCharWidth (UInt16 refNum)\r
+       HR_TRAP(HRTrapFntAverageCharWidth);\r
+\r
+extern Int16 HRFntCharWidth (UInt16 refNum, Char ch)\r
+       HR_TRAP(HRTrapFntCharWidth);\r
+\r
+extern Int16 HRFntWCharWidth (UInt16 refNum, WChar iChar)\r
+       HR_TRAP(HRTrapFntWCharWidth);\r
+\r
+extern Int16 HRFntCharsWidth (UInt16 refNum, Char const *chars, Int16 len)\r
+       HR_TRAP(HRTrapFntCharsWidth);\r
+\r
+extern Int16 HRFntWidthToOffset (UInt16 refNum, Char const *pChars, UInt16 length,\r
+               Int16 pixelWidth, Boolean *leadingEdge, Int16 *truncWidth)\r
+       HR_TRAP(HRTrapFntWidthToOffset);\r
+\r
+extern void HRFntCharsInWidth (UInt16 refNum, Char const *string, \r
+               Int16 *stringWidthP, Int16 *stringLengthP, \r
+               Boolean *fitWithinWidth)\r
+       HR_TRAP(HRTrapFntCharsInWidth);\r
+\r
+extern Int16 HRFntDescenderHeight (UInt16 refNum)\r
+       HR_TRAP(HRTrapFntDescenderHeight);\r
+\r
+extern Int16 HRFntLineWidth (UInt16 refNum, Char const *pChars, UInt16 length)\r
+       HR_TRAP(HRTrapFntLineWidth);\r
+\r
+extern UInt16 HRFntWordWrap (UInt16 refNum, Char const *chars, UInt16 maxWidth)\r
+       HR_TRAP(HRTrapFntWordWrap);\r
+\r
+extern void HRFntWordWrapReverseNLines (UInt16 refNum, Char const *const chars, \r
+               UInt16 maxWidth, UInt16 *linesToScrollP, UInt16 *scrollPosP)\r
+       HR_TRAP(HRTrapFntWordWrapReverseNLines);\r
+\r
+extern void HRFntGetScrollValues (UInt16 refNum, Char const *chars, UInt16 width, \r
+               UInt16 scrollPos, UInt16 *linesP, UInt16 *topLine)\r
+       HR_TRAP(HRTrapFntGetScrollValues);\r
+\r
+\r
+/* System Use Only */\r
+extern Err HRSystem(UInt16 refNum, UInt16 operation, UInt32 *param1, UInt32 *param2, UInt32 *param3)\r
+       HR_TRAP(HRTrapSystem);\r
+\r
+extern Err HRGetInfo(UInt16 refNum, UInt16 *ptr1, UInt16 *ptr2)\r
+       HR_TRAP(HRTrapGetInfo);\r
+       \r
+/** Number of API : 80 **/\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* __SONYHIGHRESLINB_H__ */\r
diff --git a/util/oem/SonyJogAssist.h b/util/oem/SonyJogAssist.h
new file mode 100644 (file)
index 0000000..00b05ef
--- /dev/null
@@ -0,0 +1,64 @@
+/******************************************************************************\r
+ *                                                                            *\r
+ *            (C) Copyright 2000-2002, Sony Corporation                       *\r
+ *                                                                            *\r
+ *----------------------------------------------------------------------------*\r
+ *                                                                            *\r
+ *    <IDENTIFICATION>                                                        *\r
+ *       file name    : $Workfile: SonyJogAssist.h $\r
+ *                                                                            *\r
+ *    <PROFILE>                                                               *\r
+ *       Jog Event Mask definitions                                           *\r
+ *                                                                            *\r
+ *    <HISTORY>                                                               *\r
+ *       Started on   : 00/10/24                                              *\r
+ *       Last Modified: $Date: 2004/03/16 05:05:25 $\r
+ *                                                                            *\r
+ ******************************************************************************/\r
+/* this file is best viewed by setting TAB-stop as 3 */\r
+\r
+#ifndef __SONYJOGASSIST_H__\r
+#define __SONYJOGASSIST_H__\r
+\r
+/******************************************************************************\r
+ *    Includes                                                                *\r
+ ******************************************************************************/\r
+\r
+\r
+/******************************************************************************\r
+ *    Mask for vchrJogEvent                                                   *\r
+ ******************************************************************************/\r
+\r
+/*** Type ***/\r
+#define sonyJogAstMaskType1                    (0x0001)\r
+#define sonyJogAstMaskType2                    (0x0002)\r
+\r
+/*** Mask bitfields ***/\r
+#define sonyJogAstMaskUp                               (0x0001)\r
+#define sonyJogAstMaskDown                             (0x0002)\r
+#define sonyJogAstMaskPushedUp         (0x0004)\r
+#define sonyJogAstMaskPushedDown               (0x0008)\r
+#define sonyJogAstMaskPush                             (0x0010)\r
+#define sonyJogAstMaskRelease                  (0x0020)\r
+#define sonyJogAstMaskPushRepeat               (0x0040)\r
+#define sonyJogAstMaskBack                             (0x0080)\r
+#define sonyJogAstMaskLeft                             (0x0100)\r
+#define sonyJogAstMaskRight                    (0x0200)\r
+\r
+#define sonyJogAstMaskReserved         (0xFC00)\r
+#define sonyJogAstMaskAll                              ~sonyJogAstMaskReserved\r
+#define sonyJogAstMaskNone                             (0x0000)\r
+\r
+       /* Application is discouraged to use Back unless it uses Back in accordance\r
+            with the guidline specified by Sony SDK */\r
+       /* Application should not use Back-Hold (push Back and hold it down long \r
+            enough), since it exclusively is reserved for special usage by system */\r
+\r
+/******************************************************************************\r
+ *    Control flags                                                           *\r
+ ******************************************************************************/\r
+       /* those flags are for Feature: sonySysFtrNumJogAstControlP */\r
+#define sonyJogAstControlEnable                (0x00000001L)   /* Enable JogAssist */\r
+\r
+#endif // __SONYJOGASSIST_H__\r
+\r
diff --git a/util/oem/SonySilkLib.h b/util/oem/SonySilkLib.h
new file mode 100644 (file)
index 0000000..6e69c69
--- /dev/null
@@ -0,0 +1,233 @@
+/******************************************************************************
+ *                                                                            *
+ *                 (C) Copyright 2002, Sony Corporation                       *
+ *                                                                            *
+ *----------------------------------------------------------------------------*
+ *                                                                            *
+ *    <IDENTIFICATION>                                                        *
+ *       file name    : $Workfile: SonySilkLib.h $
+ *                                                                            *
+ *    <PROFILE>                                                               *
+ *       Virtual Silk Lib API                                                 *
+ *                                                                            *
+ *    <HISTORY>                                                               *
+ *       Started on   : 00/11/01                                                       *
+ *       Last Modified: $Date: 03/07/23 10:41 $ 
+ *                                                                            *
+ ******************************************************************************/
+/* this file is best viewed by setting TAB-stop as 3 */
+
+
+#ifndef __SILK_LIB_H__
+#define __SILK_LIB_H__
+
+#include <SonyErrorBase.h>
+
+
+#if CPU_TYPE != CPU_68K
+       #define SILK_LIB_TRAP(trapNum)  // direct link to library code
+#else
+       #define SILK_LIB_TRAP(trapNum)  SYS_TRAP(trapNum)
+#endif
+
+
+/* ------------------------------------- */
+/*                             Constant def                                      */
+/* ------------------------------------- */
+/*             SilkMgr Errors          */
+#define silkLibErrParam                                        (sonySilkErrorClass | 1)        // invalid parameter
+#define silkLibErrNotOpen                              (sonySilkErrorClass | 2)        // library is not open
+#define silkLibErrStillOpen                    (sonySilkErrorClass | 3)        // returned from SilkLibClose() if
+                                                                                                                                                                       // the library is still opened by others
+#define silkLibErrNotAvailable         (sonySilkErrorClass | 4)        // memory error occurred
+#define silkLibErrResizeDisabled               (sonySilkErrorClass | 5)        // cannot resize
+
+#define vskErrParam                                            silkLibErrParam
+#define vskErrNotOpen                                  silkLibErrNotOpen
+#define vskErrStillOpen                                        silkLibErrStillOpen
+#define vskErrNotAvailable                             silkLibErrNotAvailable
+#define vskErrResizeDisabled                   silkLibErrResizeDisabled
+#define vskErrSlkwNotFound                             (sonySilkErrorClass | 6)
+#define vskErrSlkwOpenFailed                   (sonySilkErrorClass | 7)
+#define vskErrSlkwCloseFailed                  (sonySilkErrorClass | 8)
+#define vskErrSlkwStartFailed                  (sonySilkErrorClass | 9)
+#define vskErrSlkwStopFailed                   (sonySilkErrorClass | 10)
+#define vskErrSlkwLoadFailed                   (sonySilkErrorClass | 11)
+#define vskErrFuncNotAvailable         (sonySilkErrorClass | 12)
+//#define vskErr                                                       (sonySilkErrorClass | )
+// up to                                                                               (sonySilkErrorClass | 15)
+
+
+
+#define silkLibAPIVertion                              (0x00000003)
+#define vskAPIVertion                                  silkLibAPIVertion
+#define vskVersionNum1                                 (0x00010000)
+#define vskVersionNum2                                 (0x00020000)
+#define vskVersionNum3                                 (0x00030000)
+
+/*             stateType                       */
+#define vskStateResize                                 (0)
+       #define silkResizeNormal                        (0)
+       #define silkResizeToStatus                      (1)
+       #define silkResizeMax                           (2)
+       #define vskResizeMax                                    silkResizeNormal
+       #define vskResizeMin                                    silkResizeToStatus
+       #define vskResizeNone                           silkResizeMax
+
+#define vskStateEnable                                 (1)
+#define vskStateResizeDirection                        (5)
+/*The state definition of vskStateEnable and vskStateResizeDirection*/
+       #define vskResizeDisable                (0)
+       #define vskResizeVertically             (1<<0)
+       #define vskResizeHorizontally           (1<<1)
+
+#define vskStateSilkPlugInAvailable            (6)
+       #define vskSilkPlugInNotAvailable       (0)
+       #define vskSilkPlugInAvailable          (1)
+
+
+
+/*             slkwType                                */
+#define vskSlkwTypeSilk                                        (0)
+#define vskSlkwTypeStatus                              (1)
+
+#if CPU_TYPE == CPU_68K
+/* ------------------------------------- */
+/*                             Type def                                                          */
+/* ------------------------------------- */
+#define silkLibTrapResizeDispWin (sysLibTrapCustom)
+#define silkLibTrapEnableResize (sysLibTrapCustom+1)
+#define silkLibTrapDisableResize (sysLibTrapCustom+2)
+#define silkLibTrapGetAPIVersion (sysLibTrapCustom+3)
+#define silkLibLastTrap (sysLibTrapCustom+4)
+
+#define VskTrapGetAPIVersion (silkLibTrapGetAPIVersion)
+#define VskTrapSetCurrentSlkw (silkLibTrapGetAPIVersion+1)
+#define VskTrapGetCurrentSlkw (silkLibTrapGetAPIVersion+2)
+#define VskTrapSetState (silkLibTrapGetAPIVersion+3)
+#define VskTrapGetState (silkLibTrapGetAPIVersion+4)
+#define VskTrapEnablePalmSilk (silkLibTrapGetAPIVersion+5)
+#define VskTrapGetPalmSilkEnabled (silkLibTrapGetAPIVersion+6)
+#define VskTrapTimerWrite (silkLibTrapGetAPIVersion+7)
+#define VskTrapDoCommand (silkLibTrapGetAPIVersion+8)
+#define VskTrapSetDrawWindow (silkLibTrapGetAPIVersion+9)
+#define VskTrapRestoreDrawWindow (silkLibTrapGetAPIVersion+10)
+#define VskLastTrap (silkLibTrapGetAPIVersion+11)
+
+#endif
+
+/* ------------------------------------- */
+/*                             API Prototypes                                    */
+/* ------------------------------------- */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if CPU_TYPE != CPU_68K
+// new APIs
+extern Err VskOpen(void);
+extern Err VskClose(void);
+extern Err VskSleep(void);
+extern Err VskWake(void);
+extern UInt32 VskGetAPIVersion(void);
+extern Err VskSetCurrentSlkw(UInt16 slkwType, UInt32 creator);
+extern Err VskGetCurrentSlkw(UInt16 slkwType, UInt32 *creatorP);
+extern Err VskSetState(UInt16 stateType, UInt16 state);
+extern Err VskGetState(UInt16 stateType, UInt16 *stateP);
+extern Err VskEnablePalmSilk(Boolean enable);
+extern Err VskGetPalmSilkEnabled(Boolean *graffiti, Boolean *penButton);
+extern Err VskTimerWrite(UInt16 slkwType, UInt32 interval/*msec*/);
+extern Err VskDoCommand(UInt32 creator, UInt16 command,
+                                                               UInt32 data1, UInt32 data2);
+extern Err VskSetDrawWindow(UInt16 slkwType);
+extern Err VskRestoreDrawWindow(UInt16 slkwType);
+
+#else
+
+extern Err SilkLibOpen(UInt16 refNum)
+                               SILK_LIB_TRAP(sysLibTrapOpen);
+                               
+extern Err SilkLibClose(UInt16 refNum)
+                               SILK_LIB_TRAP(sysLibTrapClose);
+
+extern Err SilkLibSleep(UInt16 refNum)
+                               SILK_LIB_TRAP(sysLibTrapSleep);
+
+extern Err SilkLibWake(UInt16 refNum)
+                               SILK_LIB_TRAP(sysLibTrapWake);
+
+extern Err SilkLibResizeDispWin(UInt16 refNum, UInt8 win)
+                               SILK_LIB_TRAP(silkLibTrapResizeDispWin);
+
+extern Err SilkLibEnableResize(UInt16 refNum)
+                               SILK_LIB_TRAP(silkLibTrapEnableResize);
+
+extern Err SilkLibDisableResize(UInt16 refNum)
+                               SILK_LIB_TRAP(silkLibTrapDisableResize);
+
+extern UInt32 SilkLibGetAPIVersion(UInt16 refNum)
+                               SILK_LIB_TRAP(silkLibTrapGetAPIVersion);
+
+// new APIs
+extern Err VskOpen(UInt16 refNum)
+                               SILK_LIB_TRAP(sysLibTrapOpen);
+
+extern Err VskClose(UInt16 refNum)
+                               SILK_LIB_TRAP(sysLibTrapClose);
+
+extern Err VskSleep(UInt16 refNum)
+                               SILK_LIB_TRAP(sysLibTrapSleep);
+
+extern Err VskWake(UInt16 refNum)
+                               SILK_LIB_TRAP(sysLibTrapWake);
+
+// this will be removed
+//extern Err VskResize(UInt16 refNum, UInt8 reqSize);
+
+// this will be removed
+//extern Err VskEnableResize(UInt16 refNum);
+
+// this will be removed
+//extern Err VskDisableResize(UInt16 refNum);
+
+extern UInt32 VskGetAPIVersion(UInt16 refNum)
+                               SILK_LIB_TRAP(VskTrapGetAPIVersion);
+
+extern Err VskSetCurrentSlkw(UInt16 refNum, UInt16 slkwType, UInt32 creator)
+                               SILK_LIB_TRAP(VskTrapSetCurrentSlkw);
+
+extern Err VskGetCurrentSlkw(UInt16 refNum, UInt16 slkwType, UInt32 *creatorP)
+                               SILK_LIB_TRAP(VskTrapGetCurrentSlkw);
+
+extern Err VskSetState(UInt16 refNum, UInt16 stateType, UInt16 state)
+                               SILK_LIB_TRAP(VskTrapSetState);
+
+extern Err VskGetState(UInt16 refNum, UInt16 stateType, UInt16 *stateP)
+                               SILK_LIB_TRAP(VskTrapGetState);
+
+extern Err VskEnablePalmSilk(UInt16 refNum, Boolean enable)
+                               SILK_LIB_TRAP(VskTrapEnablePalmSilk);
+
+extern Err VskGetPalmSilkEnabled(UInt16 refNum, Boolean *graffiti, Boolean *penButton)
+                               SILK_LIB_TRAP(VskTrapGetPalmSilkEnabled);
+
+extern Err VskTimerWrite(UInt16 refNum, UInt16 slkwType, UInt32 interval/*msec*/)
+                               SILK_LIB_TRAP(VskTrapTimerWrite);
+
+extern Err VskDoCommand(UInt16 refNum, UInt32 creator, UInt16 command,
+                                                               UInt32 data1, UInt32 data2)
+                               SILK_LIB_TRAP(VskTrapDoCommand);
+
+extern Err VskSetDrawWindow(UInt16 refNum, UInt16 slkwType)
+                               SILK_LIB_TRAP(VskTrapSetDrawWindow);
+
+extern Err VskRestoreDrawWindow(UInt16 refNum, UInt16 slkwType)
+                               SILK_LIB_TRAP(VskTrapRestoreDrawWindow);
+#endif //CPU_TYPE != CPU_68K
+
+#ifdef __cplusplus 
+}
+#endif
+
+
+#endif // __SLK_LIB_H__
diff --git a/util/oem/SonySystemFtr.h b/util/oem/SonySystemFtr.h
new file mode 100644 (file)
index 0000000..66555df
--- /dev/null
@@ -0,0 +1,230 @@
+/******************************************************************************
+ *                                                                            *
+ *            (C) Copyright 2000-2002, Sony Corporation                       *
+ *                                                                            *
+ *----------------------------------------------------------------------------*
+ *                                                                            *
+ *    <IDENTIFICATION>                                                        *
+ *       file name    : $Workfile: SonySystemFtr.h $
+ *                                                                            *
+ *    <PROFILE>                                                               *
+ *       Feature related definitions for Sony System                          *
+ *                                                                            *
+ *    <HISTORY>                                                               *
+ *       Started on   : 00/11/28                                              *
+ *       Last Modified: $Date: 03/07/02 10:46 $
+ *                                                                            *
+ ******************************************************************************/
+/* this file is best viewed by setting TAB-stop as 3 */
+/* this file could be used in both ARM-native and 68K applications */
+
+#ifndef __SONYSYSTEMFTR_H__
+#define __SONYSYSTEMFTR_H__
+
+/******************************************************************************
+ *    Includes                                                                *
+ ******************************************************************************/
+#include <SystemMgr.h>
+#include <SonyTypes.h>
+#include <SonySystemResources.h>
+
+
+/******************************************************************************
+ *    Utility Definitions                                                     *
+ ******************************************************************************/
+// Those for the bug of PreProcessor which causes undefined process when
+//   those constant be undefined.
+// Those definitions are the same as ones in BuildDefines.h in PalmOS_Support
+#ifndef CPU_ARM
+#define CPU_ARM        (3)
+#endif
+#if CPU_TYPE == CPU_68K
+#ifndef CPU_ENDIAN_LITTLE
+#define CPU_ENDIAN_LITTLE      (1)
+#endif
+#ifndef CPU_ENDIAN_BIG
+#define CPU_ENDIAN_BIG         (0)
+#endif
+#ifndef CPU_ENDIAN
+#define CPU_ENDIAN CPU_ENDIAN_BIG
+#endif
+#endif
+
+#if CPU_TYPE == CPU_ARM || CPU_ENDIAN == CPU_ENDIAN_LITTLE
+       // Do we have to care about x86?
+#define _EndianSwap16(x) \
+       ((((x) >> 8) & 0xFF) | \
+        (((x) & 0xFF) << 8))
+
+#define _EndianSwap32(x) \
+       ((((x) >> 24) & 0x000000FFL) | \
+        (((x) >>  8) & 0x0000FF00L) | \
+        (((x) & 0x0000FF00L) <<  8) | \
+        (((x) & 0x000000FFL) << 24))
+#else
+// CPU_68K || CPU_ENDIAN_BIG
+#define _EndianSwap16(x)       (x) /* nop */
+#define _EndianSwap32(x)       (x) /* nop */
+#endif
+
+
+/******************************************************************************
+ *    Features                                                                *
+ ******************************************************************************/
+
+/*** Sony Ftr Creator ***/
+#define sonySysFtrCreator                              sonySysFileCSony
+
+/*** Ftr Number ***/   /* UInt16 */
+       /* for Global System information */
+#define sonySysFtrNumSysInfoP                  (1)             /* ptr to SysInfo */
+#define sonySysFtrNumStringInfoP               (2)             /* ptr to StringInfo */
+
+       /* for JogAssist */
+#define sonySysFtrNumJogAstMaskP               (3)             /* ptr to JogAstMask */
+#define sonySysFtrNumJogAstMOCardNoP (4)               /* ptr to JogAstMaskOwnerCardNo */
+#define sonySysFtrNumJogAstMODbIDP     (5)             /* ptr to JogAstMaskOwnerDbID */
+               /* for PalmOS5 or later */
+#define sonySysFtrNumJogAstControlP    (6)             /* ptr to JogAssistControl flag */
+               /* for BatteryInfo APIs */
+#define sonySysFtrNumSysGetBatteryInfoP        (7)             /* ptr to GetBatteryInfo */
+#define sonySysFtrNumSysBatteryInfoExtP        (8)             /* ptr to BatteryInfoExt */
+
+       /* for Global System Capability */
+#define sonySysFtrNumSysCapability     (9)             /* UInt32 bit field */
+       #define sonySysFtrSysCpbGrfDialog               (0x00000001L)   /* Graffiti Dialog */
+/* #define sonySysFtrSysCap                                    (0x00000002L)
+       #define sonySysFtrSysCap                                        (0x00000004L)
+       #define sonySysFtrSysCap                                        (0x00000008L)
+       #define sonySysFtrSysCap                                        (0x00000010L)
+       ... */
+
+       /* for Version */
+#define sonySysFtrNumSystemVersion     (0x0100)        /* SonySys */
+#define sonySysFtrNumJogAstVersion     (0x0101)        /* JogAssistExtn */
+#define sonySysFtrNumVskVersion                (0x0102)        /* VirtualSilkLibExtn */
+#define sonySysFtrNumRmcVersion                (0x0103)        /* RemoteContollerLibExtn */
+#define sonySysFtrNumIrcVersion                (0x0104)        /* IrCommanderLibExtn */
+#define sonySysFtrNumSndVersion                (0x0105)        /* SndLibExtn */
+
+       /* should we define ver for lib as well? */
+#define sonySysFtrNumHRLibVersion              (0x0110)        /* HiResoLib */
+#define sonySysFtrNumScsiLibVersion            (0x0111)        /* SCSILib */
+#define sonySysFtrNumJpegUtilLibVersion        (0x0112)        /* JpegUitlLib */
+#define sonySysFtrNumJpegLibVersion            (0x0113)        /* JpegLib */
+#define sonySysFtrNumMMLibVersion              (0x0114)        /* MMLib */
+#define sonySysFtrNumMMUtilLibVersion  (0x0115)        /* MMUtilLib */
+#define sonySysFtrNumMMUrlLibVersion   (0x0116)        /* MMUrlLib */
+
+#define sonySysFtrNumAppUsableMemory   (0x0010)        /* Max usable memory (dynamic heap) size for Apps */
+
+/******************************************************************************
+ *    Structures for Featrures                                                *
+ ******************************************************************************/
+/* Those definitions are depricated on PalmOS_5, exist only for compatibilities */
+
+/*** SysInfoP ***/
+typedef struct S_SonySysFtrSysInfo {
+       UInt16 revision;
+       UInt16 rsv16_00;
+       UInt32 extn;                    /* loaded extension */
+       UInt32 libr;                    /* loaded libr */
+       UInt32 rsv32_00;
+       UInt32 rsv32_01;
+
+       void *rsvP;
+       UInt32 status;                  /* current system status */
+       UInt32 msStatus;                /* current MemoryStick status */
+       UInt32 cfStatus;                /* current CompactFlash status */
+
+       UInt16 msSlotNum;               /* number of slot of MemoryStick */
+       UInt16 jogType;
+       UInt16 rmcType;
+} SonySysFtrSysInfoType;
+typedef SonySysFtrSysInfoType *SonySysFtrSysInfoP;
+
+       /* revision field */
+#define sonySysFtrSysInfoRevision              (1)
+
+       /* extn field */
+#define sonySysFtrSysInfoExtnJog               (0x00000001L)   /* vchrJogEvent usable */
+#define sonySysFtrSysInfoExtnRmc               (0x00000002L)   /* vchrRmcEvent usable */
+#define sonySysFtrSysInfoExtnHold      (0x00000004L)   /* Hold switch usable */
+#define sonySysFtrSysInfoExtnJogAst    (0x00000008L)   /* JogAssist usable */
+#define sonySysFtrSysInfoExtnSilk      (0x00000010L)   /* Software silk usable */
+#define sonySysFtrSysInfoExtnCapBtn    (0x00000020L)   /* vchrCapEvent usable */
+#define sonySysFtrSysInfoExtnKB                (0x00000040L)   /* Hardware Keyboard usable */
+
+       /* libr field */
+#define sonySysFtrSysInfoLibrHR                (0x00000001L)   /* HR-Lib usable */
+#define sonySysFtrSysInfoLibrMsa               (0x00000002L)   /* Msa-Lib usable */
+#define sonySysFtrSysInfoLibrRmc               (0x00000004L)   /* Rmc-Lib usable */
+#define sonySysFtrSysInfoLibrMsScsi (0x00000008L)      /* MsScsi-Lib usable */
+#define sonySysFtrSysInfoLibrIrc               (0x00000010L)   /* Irc-Lib usable */
+#define sonySysFtrSysInfoLibrFm                (0x00000020L)   /* Sound-Lib usable */
+#define sonySysFtrSysInfoLibrCap               (0x00000040L)   /* Capture-Lib usable */
+#define sonySysFtrSysInfoLibrJpeg      (0x00000080L)   /* Jpeg-Lib usable */
+#define sonySysFtrSysInfoLibrSilk      (0x00000100L)   /* Silk-Lib usable */
+
+       /* status field */      /* 1: on(inserted/enabled), 0: off(removed/disabled) */
+#define sonySysFtrSysInfoStatusHP                      (0x00000001)    /* HeadPhone */
+#define sonySysFtrSysInfoStatusHoldOn          (0x00000002)    /* Hold switch */
+#define sonySysFtrSysInfoStatusLcdRotate       (0x00000004)    /* Lcd Rotate status */
+#define sonySysFtrSysInfoStatusLcdFlip         (0x00000008)    /* Lcd Flip status*/
+#define sonySysFtrSysInfoStatusCamRotate       (0x00000010)    /* Cam Rotate status */
+#define sonySysFtrSysInfoStatusCamOpen         (0x00000020)    /* Cam Open status */
+
+       /* msStatus field */    /* 1: inserted, 0: removed */
+#define sonySysFtrSysInfoMsStatus1MS   (0x00000001)    /* MS in Slot 1*/
+#define sonySysFtrSysInfoMsStatus1StrgMS       (0x00000002) /* StorageMS in Slot 1*/
+#define sonySysFtrSysInfoMsStatus1MGMS (0x00000004)    /* MG-MS in Slot 1*/
+#define sonySysFtrSysInfoMsStatus1WP   (0x00000008)    /* WriteProtected */
+#define sonySysFtrSysInfoMsStatus1ReadOnly     (0x00000010)    /* Read Only */
+#define sonySysFtrSysInfoMsStatus1IO   (0x00000020)    /* IO Expansion Module */
+#define sonySysFtrSysInfoMsStatus1Mask (0x000000FF)    /* Mask for Slot 1 */
+
+       /* cfStatus field */    /* 1:inserted, 0: removed */
+#define sonySysFtrSysInfoCfStatus1CF           (0x00000001)    /* CF in Slot 1 */
+#define sonySysFtrSysInfoCfStatus1StrgCF       (0x00000002)    /* Storage CF in Slot 1 */
+#define sonySysFtrSysInfoCfStatus1IO           (0x00000020)    /* IO CF(CF+) in Slot 1 */
+#define sonySysFtrSysInfoCfStatus1Mask         (0x000000FF)    /* Mask for Slot 1 */
+
+       /* jogType field */
+#define sonySysFtrSysInfoJogTypeNone   (0)     /* No Jog available */
+#define sonySysFtrSysInfoJogType1              (1)     /* 2D Jog (PEG-S300/500) */
+#define sonySysFtrSysInfoJogType2              (2)     /* 2D Jog with Back */
+#define sonySysFtrSysInfoJogType3              (3)     /* 2D Jog with LR Button (w/o Back) */
+
+       /* rmcType field */
+#define sonySysFtrSysInfoRmcTypeNone   (0)     /* No Rmc available */
+#define sonySysFtrSysInfoRmcType1              (1)     /* 6 buttons w/o display */
+#define sonySysFtrSysInfoRmcType2              (2)     /* Audio Adapter */
+
+
+/*** StringInfoP ***/
+typedef struct S_SonySysFtrStringInfo {
+       /* All chars are described with ASCII */        /* must be null-terminated */
+                                                               /* offset: ex. */
+       Char maker[16];         /*   0/0x0000: ex. "Sony Corp." */
+       Char model[16];         /*  16/0x0010: ex. "PEG-S300" */
+       Char ship[16];                  /*  32/0x0020: ex. "Japan" */
+       Char os[32];                    /*  48/0x0030: ex. "Palm OS 3.5" */
+       Char cpu[32];                   /*  80/0x0050: ex. "Motorola DragonBall-VZ(33MHz)" */
+       Char comment[128];      /* 112/0x0070: ex. "Personal Entertainment..." */
+       UInt16 code;                    /* 240/0x00F0: code for comment2 */
+       Char comment2[254];     /* 242/0x00F2: ex. "Organizer..." */
+                                                               /* 496/0x01F0: */
+} SonySysFtrStringInfoType;
+typedef SonySysFtrStringInfoType *SonySysFtrStringInfoP;
+       /* CAUTION: those strings is not guaranteed to be correct by Sony. Null
+            strings are possible. */
+       /* code for 'code' field' */
+#define sonySysFtrStingInfoCodeASCII   (0x0001)
+#define sonySysFtrStingInfoCode8859            (0x0003)
+#define sonySysFtrStingInfoCodeMSJIS   (0x0081)
+
+
+/*** JogAstMaskP ***/
+typedef void *JogAstMaskP;
+       /* related specs are defined in JogAst.h */
+#endif // __SONYSYSTEMFTR_H__ 
diff --git a/util/oem/SonySystemResources.h b/util/oem/SonySystemResources.h
new file mode 100644 (file)
index 0000000..d73a701
--- /dev/null
@@ -0,0 +1,222 @@
+/******************************************************************************
+ *                                                                            *
+ *            (C) Copyright 2000-2002, Sony Corporation                       *
+ *                                                                            *
+ *----------------------------------------------------------------------------*
+ *                                                                            *
+ *    <IDENTIFICATION>                                                        *
+ *       file name    : $Workfile: SonySystemResources.h $
+ *                                                                            *
+ *    <PROFILE>                                                               *
+ *       CreatorID/Type of DB, ID/Type of Resoueces for Sony System           *
+ *                                                                            *
+ *    <HISTORY>                                                               *
+ *       Started on   : 00/11/28                                              *
+ *       Last Modified: $Date: 03/07/23 10:42 $
+ *                                                                            *
+ ******************************************************************************/
+/* this file is best viewed by setting TAB-stop as 3 */
+
+#ifndef __SONYSYSTEMRESOURCES_H__
+#define __SONYSYSTEMRESOURCES_H__
+
+/******************************************************************************
+ *    Includes                                                                *
+ ******************************************************************************/
+#include <SystemResources.h>
+#include <UIResources.h>
+#include <SonyTypes.h>
+
+/******************************************************************************
+ *    Fixes                                                                   *
+ ******************************************************************************/
+#ifdef _BUILD_FOR_PALMOS_5_
+
+#ifndef sysFileTExtensionOEMARM
+#define sysFileTExtensionOEMARM        'aexo'
+#endif
+
+#ifndef sysFileTExtensionARM
+#define sysFileTExtensionARM           'aext'
+#endif
+
+#ifdef sysFileTExtension
+#undef sysFileTExtension
+#endif
+#define sysFileTExtension                      sysFileTExtensionARM
+
+#ifdef sysFileTExtensionOEM
+#undef sysFileTExtensionOEM
+#endif
+#define sysFileTExtensionOEM           sysFileTExtensionOEMARM
+
+#endif
+
+/******************************************************************************
+ *    CreatorID and Type for Databases                                        *
+ ******************************************************************************/
+
+/*** Sony oveall ***/
+#define sonySysFileCSony                       'SoNy'  /* Sony overall */
+#define        sonySysVfsCstmApiCreator        sonySysFileCSony        /* VFS Custom Control */
+
+#define sonySysFileCSystem                     'SsYs'  /* Sony overall System */
+
+/*** Application ***/
+
+
+/*** Extension ***/
+#define sonySysFileCSonySys                    'SeSy'
+#define sonySysFileTSonySys            sysFileTExtensionOEM            /* 'aexo' */
+#define sonySysLibNameSonySys          "Sony Sys Library"
+
+/*** Library ***/
+/* HR-Lib */
+#define sonySysFileCHRLib                      'SlHr'  /* High Resolution */
+#define sonySysFileTHRLib                      sysFileTLibrary         /* 'libr' */
+#define sonySysLibNameHR                       "Sony HR Library"
+
+/* Msa-Lib */
+#ifndef _BUILD_FOR_PALMOS_5_
+#define sonySysFileCMsaLib                     'SlMa'  /* MS Audio */
+#define sonySysFileTMsaLib                     sysFileTLibrary         /* 'libr' */
+#define sonySysLibNameMsa                      "Sony Msa Library"
+#endif
+
+/* Rmc-Lib */
+#ifndef _BUILD_FOR_PALMOS_5_
+#define sonySysFileCRmcLib                     'SlRm'  /* Remote Control */
+#define sonySysFileTRmcLib                     sysFileTLibrary         /* 'libr' */
+#define sonySysLibNameRmc                      "Sony Rmc Library"
+#else
+#define sonySysFileCRmcLib                     'SeRm'  /* Remote Control LibExtn */
+#define sonySysFileTRmcLib                     sysFileTExtension               /* 'aext' */
+#define sonySysLibNameRmc                      "Sony Rmc Library"
+#endif
+
+/* Scsi-Lib */ /* not officially supported (as of 2001/4) */
+#define sonySysFileCScsiLib            'SlSc'  /* SCSI */
+#define sonySysFileTScsiLib            sysFileTLibrary         /* 'libr' */
+#define sonySysLibNameScsi                     "Sony Scsi Library"
+
+/* Irc-Lib */
+#ifndef _BUILD_FOR_PALMOS_5_
+#define sonySysFileCIrcLib                     'SlIr'  /* Infrared Controller */
+#define sonySysFileTIrcLib                     sysFileTLibrary         /* 'libr' */
+#define sonySysLibNameIrc                      "Sony Irc Library"
+#else
+#define sonySysFileCIrcLib                     'SeIR'  /* Infrared Controller LibExtn */
+#define sonySysFileTIrcLib                     sysFileTExtension               /* 'aext' */
+#define sonySysLibNameIrc                      "Sony Irc Library"
+#endif
+
+/* SonySilkLib */
+#ifndef _BUILD_FOR_PALMOS_5_
+#define sonySysFileCSilkLib            'SlSi'
+#define sonySysFileTSilkLib            sysFileTLibrary         /* 'libr' */
+#else
+#define sonySysFileCSilkExtn           'SeSi'
+#define sonySysFileTSilkExtn           sysFileTExtension               /* 'aext' */
+#define sonySysResTSilkExtn            sysResTModuleCode               /* 'amdc' */
+#define sonySysFileCSilkLib            sonySysFileCSilkExtn
+#define sonySysFileTSilkLib            sonySysFileTSilkExtn    /* 'aext' */
+#endif
+#define sonySysLibNameSilk                     "Sony Silk Library"
+
+/* SonySoundLib */
+#define sonySysFileTPcmLib                     'pcmR'
+#ifndef _BUILD_FOR_PALMOS_5_
+#define sonySysFileCSoundLib           'SlSd'  /* Sony Sound Lib  */
+#define sonySysFileTSoundLib           sysFileTLibrary         /* 'libr' */
+#define sonySysLibNameSound            "Sony Sound Library"
+#else
+#define sonySysFileCSoundLib           'SeSd'  /* Sony Sound LibExtn  */
+#define sonySysFileTSoundLib           sysFileTExtension               /* 'aext' */
+#define sonySysLibNameSound            "Sony Sound Library"
+#endif
+
+/* JpegUtil-Lib */
+#define sonySysFileCJpegUtilLib        'SlJU'  /* Jpeg Util Lib */
+#define sonySysFileTJpegUtilLib        sysFileTLibrary /* 'libr' */
+#define sonySysLibNameJpegUtil "Sony Jpeg Util Library"
+
+/* Capture-Lib */
+#ifndef _BUILD_FOR_PALMOS_5_
+#define sonySysFileCCaptureLib 'SlCp'  /* Capture Lib */
+#define sonySysFileTCaptureLib sysFileTLibrary /* 'libr' */
+#define sonySysLibNameCapture          "Sony Capture Library"
+#endif
+
+/* MM-Lib */
+#ifndef _FOR_SDK_
+#define sonySysFileCMMLib                      'SlMM'  /* MMLib */
+#define sonySysFileTMMLib                      sysFileTLibrary         /* 'libr' */
+#define sonySysLibNameMM                       "Sony MM Library"
+#endif
+
+/* MMUrl-Lib */
+#ifndef _FOR_SDK_
+#define sonySysFileCMMUrlLib           'SlMU'  /* MMUrlLib */
+#define sonySysFileTMMUrlLib           sysFileTLibrary         /* 'libr' */
+#define sonySysLibNameMMUrl            "Sony MMUrl Library"
+#endif
+
+/* MMInfo-Lib */
+#ifndef _FOR_SDK_
+#define sonySysFileCMMInfoLib          'SlMI'  /* MMInfoLIb */
+#define sonySysFileTMMInfoLib          sysFileTLibrary         /* 'libr' */
+#define sonySysLibNameMMInfo           "Sony MMInfo Library"
+#endif
+
+/* Print-Lib */
+#define sonySysFileCPrintLib           'SlPr'  /* Print Lib */
+#define sonySysFileTPrintLib           sysFileTLibrary /* 'libr' */
+#define sonySysLibNamePrintLib         "Sony Print Library"
+
+/* VOut-Lib */
+#define sonySysFileCVOutLib            'SlVo'  /* VOut Lib */
+#define sonySysFileTVOutLib            sysFileTLibrary /* 'libr' */
+#define sonySysLibNameVOutLib          "Sony VOut library"
+
+/*** System Application ***/
+/* JogPanel Preference */
+#ifndef _BUILD_FOR_PALMOS_5_
+#define sonySysFileCJogPanel           'SnJp'  /* Jog Panel */
+#define sonySysFileTJogPanel           sysFileTPanel           /* 'panl' */
+#endif
+
+/******************************************************************************
+ *    PalmOS5 or later (ARM-device)                                           *
+ ******************************************************************************/
+       /* There's no change for 68K-Appl on those devices, but some changes made
+            for ARM-Appl development */
+
+/*** SilkWare plug-in ***/
+#define sonySysFileTSilkWare                   'Slkw'
+#define sonySysFileTSilkWareARM                'aSkw'
+#define sonySysFileTStatusWare         'Staw'
+#define sonySysFileTStatusWareARM      'aStw'
+
+/*** SilkWare ***/
+/* ActiveInput */
+#define sonySysFileCActiveInput                'SkAi'  /* Default Silkware */
+#define sonySysFileTActiveInput                sonySysFileTSilkWareARM /* 'aSkw' */
+#define sonySysFileTActInSoftGSkin     'SknG'
+
+/*** Slot Storage Libraly ***/
+#define sonySysFileTStorageLib         'StrG'
+
+/* BackupPanel Preference */
+#define sonySysFileCBackupPanel                'HIBP'
+#define sonySysFileTBackupPanel                sysFileTPanel           /* 'panel' */
+
+/******************************************************************************
+ *    Misc CreatorID                                                          *
+ ******************************************************************************/
+
+/*** for Half Font Size for temporary ***/
+#define fontFtrCreator                                         'font'
+#define fontFtrHalfScaleFontIDBase     0
+
+#endif // __SONYSYSTEMRESOURCES_H__
+
diff --git a/util/oem/SonyTypes.h b/util/oem/SonyTypes.h
new file mode 100644 (file)
index 0000000..51b2b49
--- /dev/null
@@ -0,0 +1,32 @@
+/******************************************************************************
+ *                                                                            *
+ *            (C) Copyright 2000-2002, Sony Corporation                       *
+ *                                                                            *
+ *----------------------------------------------------------------------------*
+ *                                                                            *
+ *    <IDENTIFICATION>                                                        *
+ *       file name    : $Workfile: SonyTypes.h $
+ *                                                                            *
+ *    <PROFILE>                                                               *
+ *       General defitinions for Sony System & Libraries                      *
+ *                                                                            *
+ *    <HISTORY>                                                               *
+ *       Started on   : 02/05/25                                              *
+ *       Last Modified: $Date: 03/05/10 16:09 $
+ *                                                                            *
+ ******************************************************************************/
+/* this file is best viewed by setting TAB-stop as 3 */
+
+#ifndef __SONYTYPES_H__
+#define __SONYTYPES_H__
+
+/******************************************************************************
+ *    Environment configuration
+ ******************************************************************************/
+#define _BUILD_FOR_PALMOS_5_
+       /* this definition must not appear in SDK for PalmOS 4 or older (for 3.5) */
+       /* Defining this here and not in SonyCLIE.h is reasonable, since SonyCLIE.h
+            is not included in all libraries. */
+
+#endif // __SONYTYPES_H__
+
diff --git a/util/pce.h b/util/pce.h
new file mode 100644 (file)
index 0000000..7d44e74
--- /dev/null
@@ -0,0 +1,53 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef PCE_H
+#define PCE_H
+
+#include <stdint.h>
+#include <Standalone.h>
+#include <PceNativeCall.h>
+
+#define ByteSwap16(n) ( ((((unsigned short) (n)) << 8) & 0xFF00) | \
+                        ((((unsigned short) (n)) >> 8) & 0x00FF) )
+
+#define ByteSwap32(n) ( ((((unsigned long) (n)) << 24) & 0xFF000000) | \
+                        ((((unsigned long) (n)) <<  8) & 0x00FF0000) | \
+                        ((((unsigned long) (n)) >>  8) & 0x0000FF00) | \
+                        ((((unsigned long) (n)) >> 24) & 0x000000FF) )
+
+#define Read68KUnaligned32(a) \
+     ( ((((unsigned char *)(a))[0]) << 24) | \
+       ((((unsigned char *)(a))[1]) << 16) | \
+       ((((unsigned char *)(a))[2]) <<  8) | \
+       ((((unsigned char *)(a))[3]) <<  0) )
+
+#define Write68KUnaligned32(a, v) \
+     ( ((unsigned char *)(a))[0]=(unsigned char)((unsigned long)(v) >> 24), \
+       ((unsigned char *)(a))[1]=(unsigned char)((unsigned long)(v) >> 16), \
+       ((unsigned char *)(a))[2]=(unsigned char)((unsigned long)(v) >>  8), \
+       ((unsigned char *)(a))[3]=(unsigned char)((unsigned long)(v) >>  0) )
+
+
+#endif
diff --git a/util/queue.c b/util/queue.c
new file mode 100644 (file)
index 0000000..8758b19
--- /dev/null
@@ -0,0 +1,91 @@
+/**********
+ * Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "assert.h"
+#include "queue.h"
+#include "ssh/openssh/buffer.h"
+
+struct queue_t {
+    Buffer b;
+};
+
+
+queue_t *queue_new(void)
+{
+    queue_t *q = arena_calloc(sizeof(queue_t));
+    buffer_init(&q->b);
+    return q;
+}
+
+void queue_free(queue_t *q)
+{
+    if (q) {
+        buffer_free(&q->b);
+        arena_free(q);
+    }
+}
+
+uint16_t queue_count(queue_t *q)
+{
+    return buffer_len(&q->b) / sizeof(void *);
+}
+
+Boolean queue_empty(queue_t *q)
+{
+    return buffer_len(&q->b) == 0;
+}
+
+void queue_enqueue(queue_t *q, void *e)
+{
+    buffer_append(&q->b, &e, sizeof(void *));
+}
+
+void *queue_dequeue(queue_t *q)
+{
+    void *result;
+    assert(queue_count(q) > 0);
+    buffer_get(&q->b, &result, sizeof(void *));
+    return result;
+}
+
+void *queue_peek(queue_t *q, uint16_t index)
+{
+    assert(index < queue_count(q));
+    return ((void **)buffer_ptr(&q->b))[index];
+}
+
+void queue_remove_if_present(queue_t *q, void *e)
+{
+    void **p = buffer_ptr(&q->b);
+    void **end = (void **)(buffer_len(&q->b) + (uint8_t *)buffer_ptr(&q->b));
+
+    for ( ; p < end; p++) {
+        if (*p == e) {
+            memcpy(p, p+1, (end - p+1) * sizeof(void *));
+            buffer_consume_end(&q->b, sizeof(void *));
+            return;
+        }
+    }
+}
diff --git a/util/queue.h b/util/queue.h
new file mode 100644 (file)
index 0000000..0eae5bc
--- /dev/null
@@ -0,0 +1,41 @@
+/**********
+ * Copyright (c) 2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef QUEUE_H
+#define QUEUE_H
+
+#include "includes.h"
+
+typedef struct queue_t queue_t;
+
+queue_t *queue_new(void);
+void queue_free(queue_t *q);
+uint16_t queue_count(queue_t *q);
+Boolean queue_empty(queue_t *q);
+void queue_enqueue(queue_t *q, void *e);
+void *queue_dequeue(queue_t *q);
+void *queue_peek(queue_t *q, uint16_t index);
+void queue_remove_if_present(queue_t *q, void *e);
+
+#endif
diff --git a/util/stdlib.c b/util/stdlib.c
new file mode 100644 (file)
index 0000000..00b24dc
--- /dev/null
@@ -0,0 +1,162 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "stdlib.h"
+
+#include "ctype.h"
+#include "assert.h"
+#include "ssh/ssh.h"
+#include "rsrc/rsrc.h"
+
+uint8_t *memchr(uint8_t *buf, uint8_t ch, uint16_t bufLen)
+{
+    uint8_t *end = buf + bufLen;
+    for ( ; buf < end; buf++) {
+        if (*buf == ch) return buf;
+    }
+    return NULL;
+}
+
+
+char *strsep(char **stringp, const char *delim)
+{
+    char *pos;
+    char *str = *stringp;
+    if (!str) return NULL;
+
+    // GrP only implemented for single-character delim
+    assert(strlen(delim) == 1);
+
+    pos = strchr(str, *delim);
+    if (pos) {
+        *pos = '\0';
+        *stringp = pos+1;
+    } else {
+        *stringp = NULL;
+    }
+    return str;
+}
+
+
+int strcasecmp(const char *s1, const char *s2)
+{
+    return StrCaselessCompare(s1, s2);
+}
+
+
+char *strcasestr(const char *big, const char *little)
+{
+    int littlelen = strlen(little);
+
+    const char *s = big;
+    for (s = big; *s != '\0'; s++) {
+        if (0 == memcmp(s, little, littlelen)) return (char *)s;
+    }
+    return NULL;
+}
+
+
+void printf(const char *format, ...)
+{
+    char buf[320];
+    char *c;
+    va_list args;
+    struct ssh_session_t *ss = ssh_get_current();
+
+    va_start(args, format);
+    vsnprintf(buf, sizeof(buf), format, args);
+    va_end(args);
+
+    // Filter out nonprintable chars
+    for (c = buf; *c != '\0'; c++) {
+        if (!isprint(*c)  &&  !isspace(*c)) *c = '?';
+    }
+
+    if (ss) ssh_receive_bytes(ss, buf, strlen(buf));
+    // ssh_update(ss);
+    // DON'T update here - it can cause a crash 
+}
+
+void debug_printf(const char *format, ...)
+{
+    char buf[320];
+    va_list args;
+    RectangleType r = {{0, 0}, {160, 14}};
+    WinHandle drawWindow;
+    int len;
+
+    len = snprintf(buf, sizeof(buf), "%lu ", TimGetTicks());
+
+    va_start(args, format);
+    vsnprintf(buf+len, sizeof(buf)-len, format, args);
+    va_end(args);
+
+    // print on top of program title box
+    // will be visible even with vt100 problems and alerts
+    // fixme this causes problems with hi-res drawing
+    // drawWindow = WinSetDrawWindow(NULL);
+    WinPushDrawState();
+    WinEraseRectangle(&r, 0);
+    WinDrawChars(buf, strlen(buf), 0, 0);
+    WinPopDrawState();
+    // WinSetDrawWindow(drawWindow);
+}
+
+int fatal(const char *format, ...)
+{
+    char buf[320];
+    va_list args;
+
+    va_start(args, format);
+    vsnprintf(buf, sizeof(buf), format, args);
+    va_end(args);
+
+    // release version: display alert, then kill program
+    FrmCustomAlert(FatalAlertID, buf, " ", " ");
+    SysReset();  // fixme don't see a better way to kill the program cleanly
+
+    // development version: don't obscure debug_printf output or vt100
+    /*
+      {
+      struct ssh_session_t *ss = ssh_get_current();
+      if (ss) {
+      ssh_receive_bytes(ss, "\nFATAL:", 7);
+      ssh_receive_bytes(ss, buf, strlen(buf));
+      } else {
+      debug_printf("%s", buf);
+      while(1) { }
+      }
+    */
+
+    return 0;
+}
+
+
+
+void assert_failed(uint32_t which)
+{
+    char intbuf[20];
+    FrmCustomAlert(AlertFormID, "arm assert failed!", StrIToA(intbuf, which), " ");
+}
+
diff --git a/util/stdlib.h b/util/stdlib.h
new file mode 100644 (file)
index 0000000..e5db837
--- /dev/null
@@ -0,0 +1,48 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef STDLIB_H
+#define STDLIB_H
+
+#include "includes.h"
+#include "xmalloc.h"
+
+struct ssh_session_t;
+
+uint8_t *memchr(uint8_t *buf, uint8_t ch, uint16_t bufLen);
+char *strsep(char **stringp, const char *delim);
+int strcasecmp(const char *s1, const char *s2);
+char *strcasestr(const char *big, const char *little);
+
+void printf(const char *format, ...);
+void debug_printf(const char *format, ...);
+int fatal(const char *format, ...);
+
+// in openssh/openbsd-compat/bsd-snprintf.c
+int vsnprintf(char *str, size_t count, const char *fmt, va_list args);
+int snprintf(char *str, size_t count, const char *fmt, ...) SSH_SEGMENT;
+
+void assert_failed(uint32_t which);
+
+#endif
diff --git a/util/xmalloc.c b/util/xmalloc.c
new file mode 100644 (file)
index 0000000..f7793b0
--- /dev/null
@@ -0,0 +1,88 @@
+/**********
+ * Copyright (c) 2003-2005 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "ssh/ssh.h"
+
+#include <PalmOSGlue.h>
+
+// #define DEBUG_ARENA
+// #define DEBUG_NONARENA
+
+// arena allocator is intended for use if pssh ever supports multiple 
+// simultaneous connections. An error in one connection would trigger 
+// destruction of its arena during cleanup.
+// Currently, arena and non-arena allocators are identical.
+
+void *arena_malloc(size_t s) 
+{
+    void *p;
+    if (s == 0) s = 1; // fixme openssh is expecting fatal for size 0
+    p = MemGluePtrNew(s);
+    if (p == NULL) {
+        debug_printf("%ld bytes", s);
+        fatal("arena_malloc: out of memory");
+    }
+    return p;
+}
+
+void arena_free(void *p) 
+{
+    if (!p) return; // needed by PuTTY?
+    MemPtrFree(p);
+}
+
+void *arena_calloc(size_t s) 
+{
+    void *p;
+    p = arena_malloc(s);
+    memset(p, 0, s);
+    return p;
+}
+
+void *arena_realloc(void *oldp, size_t newsize)
+{
+    void *newp;
+
+    newp = arena_malloc(newsize);
+    if (!oldp) {
+        return newp;
+    } else {
+        size_t oldsize;
+        oldsize = MemPtrSize(oldp);
+        memcpy(newp, oldp, MIN(newsize, oldsize));
+        arena_free(oldp); // fixme reallocf?
+        return newp;
+    }
+}
+
+char *arena_strdup(const char *s)
+{
+    size_t len = 1+strlen(s);
+    char *news;
+    news = arena_malloc(len);
+    memcpy(news, s, len);
+    return news;
+}
+
diff --git a/util/xmalloc.h b/util/xmalloc.h
new file mode 100644 (file)
index 0000000..4f9824a
--- /dev/null
@@ -0,0 +1,48 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef XMALLOC_H
+#define XMALLOC_H
+
+#include "includes.h"
+
+void *arena_malloc(size_t s);
+void arena_free(void *p);
+void *arena_calloc(size_t s);
+void *arena_realloc(void *oldp, size_t newsize);
+char *arena_strdup(const char *s);
+
+// non-arena versions
+#define nonarena_malloc arena_malloc
+#define nonarena_free arena_free
+#define nonarena_strdup arena_strdup
+
+// OpenSSH versions (fixme move somewhere else?)
+#define xmalloc arena_malloc
+#define xfree arena_free
+#define xrealloc arena_realloc
+#define xcalloc arena_calloc
+#define xstrdup arena_strdup
+
+#endif
diff --git a/vt100/vt100.c b/vt100/vt100.c
new file mode 100644 (file)
index 0000000..c0da798
--- /dev/null
@@ -0,0 +1,306 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#include "includes.h"
+#include "vt100.h"
+#include "armstubs.h"
+#include "peal.h"
+
+
+// bounds is STANDARD-RESOLUTION
+struct display *vt100_new(struct ssh_session_t *ss, RectangleType bounds) 
+{
+    uint32_t param[5];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    vt100_log(__PRETTY_FUNCTION__);
+
+    param[0] = (uint32_t)ss;
+    param[1] = (uint32_t)&bounds;
+    return (struct display *) PealCall(arm_module, sym, param);
+}
+
+
+void vt100_free(struct display *disp) 
+{
+    uint32_t param[1];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    vt100_log(__PRETTY_FUNCTION__);
+
+    param[0] = (uint32_t)disp;
+    PealCall(arm_module, sym, param);
+}
+
+
+void vt100_write(struct display *disp, const char *bytes, size_t len) 
+{
+    uint32_t param[3];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    vt100_log(__PRETTY_FUNCTION__);
+
+    param[0] = (uint32_t)disp;
+    param[1] = (uint32_t)bytes;
+    param[2] = (uint32_t)len;
+    PealCall(arm_module, sym, param);
+}
+
+
+void vt100_update(struct display *disp) 
+{
+    uint32_t param[1];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    vt100_log(__PRETTY_FUNCTION__);
+
+    param[0] = (uint32_t)disp;
+    PealCall(arm_module, sym, param);
+}
+
+
+void vt100_task(struct display *disp) 
+{
+    uint32_t param[1];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    vt100_log(__PRETTY_FUNCTION__);
+
+    param[0] = (uint32_t)disp;
+    PealCall(arm_module, sym, param);
+}
+
+
+void vt100_scroll(struct display *disp, int lines) 
+{
+    uint32_t param[2];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    vt100_log(__PRETTY_FUNCTION__);
+
+    param[0] = (uint32_t)disp;
+    param[1] = (uint32_t)lines;
+    PealCall(arm_module, sym, param);
+}
+
+
+void vt100_activate(struct display *disp) 
+{
+    uint32_t param[1];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    vt100_log(__PRETTY_FUNCTION__);
+
+    param[0] = (uint32_t)disp;
+    PealCall(arm_module, sym, param);
+}
+
+
+void vt100_deactivate(struct display *disp) 
+{
+    uint32_t param[1];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    vt100_log(__PRETTY_FUNCTION__);
+
+    param[0] = (uint32_t)disp;
+    PealCall(arm_module, sym, param);
+}
+
+
+// in: bounds (STANDARD-RESOLUTION)
+// out: charsWide and charsHigh
+void vt100_set_bounds(struct display *disp, RectangleType bounds) 
+{
+    uint32_t param[5];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    vt100_log(__PRETTY_FUNCTION__);
+
+    param[0] = (uint32_t)disp;
+    param[1] = (uint32_t)&bounds;
+    PealCall(arm_module, sym, param);
+}
+
+
+// x and y are STANDARD-RESOLUTION
+// clickCount is 1 or more for mouse down, 0 for mouse up
+void vt100_click(struct display *disp, int x, int y, int clickCount) 
+{
+    uint32_t param[4];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    vt100_log(__PRETTY_FUNCTION__);
+
+    param[0] = (uint32_t)disp;
+    param[1] = (uint32_t)x;
+    param[2] = (uint32_t)y;
+    param[3] = (uint32_t)clickCount;
+    PealCall(arm_module, sym, param);
+}
+
+
+void vt100_deselect(struct display *disp) 
+{
+    uint32_t param[1];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    vt100_log(__PRETTY_FUNCTION__);
+
+    param[0] = (uint32_t)disp;
+    PealCall(arm_module, sym, param);
+}
+
+
+void vt100_copy(struct display *disp) 
+{
+    uint32_t param[1];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    vt100_log(__PRETTY_FUNCTION__);
+
+    param[0] = (uint32_t)disp;
+    PealCall(arm_module, sym, param);
+}
+
+
+void vt100_paste(struct display *disp) 
+{
+    uint32_t param[1];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    vt100_log(__PRETTY_FUNCTION__);
+
+    param[0] = (uint32_t)disp;
+    PealCall(arm_module, sym, param);
+}
+
+
+int vt100_selection_exists(struct display *disp) 
+{
+    uint32_t param[1];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    vt100_log(__PRETTY_FUNCTION__);
+
+    param[0] = (uint32_t)disp;
+    return (int) PealCall(arm_module, sym, param);
+}
+
+
+// bounds returned is NATIVE-RESOLUTION
+void vt100_size(struct display *disp, int *charsWide, int *charsHigh, RectangleType *bounds) 
+{
+    uint32_t param[4];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    vt100_log(__PRETTY_FUNCTION__);
+
+    param[0] = (uint32_t)disp;
+    param[1] = (uint32_t)charsWide;
+    param[2] = (uint32_t)charsHigh;
+    param[3] = (uint32_t)bounds;
+    PealCall(arm_module, sym, param);
+}
+
+
+void vt100_reread_prefs(struct display *disp) 
+{
+    uint32_t param[1];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    vt100_log(__PRETTY_FUNCTION__);
+
+    param[0] = (uint32_t)disp;
+    PealCall(arm_module, sym, param);
+}
+
+
+void vt100_seen_key(struct display *disp) 
+{
+    uint32_t param[1];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    vt100_log(__PRETTY_FUNCTION__);
+
+    param[0] = (uint32_t)disp;
+    PealCall(arm_module, sym, param);
+}
+
+
+int vt100_app_cursor_keys(struct display *disp) 
+{
+    uint32_t param[1];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    vt100_log(__PRETTY_FUNCTION__);
+
+    param[0] = (uint32_t)disp;
+    return (int) PealCall(arm_module, sym, param);
+}
+
+
+FontID font_for_screen(int fontPref)
+{
+    uint32_t param[1];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    vt100_log(__PRETTY_FUNCTION__);
+
+    param[0] = (uint32_t)fontPref;
+    return (FontID) PealCall(arm_module, sym, param);
+}
+
+
+void set_palm_color(int fg_color, int bg_color)
+{
+    uint32_t param[2];
+    static void *sym = NULL;
+    if (!sym) sym = PealLookupSymbol(arm_module, __FUNCTION__ "_stub");
+    if (!sym) fatal("no ARM symbol %s", __FUNCTION__ "_stub");
+    vt100_log(__PRETTY_FUNCTION__);
+
+    param[0] = (uint32_t)fg_color;
+    param[1] = (uint32_t)bg_color;
+    PealCall(arm_module, sym, param);
+}
diff --git a/vt100/vt100.h b/vt100/vt100.h
new file mode 100644 (file)
index 0000000..1e23743
--- /dev/null
@@ -0,0 +1,75 @@
+/**********
+ * Copyright (c) 2003-2004 Greg Parker.  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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``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 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.
+ **********/
+
+#ifndef VT100_H
+#define VT100_H
+
+#include "includes.h"
+
+struct display;  // ARM-only
+
+// bounds is STANDARD-RESOLUTION
+struct display *vt100_new(struct ssh_session_t *ss, 
+                          RectangleType bounds) VT100_SEGMENT;
+
+void vt100_free(struct display *disp) VT100_SEGMENT;
+
+void vt100_write(struct display *disp, const char *bytes, size_t len) VT100_SEGMENT;
+
+void vt100_update(struct display *disp) VT100_SEGMENT;
+
+void vt100_task(struct display *disp) VT100_SEGMENT;
+
+void vt100_scroll(struct display *disp, int lines) VT100_SEGMENT;
+
+void vt100_activate(struct display *disp) VT100_SEGMENT;
+
+void vt100_deactivate(struct display *disp) VT100_SEGMENT;
+
+// in: bounds (STANDARD-RESOLUTION)
+// out: charsWide and charsHigh
+void vt100_set_bounds(struct display *disp, RectangleType bounds) VT100_SEGMENT;
+
+// x and y are STANDARD-RESOLUTION
+// clickCount is 1 or more for mouse down, 0 for mouse up
+void vt100_click(struct display *disp, int x, int y, int clickCount) VT100_SEGMENT;
+
+void vt100_deselect(struct display *disp) VT100_SEGMENT;
+
+void vt100_copy(struct display *disp) VT100_SEGMENT;
+
+void vt100_paste(struct display *disp) VT100_SEGMENT;
+
+int vt100_selection_exists(struct display *disp) VT100_SEGMENT;
+
+// bounds returned is NATIVE-RESOLUTION
+void vt100_size(struct display *disp, int *charsWide, int *charsHigh, RectangleType *bounds) VT100_SEGMENT;
+
+void vt100_reread_prefs(struct display *disp) VT100_SEGMENT;
+
+void vt100_seen_key(struct display *disp) VT100_SEGMENT;
+
+int vt100_app_cursor_keys(struct display *disp) VT100_SEGMENT; // fixme suck
+
+#endif