From 52d9d61ac6635b07baeb1db688169c8156a6745e Mon Sep 17 00:00:00 2001 From: Bob Beck Date: Fri, 15 Dec 2000 02:58:47 +0000 Subject: import openssl-0.9.7-beta1 --- lib/libssl/src/README.ENGINE | 63 + lib/libssl/src/apps/dh2048.pem | 12 + lib/libssl/src/apps/dh4096.pem | 18 + lib/libssl/src/apps/dh512.pem | 9 + lib/libssl/src/apps/rsautl.c | 315 ++++ lib/libssl/src/crypto/asn1/a_strex.c | 533 ++++++ lib/libssl/src/crypto/asn1/charmap.h | 15 + lib/libssl/src/crypto/asn1/charmap.pl | 80 + lib/libssl/src/crypto/bio/bf_lbuf.c | 397 +++++ lib/libssl/src/crypto/bn/asm/pa-risc2W.s | 1605 +++++++++++++++++ lib/libssl/src/crypto/conf/conf_api.c | 289 ++++ lib/libssl/src/crypto/conf/conf_api.h | 87 + lib/libssl/src/crypto/conf/conf_def.c | 703 ++++++++ lib/libssl/src/crypto/conf/conf_def.h | 145 ++ lib/libssl/src/crypto/conf/conf_lib.c | 352 ++++ lib/libssl/src/crypto/dso/Makefile.ssl | 140 ++ lib/libssl/src/crypto/dso/README | 24 + lib/libssl/src/crypto/dso/dso.h | 250 +++ lib/libssl/src/crypto/dso/dso_dl.c | 251 +++ lib/libssl/src/crypto/dso/dso_dlfcn.c | 276 +++ lib/libssl/src/crypto/dso/dso_err.c | 128 ++ lib/libssl/src/crypto/dso/dso_lib.c | 306 ++++ lib/libssl/src/crypto/dso/dso_null.c | 86 + lib/libssl/src/crypto/dso/dso_openssl.c | 81 + lib/libssl/src/crypto/dso/dso_vms.c | 371 ++++ lib/libssl/src/crypto/dso/dso_win32.c | 273 +++ lib/libssl/src/crypto/engine/Makefile.ssl | 220 +++ lib/libssl/src/crypto/engine/README | 278 +++ lib/libssl/src/crypto/engine/engine.h | 398 +++++ lib/libssl/src/crypto/engine/enginetest.c | 251 +++ lib/libssl/src/crypto/engine/hw_atalla.c | 444 +++++ lib/libssl/src/crypto/engine/hw_cswift.c | 807 +++++++++ lib/libssl/src/crypto/engine/hw_ncipher.c | 1019 +++++++++++ lib/libssl/src/crypto/engine/vendor_defns/atalla.h | 61 + lib/libssl/src/crypto/engine/vendor_defns/cswift.h | 213 +++ lib/libssl/src/crypto/evp/e_bf.c | 80 + lib/libssl/src/crypto/evp/e_cast.c | 82 + lib/libssl/src/crypto/evp/e_des.c | 118 ++ lib/libssl/src/crypto/evp/e_des3.c | 165 ++ lib/libssl/src/crypto/evp/e_idea.c | 112 ++ lib/libssl/src/crypto/evp/e_rc2.c | 222 +++ lib/libssl/src/crypto/evp/e_rc5.c | 118 ++ lib/libssl/src/crypto/evp/evp_locl.h | 168 ++ lib/libssl/src/crypto/evp/m_md4.c | 83 + lib/libssl/src/crypto/md4/Makefile.ssl | 84 + lib/libssl/src/crypto/md4/md4.c | 127 ++ lib/libssl/src/crypto/md4/md4.h | 114 ++ lib/libssl/src/crypto/md4/md4_dgst.c | 285 ++++ lib/libssl/src/crypto/md4/md4_locl.h | 154 ++ lib/libssl/src/crypto/md4/md4_one.c | 95 ++ lib/libssl/src/crypto/md4/md4s.cpp | 78 + lib/libssl/src/crypto/md4/md4test.c | 131 ++ lib/libssl/src/crypto/objects/obj_mac.h | 1798 ++++++++++++++++++++ lib/libssl/src/crypto/objects/obj_mac.num | 392 +++++ lib/libssl/src/crypto/objects/objects.README | 44 + lib/libssl/src/crypto/objects/objects.pl | 224 +++ lib/libssl/src/crypto/rand/rand_lcl.h | 184 ++ lib/libssl/src/crypto/rand/rand_win.c | 732 ++++++++ lib/libssl/src/crypto/symhacks.h | 154 ++ lib/libssl/src/doc/apps/rsautl.pod | 183 ++ lib/libssl/src/doc/crypto/BIO_ctrl.pod | 128 ++ lib/libssl/src/doc/crypto/BIO_f_base64.pod | 82 + lib/libssl/src/doc/crypto/BIO_f_buffer.pod | 69 + lib/libssl/src/doc/crypto/BIO_f_cipher.pod | 76 + lib/libssl/src/doc/crypto/BIO_f_md.pod | 138 ++ lib/libssl/src/doc/crypto/BIO_f_null.pod | 32 + lib/libssl/src/doc/crypto/BIO_f_ssl.pod | 313 ++++ lib/libssl/src/doc/crypto/BIO_find_type.pod | 98 ++ lib/libssl/src/doc/crypto/BIO_new.pod | 65 + lib/libssl/src/doc/crypto/BIO_new_bio_pair.pod | 102 ++ lib/libssl/src/doc/crypto/BIO_push.pod | 69 + lib/libssl/src/doc/crypto/BIO_read.pod | 66 + lib/libssl/src/doc/crypto/BIO_s_accept.pod | 184 ++ lib/libssl/src/doc/crypto/BIO_s_bio.pod | 130 ++ lib/libssl/src/doc/crypto/BIO_s_connect.pod | 182 ++ lib/libssl/src/doc/crypto/BIO_s_fd.pod | 89 + lib/libssl/src/doc/crypto/BIO_s_file.pod | 144 ++ lib/libssl/src/doc/crypto/BIO_s_mem.pod | 115 ++ lib/libssl/src/doc/crypto/BIO_s_null.pod | 37 + lib/libssl/src/doc/crypto/BIO_s_socket.pod | 61 + lib/libssl/src/doc/crypto/BIO_set_callback.pod | 108 ++ lib/libssl/src/doc/crypto/BIO_should_retry.pod | 114 ++ lib/libssl/src/doc/crypto/bio.pod | 54 + lib/libssl/src/doc/crypto/evp.pod | 37 + lib/libssl/src/doc/ssl/SSL_CIPHER_get_name.pod | 57 + lib/libssl/src/doc/ssl/SSL_CTX_free.pod | 29 + lib/libssl/src/doc/ssl/SSL_CTX_new.pod | 93 + lib/libssl/src/doc/ssl/SSL_CTX_set_cipher_list.pod | 52 + lib/libssl/src/doc/ssl/SSL_CTX_set_ssl_version.pod | 60 + lib/libssl/src/doc/ssl/SSL_SESSION_free.pod | 25 + lib/libssl/src/doc/ssl/SSL_accept.pod | 72 + lib/libssl/src/doc/ssl/SSL_clear.pod | 39 + lib/libssl/src/doc/ssl/SSL_connect.pod | 69 + lib/libssl/src/doc/ssl/SSL_free.pod | 33 + lib/libssl/src/doc/ssl/SSL_get_ciphers.pod | 42 + lib/libssl/src/doc/ssl/SSL_get_current_cipher.pod | 43 + lib/libssl/src/doc/ssl/SSL_get_fd.pod | 44 + lib/libssl/src/doc/ssl/SSL_get_peer_cert_chain.pod | 52 + .../src/doc/ssl/SSL_get_peer_certificate.pod | 48 + lib/libssl/src/doc/ssl/SSL_get_rbio.pod | 40 + lib/libssl/src/doc/ssl/SSL_get_session.pod | 48 + lib/libssl/src/doc/ssl/SSL_get_verify_result.pod | 57 + lib/libssl/src/doc/ssl/SSL_library_init.pod | 52 + lib/libssl/src/doc/ssl/SSL_new.pod | 42 + lib/libssl/src/doc/ssl/SSL_pending.pod | 30 + lib/libssl/src/doc/ssl/SSL_read.pod | 77 + lib/libssl/src/doc/ssl/SSL_set_bio.pod | 34 + lib/libssl/src/doc/ssl/SSL_set_fd.pod | 54 + lib/libssl/src/doc/ssl/SSL_set_session.pod | 45 + lib/libssl/src/doc/ssl/SSL_set_verify_result.pod | 38 + lib/libssl/src/doc/ssl/SSL_shutdown.pod | 62 + lib/libssl/src/doc/ssl/SSL_write.pod | 76 + lib/libssl/src/doc/standards.txt | 121 ++ lib/libssl/src/ms/tlhelp32.h | 136 ++ lib/libssl/src/openssl.spec | 213 +++ lib/libssl/src/times/x86/md4s.cpp | 78 + lib/libssl/src/util/mkstack.pl | 124 ++ 117 files changed, 21005 insertions(+) create mode 100644 lib/libssl/src/README.ENGINE create mode 100644 lib/libssl/src/apps/dh2048.pem create mode 100644 lib/libssl/src/apps/dh4096.pem create mode 100644 lib/libssl/src/apps/dh512.pem create mode 100644 lib/libssl/src/apps/rsautl.c create mode 100644 lib/libssl/src/crypto/asn1/a_strex.c create mode 100644 lib/libssl/src/crypto/asn1/charmap.h create mode 100644 lib/libssl/src/crypto/asn1/charmap.pl create mode 100644 lib/libssl/src/crypto/bio/bf_lbuf.c create mode 100644 lib/libssl/src/crypto/bn/asm/pa-risc2W.s create mode 100644 lib/libssl/src/crypto/conf/conf_api.c create mode 100644 lib/libssl/src/crypto/conf/conf_api.h create mode 100644 lib/libssl/src/crypto/conf/conf_def.c create mode 100644 lib/libssl/src/crypto/conf/conf_def.h create mode 100644 lib/libssl/src/crypto/conf/conf_lib.c create mode 100644 lib/libssl/src/crypto/dso/Makefile.ssl create mode 100644 lib/libssl/src/crypto/dso/README create mode 100644 lib/libssl/src/crypto/dso/dso.h create mode 100644 lib/libssl/src/crypto/dso/dso_dl.c create mode 100644 lib/libssl/src/crypto/dso/dso_dlfcn.c create mode 100644 lib/libssl/src/crypto/dso/dso_err.c create mode 100644 lib/libssl/src/crypto/dso/dso_lib.c create mode 100644 lib/libssl/src/crypto/dso/dso_null.c create mode 100644 lib/libssl/src/crypto/dso/dso_openssl.c create mode 100644 lib/libssl/src/crypto/dso/dso_vms.c create mode 100644 lib/libssl/src/crypto/dso/dso_win32.c create mode 100644 lib/libssl/src/crypto/engine/Makefile.ssl create mode 100644 lib/libssl/src/crypto/engine/README create mode 100644 lib/libssl/src/crypto/engine/engine.h create mode 100644 lib/libssl/src/crypto/engine/enginetest.c create mode 100644 lib/libssl/src/crypto/engine/hw_atalla.c create mode 100644 lib/libssl/src/crypto/engine/hw_cswift.c create mode 100644 lib/libssl/src/crypto/engine/hw_ncipher.c create mode 100644 lib/libssl/src/crypto/engine/vendor_defns/atalla.h create mode 100644 lib/libssl/src/crypto/engine/vendor_defns/cswift.h create mode 100644 lib/libssl/src/crypto/evp/e_bf.c create mode 100644 lib/libssl/src/crypto/evp/e_cast.c create mode 100644 lib/libssl/src/crypto/evp/e_des.c create mode 100644 lib/libssl/src/crypto/evp/e_des3.c create mode 100644 lib/libssl/src/crypto/evp/e_idea.c create mode 100644 lib/libssl/src/crypto/evp/e_rc2.c create mode 100644 lib/libssl/src/crypto/evp/e_rc5.c create mode 100644 lib/libssl/src/crypto/evp/evp_locl.h create mode 100644 lib/libssl/src/crypto/evp/m_md4.c create mode 100644 lib/libssl/src/crypto/md4/Makefile.ssl create mode 100644 lib/libssl/src/crypto/md4/md4.c create mode 100644 lib/libssl/src/crypto/md4/md4.h create mode 100644 lib/libssl/src/crypto/md4/md4_dgst.c create mode 100644 lib/libssl/src/crypto/md4/md4_locl.h create mode 100644 lib/libssl/src/crypto/md4/md4_one.c create mode 100644 lib/libssl/src/crypto/md4/md4s.cpp create mode 100644 lib/libssl/src/crypto/md4/md4test.c create mode 100644 lib/libssl/src/crypto/objects/obj_mac.h create mode 100644 lib/libssl/src/crypto/objects/obj_mac.num create mode 100644 lib/libssl/src/crypto/objects/objects.README create mode 100644 lib/libssl/src/crypto/objects/objects.pl create mode 100644 lib/libssl/src/crypto/rand/rand_lcl.h create mode 100644 lib/libssl/src/crypto/rand/rand_win.c create mode 100644 lib/libssl/src/crypto/symhacks.h create mode 100644 lib/libssl/src/doc/apps/rsautl.pod create mode 100644 lib/libssl/src/doc/crypto/BIO_ctrl.pod create mode 100644 lib/libssl/src/doc/crypto/BIO_f_base64.pod create mode 100644 lib/libssl/src/doc/crypto/BIO_f_buffer.pod create mode 100644 lib/libssl/src/doc/crypto/BIO_f_cipher.pod create mode 100644 lib/libssl/src/doc/crypto/BIO_f_md.pod create mode 100644 lib/libssl/src/doc/crypto/BIO_f_null.pod create mode 100644 lib/libssl/src/doc/crypto/BIO_f_ssl.pod create mode 100644 lib/libssl/src/doc/crypto/BIO_find_type.pod create mode 100644 lib/libssl/src/doc/crypto/BIO_new.pod create mode 100644 lib/libssl/src/doc/crypto/BIO_new_bio_pair.pod create mode 100644 lib/libssl/src/doc/crypto/BIO_push.pod create mode 100644 lib/libssl/src/doc/crypto/BIO_read.pod create mode 100644 lib/libssl/src/doc/crypto/BIO_s_accept.pod create mode 100644 lib/libssl/src/doc/crypto/BIO_s_bio.pod create mode 100644 lib/libssl/src/doc/crypto/BIO_s_connect.pod create mode 100644 lib/libssl/src/doc/crypto/BIO_s_fd.pod create mode 100644 lib/libssl/src/doc/crypto/BIO_s_file.pod create mode 100644 lib/libssl/src/doc/crypto/BIO_s_mem.pod create mode 100644 lib/libssl/src/doc/crypto/BIO_s_null.pod create mode 100644 lib/libssl/src/doc/crypto/BIO_s_socket.pod create mode 100644 lib/libssl/src/doc/crypto/BIO_set_callback.pod create mode 100644 lib/libssl/src/doc/crypto/BIO_should_retry.pod create mode 100644 lib/libssl/src/doc/crypto/bio.pod create mode 100644 lib/libssl/src/doc/crypto/evp.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_CIPHER_get_name.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_CTX_free.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_CTX_new.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_CTX_set_cipher_list.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_CTX_set_ssl_version.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_SESSION_free.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_accept.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_clear.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_connect.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_free.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_get_ciphers.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_get_current_cipher.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_get_fd.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_get_peer_cert_chain.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_get_peer_certificate.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_get_rbio.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_get_session.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_get_verify_result.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_library_init.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_new.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_pending.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_read.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_set_bio.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_set_fd.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_set_session.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_set_verify_result.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_shutdown.pod create mode 100644 lib/libssl/src/doc/ssl/SSL_write.pod create mode 100644 lib/libssl/src/doc/standards.txt create mode 100644 lib/libssl/src/ms/tlhelp32.h create mode 100644 lib/libssl/src/openssl.spec create mode 100644 lib/libssl/src/times/x86/md4s.cpp create mode 100644 lib/libssl/src/util/mkstack.pl (limited to 'lib/libssl') diff --git a/lib/libssl/src/README.ENGINE b/lib/libssl/src/README.ENGINE new file mode 100644 index 00000000000..3d88ed152ff --- /dev/null +++ b/lib/libssl/src/README.ENGINE @@ -0,0 +1,63 @@ + + ENGINE + ====== + + With OpenSSL 0.9.6, a new component has been added to support external + crypto devices, for example accelerator cards. The component is called + ENGINE, and has still a pretty experimental status and almost no + documentation. It's designed to be faily easily extensible by the + calling programs. + + There's currently built-in support for the following crypto devices: + + o CryptoSwift + o Compaq Atalla + o nCipher CHIL + + A number of things are still needed and are being worked on: + + o An openssl utility command to handle or at least check available + engines. + o A better way of handling the methods that are handled by the + engines. + o Documentation! + + What already exists is fairly stable as far as it has been tested, but + the test base has been a bit small most of the time. + + Because of this experimental status and what's lacking, the ENGINE + component is not yet part of the default OpenSSL distribution. However, + we have made a separate kit for those who want to try this out, to be + found in the same places as the default OpenSSL distribution, but with + "-engine-" being part of the kit file name. For example, version 0.9.6 + is distributed in the following two files: + + openssl-0.9.6.tar.gz + openssl-engine-0.9.6.tar.gz + + NOTES + ===== + + openssl-engine-0.9.6.tar.gz does not depend on openssl-0.9.6.tar, you do + not need to download both. + + openssl-engine-0.9.6.tar.gz is usable even if you don't have an external + crypto device. The internal OpenSSL functions are contained in the + engine "openssl", and will be used by default. + + No external crypto device is chosen unless you say so. You have actively + tell the openssl utility commands to use it through a new command line + switch called "-engine". And if you want to use the ENGINE library to + do something similar, you must also explicitely choose an external crypto + device, or the built-in crypto routines will be used, just as in the + default OpenSSL distribution. + + + PROBLEMS + ======== + + It seems like the ENGINE part doesn't work too well with Cryptoswift on + Win32. A quick test done right before the release showed that trying + "openssl speed -engine cswift" generated errors. If the DSO gets enabled, + an attempt is made to write at memory address 0x00000002. + diff --git a/lib/libssl/src/apps/dh2048.pem b/lib/libssl/src/apps/dh2048.pem new file mode 100644 index 00000000000..dcd0b8d01b8 --- /dev/null +++ b/lib/libssl/src/apps/dh2048.pem @@ -0,0 +1,12 @@ +-----BEGIN DH PARAMETERS----- +MIIBCAKCAQEA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlLOCDaAadWoxTpj0BV +89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeSWc39uK50 +T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0iP1YTknb +zSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF040zT9fBdX +Q6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCbAkbT +CD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwIBAg== +-----END DH PARAMETERS----- + +These are the 2048 bit DH parameters from "Assigned Number for SKIP Protocols" +(http://www.skip-vpn.org/spec/numbers.html). +See there for how they were generated. diff --git a/lib/libssl/src/apps/dh4096.pem b/lib/libssl/src/apps/dh4096.pem new file mode 100644 index 00000000000..1b35ad8e62e --- /dev/null +++ b/lib/libssl/src/apps/dh4096.pem @@ -0,0 +1,18 @@ +-----BEGIN DH PARAMETERS----- +MIICCAKCAgEA+hRyUsFN4VpJ1O8JLcCo/VWr19k3BCgJ4uk+d+KhehjdRqNDNyOQ +l/MOyQNQfWXPeGKmOmIig6Ev/nm6Nf9Z2B1h3R4hExf+zTiHnvVPeRBhjdQi81rt +Xeoh6TNrSBIKIHfUJWBh3va0TxxjQIs6IZOLeVNRLMqzeylWqMf49HsIXqbcokUS +Vt1BkvLdW48j8PPv5DsKRN3tloTxqDJGo9tKvj1Fuk74A+Xda1kNhB7KFlqMyN98 +VETEJ6c7KpfOo30mnK30wqw3S8OtaIR/maYX72tGOno2ehFDkq3pnPtEbD2CScxc +alJC+EL7RPk5c/tgeTvCngvc1KZn92Y//EI7G9tPZtylj2b56sHtMftIoYJ9+ODM +sccD5Piz/rejE3Ome8EOOceUSCYAhXn8b3qvxVI1ddd1pED6FHRhFvLrZxFvBEM9 +ERRMp5QqOaHJkM+Dxv8Cj6MqrCbfC4u+ZErxodzuusgDgvZiLF22uxMZbobFWyte +OvOzKGtwcTqO/1wV5gKkzu1ZVswVUQd5Gg8lJicwqRWyyNRczDDoG9jVDxmogKTH +AaqLulO7R8Ifa1SwF2DteSGVtgWEN8gDpN3RBmmPTDngyF2DHb5qmpnznwtFKdTL +KWbuHn491xNO25CQWMtem80uKw+pTnisBRF/454n1Jnhub144YRBoN8CAQI= +-----END DH PARAMETERS----- + +These are the 4096 bit DH parameters from "Assigned Number for SKIP Protocols" +(http://www.skip-vpn.org/spec/numbers.html). +See there for how they were generated. +Note that g is not a generator, but this is not a problem since p is a safe prime. diff --git a/lib/libssl/src/apps/dh512.pem b/lib/libssl/src/apps/dh512.pem new file mode 100644 index 00000000000..200d16cd897 --- /dev/null +++ b/lib/libssl/src/apps/dh512.pem @@ -0,0 +1,9 @@ +-----BEGIN DH PARAMETERS----- +MEYCQQD1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWak +XUGfnHy9iUsiGSa6q6Jew1XpKgVfAgEC +-----END DH PARAMETERS----- + +These are the 512 bit DH parameters from "Assigned Number for SKIP Protocols" +(http://www.skip-vpn.org/spec/numbers.html). +See there for how they were generated. +Note that g is not a generator, but this is not a problem since p is a safe prime. diff --git a/lib/libssl/src/apps/rsautl.c b/lib/libssl/src/apps/rsautl.c new file mode 100644 index 00000000000..2ef75649dd7 --- /dev/null +++ b/lib/libssl/src/apps/rsautl.c @@ -0,0 +1,315 @@ +/* rsautl.c */ +/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 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 + * 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). + * + */ +#include "apps.h" +#include +#include +#include +#include + +#define RSA_SIGN 1 +#define RSA_VERIFY 2 +#define RSA_ENCRYPT 3 +#define RSA_DECRYPT 4 + +#define KEY_PRIVKEY 1 +#define KEY_PUBKEY 2 +#define KEY_CERT 3 + +static void usage(void); + +#undef PROG + +#define PROG rsautl_main + +int MAIN(int argc, char **); + +int MAIN(int argc, char **argv) +{ + ENGINE *e = NULL; + BIO *in = NULL, *out = NULL; + char *infile = NULL, *outfile = NULL; + char *keyfile = NULL; + char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY; + int keyform = FORMAT_PEM; + char need_priv = 0, badarg = 0, rev = 0; + char hexdump = 0, asn1parse = 0; + X509 *x; + EVP_PKEY *pkey = NULL; + RSA *rsa = NULL; + unsigned char *rsa_in = NULL, *rsa_out = NULL, pad; + int rsa_inlen, rsa_outlen = 0; + int keysize; + char *engine=NULL; + + int ret = 1; + + argc--; + argv++; + + if(!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); + ERR_load_crypto_strings(); + OpenSSL_add_all_algorithms(); + pad = RSA_PKCS1_PADDING; + + while(argc >= 1) + { + if (!strcmp(*argv,"-in")) { + if (--argc < 1) badarg = 1; + infile= *(++argv); + } else if (!strcmp(*argv,"-out")) { + if (--argc < 1) badarg = 1; + outfile= *(++argv); + } else if(!strcmp(*argv, "-inkey")) { + if (--argc < 1) badarg = 1; + keyfile = *(++argv); + } else if(!strcmp(*argv, "-engine")) { + if (--argc < 1) badarg = 1; + engine = *(++argv); + } else if(!strcmp(*argv, "-pubin")) { + key_type = KEY_PUBKEY; + } else if(!strcmp(*argv, "-certin")) { + key_type = KEY_CERT; + } + else if(!strcmp(*argv, "-asn1parse")) asn1parse = 1; + else if(!strcmp(*argv, "-hexdump")) hexdump = 1; + else if(!strcmp(*argv, "-raw")) pad = RSA_NO_PADDING; + else if(!strcmp(*argv, "-oaep")) pad = RSA_PKCS1_OAEP_PADDING; + else if(!strcmp(*argv, "-ssl")) pad = RSA_SSLV23_PADDING; + else if(!strcmp(*argv, "-pkcs")) pad = RSA_PKCS1_PADDING; + else if(!strcmp(*argv, "-sign")) { + rsa_mode = RSA_SIGN; + need_priv = 1; + } else if(!strcmp(*argv, "-verify")) rsa_mode = RSA_VERIFY; + else if(!strcmp(*argv, "-rev")) rev = 1; + else if(!strcmp(*argv, "-encrypt")) rsa_mode = RSA_ENCRYPT; + else if(!strcmp(*argv, "-decrypt")) { + rsa_mode = RSA_DECRYPT; + need_priv = 1; + } else badarg = 1; + if(badarg) { + usage(); + goto end; + } + argc--; + argv++; + } + + if(need_priv && (key_type != KEY_PRIVKEY)) { + BIO_printf(bio_err, "A private key is needed for this operation\n"); + goto end; + } + + if (engine != NULL) + { + if((e = ENGINE_by_id(engine)) == NULL) + { + BIO_printf(bio_err,"invalid engine \"%s\"\n", + engine); + goto end; + } + if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) + { + BIO_printf(bio_err,"can't use that engine\n"); + goto end; + } + BIO_printf(bio_err,"engine \"%s\" set.\n", engine); + /* Free our "structural" reference. */ + ENGINE_free(e); + } + +/* FIXME: seed PRNG only if needed */ + app_RAND_load_file(NULL, bio_err, 0); + + switch(key_type) { + case KEY_PRIVKEY: + pkey = load_key(bio_err, keyfile, keyform, NULL); + break; + + case KEY_PUBKEY: + pkey = load_pubkey(bio_err, keyfile, keyform); + break; + + case KEY_CERT: + x = load_cert(bio_err, keyfile, keyform); + if(x) { + pkey = X509_get_pubkey(x); + X509_free(x); + } + break; + } + + if(!pkey) { + BIO_printf(bio_err, "Error loading key\n"); + return 1; + } + + rsa = EVP_PKEY_get1_RSA(pkey); + EVP_PKEY_free(pkey); + + if(!rsa) { + BIO_printf(bio_err, "Error getting RSA key\n"); + ERR_print_errors(bio_err); + goto end; + } + + + if(infile) { + if(!(in = BIO_new_file(infile, "rb"))) { + BIO_printf(bio_err, "Error Reading Input File\n"); + ERR_print_errors(bio_err); + goto end; + } + } else in = BIO_new_fp(stdin, BIO_NOCLOSE); + + if(outfile) { + if(!(out = BIO_new_file(outfile, "wb"))) { + BIO_printf(bio_err, "Error Reading Output File\n"); + ERR_print_errors(bio_err); + goto end; + } + } else { + out = BIO_new_fp(stdout, BIO_NOCLOSE); +#ifdef VMS + { + BIO *tmpbio = BIO_new(BIO_f_linebuffer()); + out = BIO_push(tmpbio, out); + } +#endif + } + + keysize = RSA_size(rsa); + + rsa_in = OPENSSL_malloc(keysize * 2); + rsa_out = OPENSSL_malloc(keysize); + + /* Read the input data */ + rsa_inlen = BIO_read(in, rsa_in, keysize * 2); + if(rsa_inlen <= 0) { + BIO_printf(bio_err, "Error reading input Data\n"); + exit(1); + } + if(rev) { + int i; + unsigned char ctmp; + for(i = 0; i < rsa_inlen/2; i++) { + ctmp = rsa_in[i]; + rsa_in[i] = rsa_in[rsa_inlen - 1 - i]; + rsa_in[rsa_inlen - 1 - i] = ctmp; + } + } + switch(rsa_mode) { + + case RSA_VERIFY: + rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); + break; + + case RSA_SIGN: + rsa_outlen = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); + break; + + case RSA_ENCRYPT: + rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); + break; + + case RSA_DECRYPT: + rsa_outlen = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); + break; + + } + + if(rsa_outlen <= 0) { + BIO_printf(bio_err, "RSA operation error\n"); + ERR_print_errors(bio_err); + goto end; + } + ret = 0; + if(asn1parse) { + if(!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) { + ERR_print_errors(bio_err); + } + } else if(hexdump) BIO_dump(out, (char *)rsa_out, rsa_outlen); + else BIO_write(out, rsa_out, rsa_outlen); + end: + RSA_free(rsa); + BIO_free(in); + BIO_free_all(out); + if(rsa_in) OPENSSL_free(rsa_in); + if(rsa_out) OPENSSL_free(rsa_out); + return ret; +} + +static void usage() +{ + BIO_printf(bio_err, "Usage: rsautl [options]\n"); + BIO_printf(bio_err, "-in file input file\n"); + BIO_printf(bio_err, "-out file output file\n"); + BIO_printf(bio_err, "-inkey file input key\n"); + BIO_printf(bio_err, "-pubin input is an RSA public\n"); + BIO_printf(bio_err, "-certin input is a certificate carrying an RSA public key\n"); + BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n"); + BIO_printf(bio_err, "-ssl use SSL v2 padding\n"); + BIO_printf(bio_err, "-raw use no padding\n"); + BIO_printf(bio_err, "-pkcs use PKCS#1 v1.5 padding (default)\n"); + BIO_printf(bio_err, "-oaep use PKCS#1 OAEP\n"); + BIO_printf(bio_err, "-sign sign with private key\n"); + BIO_printf(bio_err, "-verify verify with public key\n"); + BIO_printf(bio_err, "-encrypt encrypt with public key\n"); + BIO_printf(bio_err, "-decrypt decrypt with private key\n"); + BIO_printf(bio_err, "-hexdump hex dump output\n"); +} + diff --git a/lib/libssl/src/crypto/asn1/a_strex.c b/lib/libssl/src/crypto/asn1/a_strex.c new file mode 100644 index 00000000000..569b8119985 --- /dev/null +++ b/lib/libssl/src/crypto/asn1/a_strex.c @@ -0,0 +1,533 @@ +/* a_strex.c */ +/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 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 + * 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). + * + */ + +#include +#include +#include +#include +#include + +#include "charmap.h" + +/* ASN1_STRING_print_ex() and X509_NAME_print_ex(). + * Enhanced string and name printing routines handling + * multibyte characters, RFC2253 and a host of other + * options. + */ + + +#define CHARTYPE_BS_ESC (ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253) + + +/* Three IO functions for sending data to memory, a BIO and + * and a FILE pointer. + */ + +int send_mem_chars(void *arg, const void *buf, int len) +{ + unsigned char **out = arg; + if(!out) return 1; + memcpy(*out, buf, len); + *out += len; + return 1; +} + +int send_bio_chars(void *arg, const void *buf, int len) +{ + if(!arg) return 1; + if(BIO_write(arg, buf, len) != len) return 0; + return 1; +} + +int send_fp_chars(void *arg, const void *buf, int len) +{ + if(!arg) return 1; + if(fwrite(buf, 1, len, arg) != (unsigned int)len) return 0; + return 1; +} + +typedef int char_io(void *arg, const void *buf, int len); + +/* This function handles display of + * strings, one character at a time. + * It is passed an unsigned long for each + * character because it could come from 2 or even + * 4 byte forms. + */ + +static int do_esc_char(unsigned long c, unsigned char flags, char *do_quotes, char_io *io_ch, void *arg) +{ + unsigned char chflgs, chtmp; + char tmphex[11]; + if(c > 0xffff) { + BIO_snprintf(tmphex, 11, "\\W%08lX", c); + if(!io_ch(arg, tmphex, 10)) return -1; + return 10; + } + if(c > 0xff) { + BIO_snprintf(tmphex, 11, "\\U%04lX", c); + if(!io_ch(arg, tmphex, 6)) return -1; + return 6; + } + chtmp = (unsigned char)c; + if(chtmp > 0x7f) chflgs = flags & ASN1_STRFLGS_ESC_MSB; + else chflgs = char_type[chtmp] & flags; + if(chflgs & CHARTYPE_BS_ESC) { + /* If we don't escape with quotes, signal we need quotes */ + if(chflgs & ASN1_STRFLGS_ESC_QUOTE) { + if(do_quotes) *do_quotes = 1; + if(!io_ch(arg, &chtmp, 1)) return -1; + return 1; + } + if(!io_ch(arg, "\\", 1)) return -1; + if(!io_ch(arg, &chtmp, 1)) return -1; + return 2; + } + if(chflgs & (ASN1_STRFLGS_ESC_CTRL|ASN1_STRFLGS_ESC_MSB)) { + BIO_snprintf(tmphex, 11, "\\%02X", chtmp); + if(!io_ch(arg, tmphex, 3)) return -1; + return 3; + } + if(!io_ch(arg, &chtmp, 1)) return -1; + return 1; +} + +#define BUF_TYPE_WIDTH_MASK 0x7 +#define BUF_TYPE_CONVUTF8 0x8 + +/* This function sends each character in a buffer to + * do_esc_char(). It interprets the content formats + * and converts to or from UTF8 as appropriate. + */ + +static int do_buf(unsigned char *buf, int buflen, + int type, unsigned char flags, char *quotes, char_io *io_ch, void *arg) +{ + int i, outlen, len; + unsigned char orflags, *p, *q; + unsigned long c; + p = buf; + q = buf + buflen; + outlen = 0; + while(p != q) { + if(p == buf) orflags = CHARTYPE_FIRST_ESC_2253; + else orflags = 0; + switch(type & BUF_TYPE_WIDTH_MASK) { + case 4: + c = ((unsigned long)*p++) << 24; + c |= ((unsigned long)*p++) << 16; + c |= ((unsigned long)*p++) << 8; + c |= *p++; + break; + + case 2: + c = ((unsigned long)*p++) << 8; + c |= *p++; + break; + + case 1: + c = *p++; + break; + + case 0: + i = UTF8_getc(p, buflen, &c); + if(i < 0) return -1; /* Invalid UTF8String */ + p += i; + break; + } + if (p == q) orflags = CHARTYPE_LAST_ESC_2253; + if(type & BUF_TYPE_CONVUTF8) { + unsigned char utfbuf[6]; + int utflen; + utflen = UTF8_putc(utfbuf, 6, c); + for(i = 0; i < utflen; i++) { + /* We don't need to worry about setting orflags correctly + * because if utflen==1 its value will be correct anyway + * otherwise each character will be > 0x7f and so the + * character will never be escaped on first and last. + */ + len = do_esc_char(utfbuf[i], (unsigned char)(flags | orflags), quotes, io_ch, arg); + if(len < 0) return -1; + outlen += len; + } + } else { + len = do_esc_char(c, (unsigned char)(flags | orflags), quotes, io_ch, arg); + if(len < 0) return -1; + outlen += len; + } + } + return outlen; +} + +/* This function hex dumps a buffer of characters */ + +static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf, int buflen) +{ + const static char hexdig[] = "0123456789ABCDEF"; + unsigned char *p, *q; + char hextmp[2]; + if(arg) { + p = buf; + q = buf + buflen; + while(p != q) { + hextmp[0] = hexdig[*p >> 4]; + hextmp[1] = hexdig[*p & 0xf]; + if(!io_ch(arg, hextmp, 2)) return -1; + p++; + } + } + return buflen << 1; +} + +/* "dump" a string. This is done when the type is unknown, + * or the flags request it. We can either dump the content + * octets or the entire DER encoding. This uses the RFC2253 + * #01234 format. + */ + +int do_dump(unsigned long lflags, char_io *io_ch, void *arg, ASN1_STRING *str) +{ + /* Placing the ASN1_STRING in a temp ASN1_TYPE allows + * the DER encoding to readily obtained + */ + ASN1_TYPE t; + unsigned char *der_buf, *p; + int outlen, der_len; + + if(!io_ch(arg, "#", 1)) return -1; + /* If we don't dump DER encoding just dump content octets */ + if(!(lflags & ASN1_STRFLGS_DUMP_DER)) { + outlen = do_hex_dump(io_ch, arg, str->data, str->length); + if(outlen < 0) return -1; + return outlen + 1; + } + t.type = str->type; + t.value.ptr = (char *)str; + der_len = i2d_ASN1_TYPE(&t, NULL); + der_buf = OPENSSL_malloc(der_len); + if(!der_buf) return -1; + p = der_buf; + i2d_ASN1_TYPE(&t, &p); + outlen = do_hex_dump(io_ch, arg, der_buf, der_len); + OPENSSL_free(der_buf); + if(outlen < 0) return -1; + return outlen + 1; +} + +/* Lookup table to convert tags to character widths, + * 0 = UTF8 encoded, -1 is used for non string types + * otherwise it is the number of bytes per character + */ + +const static char tag2nbyte[] = { + -1, -1, -1, -1, -1, /* 0-4 */ + -1, -1, -1, -1, -1, /* 5-9 */ + -1, -1, 0, -1, /* 10-13 */ + -1, -1, -1, -1, /* 15-17 */ + -1, 1, 1, /* 18-20 */ + -1, 1, -1,-1, /* 21-24 */ + -1, 1, -1, /* 25-27 */ + 4, -1, 2 /* 28-30 */ +}; + +#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \ + ASN1_STRFLGS_ESC_QUOTE | \ + ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB) + +/* This is the main function, print out an + * ASN1_STRING taking note of various escape + * and display options. Returns number of + * characters written or -1 if an error + * occurred. + */ + +static int do_print_ex(char_io *io_ch, void *arg, unsigned long lflags, ASN1_STRING *str) +{ + int outlen, len; + int type; + char quotes; + unsigned char flags; + quotes = 0; + /* Keep a copy of escape flags */ + flags = (unsigned char)(lflags & ESC_FLAGS); + + type = str->type; + + outlen = 0; + + + if(lflags & ASN1_STRFLGS_SHOW_TYPE) { + const char *tagname; + tagname = ASN1_tag2str(type); + outlen += strlen(tagname); + if(!io_ch(arg, tagname, outlen) || !io_ch(arg, ":", 1)) return -1; + outlen++; + } + + /* Decide what to do with type, either dump content or display it */ + + /* Dump everything */ + if(lflags & ASN1_STRFLGS_DUMP_ALL) type = -1; + /* Ignore the string type */ + else if(lflags & ASN1_STRFLGS_IGNORE_TYPE) type = 1; + else { + /* Else determine width based on type */ + if((type > 0) && (type < 31)) type = tag2nbyte[type]; + else type = -1; + if((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN)) type = 1; + } + + if(type == -1) { + len = do_dump(lflags, io_ch, arg, str); + if(len < 0) return -1; + outlen += len; + return outlen; + } + + if(lflags & ASN1_STRFLGS_UTF8_CONVERT) { + /* Note: if string is UTF8 and we want + * to convert to UTF8 then we just interpret + * it as 1 byte per character to avoid converting + * twice. + */ + if(!type) type = 1; + else type |= BUF_TYPE_CONVUTF8; + } + + len = do_buf(str->data, str->length, type, flags, "es, io_ch, NULL); + if(outlen < 0) return -1; + outlen += len; + if(quotes) outlen += 2; + if(!arg) return outlen; + if(quotes && !io_ch(arg, "\"", 1)) return -1; + do_buf(str->data, str->length, type, flags, NULL, io_ch, arg); + if(quotes && !io_ch(arg, "\"", 1)) return -1; + return outlen; +} + +/* Used for line indenting: print 'indent' spaces */ + +static int do_indent(char_io *io_ch, void *arg, int indent) +{ + int i; + for(i = 0; i < indent; i++) + if(!io_ch(arg, " ", 1)) return 0; + return 1; +} + + +static int do_name_ex(char_io *io_ch, void *arg, X509_NAME *n, + int indent, unsigned long flags) +{ + int i, prev = -1, orflags, cnt; + int fn_opt, fn_nid; + ASN1_OBJECT *fn; + ASN1_STRING *val; + X509_NAME_ENTRY *ent; + char objtmp[80]; + const char *objbuf; + int outlen, len; + char *sep_dn, *sep_mv, *sep_eq; + int sep_dn_len, sep_mv_len, sep_eq_len; + if(indent < 0) indent = 0; + outlen = indent; + if(!do_indent(io_ch, arg, indent)) return -1; + switch (flags & XN_FLAG_SEP_MASK) + { + case XN_FLAG_SEP_MULTILINE: + sep_dn = "\n"; + sep_dn_len = 1; + sep_mv = " + "; + sep_mv_len = 3; + break; + + case XN_FLAG_SEP_COMMA_PLUS: + sep_dn = ","; + sep_dn_len = 1; + sep_mv = "+"; + sep_mv_len = 1; + indent = 0; + break; + + case XN_FLAG_SEP_CPLUS_SPC: + sep_dn = ", "; + sep_dn_len = 2; + sep_mv = " + "; + sep_mv_len = 3; + indent = 0; + break; + + case XN_FLAG_SEP_SPLUS_SPC: + sep_dn = "; "; + sep_dn_len = 2; + sep_mv = " + "; + sep_mv_len = 3; + indent = 0; + break; + + default: + return -1; + } + + if(flags & XN_FLAG_SPC_EQ) { + sep_eq = " = "; + sep_eq_len = 3; + } else { + sep_eq = "="; + sep_eq_len = 1; + } + + fn_opt = flags & XN_FLAG_FN_MASK; + + cnt = X509_NAME_entry_count(n); + for(i = 0; i < cnt; i++) { + if(flags & XN_FLAG_DN_REV) + ent = X509_NAME_get_entry(n, cnt - i - 1); + else ent = X509_NAME_get_entry(n, i); + if(prev != -1) { + if(prev == ent->set) { + if(!io_ch(arg, sep_mv, sep_mv_len)) return -1; + outlen += sep_mv_len; + } else { + if(!io_ch(arg, sep_dn, sep_dn_len)) return -1; + outlen += sep_dn_len; + if(!do_indent(io_ch, arg, indent)) return -1; + outlen += indent; + } + } + prev = ent->set; + fn = X509_NAME_ENTRY_get_object(ent); + val = X509_NAME_ENTRY_get_data(ent); + fn_nid = OBJ_obj2nid(fn); + if(fn_opt != XN_FLAG_FN_NONE) { + int objlen; + if((fn_opt == XN_FLAG_FN_OID) || (fn_nid==NID_undef) ) { + OBJ_obj2txt(objtmp, 80, fn, 1); + objbuf = objtmp; + } else { + if(fn_opt == XN_FLAG_FN_SN) + objbuf = OBJ_nid2sn(fn_nid); + else if(fn_opt == XN_FLAG_FN_LN) + objbuf = OBJ_nid2ln(fn_nid); + else objbuf = ""; + } + objlen = strlen(objbuf); + if(!io_ch(arg, objbuf, objlen)) return -1; + if(!io_ch(arg, sep_eq, sep_eq_len)) return -1; + outlen += objlen + sep_eq_len; + } + /* If the field name is unknown then fix up the DER dump + * flag. We might want to limit this further so it will + * DER dump on anything other than a few 'standard' fields. + */ + if((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS)) + orflags = ASN1_STRFLGS_DUMP_ALL; + else orflags = 0; + + len = do_print_ex(io_ch, arg, flags | orflags, val); + if(len < 0) return -1; + outlen += len; + } + return outlen; +} + +/* Wrappers round the main functions */ + +int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags) +{ + return do_name_ex(send_bio_chars, out, nm, indent, flags); +} + + +int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags) +{ + return do_name_ex(send_fp_chars, fp, nm, indent, flags); +} + +int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags) +{ + return do_print_ex(send_bio_chars, out, flags, str); +} + + +int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags) +{ + return do_print_ex(send_fp_chars, fp, flags, str); +} + +/* Utility function: convert any string type to UTF8, returns number of bytes + * in output string or a negative error code + */ + +int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in) +{ + ASN1_STRING stmp, *str = &stmp; + int mbflag, type, ret; + if(!*out || !in) return -1; + type = in->type; + if((type < 0) || (type > 30)) return -1; + mbflag = tag2nbyte[type]; + if(mbflag == -1) return -1; + mbflag |= MBSTRING_FLAG; + stmp.data = NULL; + ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag, B_ASN1_UTF8STRING); + if(ret < 0) return ret; + if(out) *out = stmp.data; + return stmp.length; +} diff --git a/lib/libssl/src/crypto/asn1/charmap.h b/lib/libssl/src/crypto/asn1/charmap.h new file mode 100644 index 00000000000..bd020a9562f --- /dev/null +++ b/lib/libssl/src/crypto/asn1/charmap.h @@ -0,0 +1,15 @@ +/* Auto generated with chartype.pl script. + * Mask of various character properties + */ + +static unsigned char char_type[] = { + 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, 2, +120, 0, 1,40, 0, 0, 0,16,16,16, 0,25,25,16,16,16, +16,16,16,16,16,16,16,16,16,16,16, 9, 9,16, 9,16, + 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, +16,16,16,16,16,16,16,16,16,16,16, 0, 1, 0, 0, 0, + 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, +16,16,16,16,16,16,16,16,16,16,16, 0, 0, 0, 0, 2 +}; + diff --git a/lib/libssl/src/crypto/asn1/charmap.pl b/lib/libssl/src/crypto/asn1/charmap.pl new file mode 100644 index 00000000000..2875c598672 --- /dev/null +++ b/lib/libssl/src/crypto/asn1/charmap.pl @@ -0,0 +1,80 @@ +#!/usr/local/bin/perl -w + +use strict; + +my ($i, @arr); + +# Set up an array with the type of ASCII characters +# Each set bit represents a character property. + +# RFC2253 character properties +my $RFC2253_ESC = 1; # Character escaped with \ +my $ESC_CTRL = 2; # Escaped control character +# These are used with RFC1779 quoting using " +my $NOESC_QUOTE = 8; # Not escaped if quoted +my $PSTRING_CHAR = 0x10; # Valid PrintableString character +my $RFC2253_FIRST_ESC = 0x20; # Escaped with \ if first character +my $RFC2253_LAST_ESC = 0x40; # Escaped with \ if last character + +for($i = 0; $i < 128; $i++) { + # Set the RFC2253 escape characters (control) + $arr[$i] = 0; + if(($i < 32) || ($i > 126)) { + $arr[$i] |= $ESC_CTRL; + } + + # Some PrintableString characters + if( ( ( $i >= ord("a")) && ( $i <= ord("z")) ) + || ( ( $i >= ord("A")) && ( $i <= ord("Z")) ) + || ( ( $i >= ord("0")) && ( $i <= ord("9")) ) ) { + $arr[$i] |= $PSTRING_CHAR; + } +} + +# Now setup the rest + +# Remaining RFC2253 escaped characters + +$arr[ord(" ")] |= $NOESC_QUOTE | $RFC2253_FIRST_ESC | $RFC2253_LAST_ESC; +$arr[ord("#")] |= $NOESC_QUOTE | $RFC2253_FIRST_ESC; + +$arr[ord(",")] |= $NOESC_QUOTE | $RFC2253_ESC; +$arr[ord("+")] |= $NOESC_QUOTE | $RFC2253_ESC; +$arr[ord("\"")] |= $RFC2253_ESC; +$arr[ord("\\")] |= $RFC2253_ESC; +$arr[ord("<")] |= $NOESC_QUOTE | $RFC2253_ESC; +$arr[ord(">")] |= $NOESC_QUOTE | $RFC2253_ESC; +$arr[ord(";")] |= $NOESC_QUOTE | $RFC2253_ESC; + +# Remaining PrintableString characters + +$arr[ord(" ")] |= $PSTRING_CHAR; +$arr[ord("'")] |= $PSTRING_CHAR; +$arr[ord("(")] |= $PSTRING_CHAR; +$arr[ord(")")] |= $PSTRING_CHAR; +$arr[ord("+")] |= $PSTRING_CHAR; +$arr[ord(",")] |= $PSTRING_CHAR; +$arr[ord("-")] |= $PSTRING_CHAR; +$arr[ord(".")] |= $PSTRING_CHAR; +$arr[ord("/")] |= $PSTRING_CHAR; +$arr[ord(":")] |= $PSTRING_CHAR; +$arr[ord("=")] |= $PSTRING_CHAR; +$arr[ord("?")] |= $PSTRING_CHAR; + +# Now generate the C code + +print < +#include +#include "cryptlib.h" +#include +#include + +static int linebuffer_write(BIO *h, const char *buf,int num); +static int linebuffer_read(BIO *h, char *buf, int size); +static int linebuffer_puts(BIO *h, const char *str); +static int linebuffer_gets(BIO *h, char *str, int size); +static long linebuffer_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int linebuffer_new(BIO *h); +static int linebuffer_free(BIO *data); +static long linebuffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); + +/* A 10k maximum should be enough for most purposes */ +#define DEFAULT_LINEBUFFER_SIZE 1024*10 + +/* #define DEBUG */ + +static BIO_METHOD methods_linebuffer= + { + BIO_TYPE_LINEBUFFER, + "linebuffer", + linebuffer_write, + linebuffer_read, + linebuffer_puts, + linebuffer_gets, + linebuffer_ctrl, + linebuffer_new, + linebuffer_free, + linebuffer_callback_ctrl, + }; + +BIO_METHOD *BIO_f_linebuffer(void) + { + return(&methods_linebuffer); + } + +typedef struct bio_linebuffer_ctx_struct + { + char *obuf; /* the output char array */ + int obuf_size; /* how big is the output buffer */ + int obuf_len; /* how many bytes are in it */ + } BIO_LINEBUFFER_CTX; + +static int linebuffer_new(BIO *bi) + { + BIO_LINEBUFFER_CTX *ctx; + + ctx=(BIO_LINEBUFFER_CTX *)OPENSSL_malloc(sizeof(BIO_LINEBUFFER_CTX)); + if (ctx == NULL) return(0); + ctx->obuf=(char *)OPENSSL_malloc(DEFAULT_LINEBUFFER_SIZE); + if (ctx->obuf == NULL) { OPENSSL_free(ctx); return(0); } + ctx->obuf_size=DEFAULT_LINEBUFFER_SIZE; + ctx->obuf_len=0; + + bi->init=1; + bi->ptr=(char *)ctx; + bi->flags=0; + return(1); + } + +static int linebuffer_free(BIO *a) + { + BIO_LINEBUFFER_CTX *b; + + if (a == NULL) return(0); + b=(BIO_LINEBUFFER_CTX *)a->ptr; + if (b->obuf != NULL) OPENSSL_free(b->obuf); + OPENSSL_free(a->ptr); + a->ptr=NULL; + a->init=0; + a->flags=0; + return(1); + } + +static int linebuffer_read(BIO *b, char *out, int outl) + { + int ret=0; + + if (out == NULL) return(0); + if (b->next_bio == NULL) return(0); + ret=BIO_read(b->next_bio,out,outl); + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + return(ret); + } + +static int linebuffer_write(BIO *b, const char *in, int inl) + { + int i,num=0,foundnl; + BIO_LINEBUFFER_CTX *ctx; + + if ((in == NULL) || (inl <= 0)) return(0); + ctx=(BIO_LINEBUFFER_CTX *)b->ptr; + if ((ctx == NULL) || (b->next_bio == NULL)) return(0); + + BIO_clear_retry_flags(b); + + do + { + const char *p; + + for(p = in; p < in + inl && *p != '\n'; p++) + ; + if (*p == '\n') + { + p++; + foundnl = 1; + } + else + foundnl = 0; + + /* If a NL was found and we already have text in the save + buffer, concatenate them and write */ + while ((foundnl || p - in > ctx->obuf_size - ctx->obuf_len) + && ctx->obuf_len > 0) + { + int orig_olen = ctx->obuf_len; + + i = ctx->obuf_size - ctx->obuf_len; + if (p - in > 0) + { + if (i >= p - in) + { + memcpy(&(ctx->obuf[ctx->obuf_len]), + in,p - in); + ctx->obuf_len += p - in; + inl -= p - in; + num += p - in; + in = p; + } + else + { + memcpy(&(ctx->obuf[ctx->obuf_len]), + in,i); + ctx->obuf_len += i; + inl -= i; + in += i; + num += i; + } + } + +#ifdef DEBUG +BIO_write(b->next_bio, "<*<", 3); +#endif + i=BIO_write(b->next_bio, + ctx->obuf, ctx->obuf_len); + if (i <= 0) + { + ctx->obuf_len = orig_olen; + BIO_copy_next_retry(b); + +#ifdef DEBUG +BIO_write(b->next_bio, ">*>", 3); +#endif + if (i < 0) return((num > 0)?num:i); + if (i == 0) return(num); + } +#ifdef DEBUG +BIO_write(b->next_bio, ">*>", 3); +#endif + if (i < ctx->obuf_len) + memmove(ctx->obuf, ctx->obuf + i, + ctx->obuf_len - i); + ctx->obuf_len-=i; + } + + /* Now that the save buffer is emptied, let's write the input + buffer if a NL was found and there is anything to write. */ + if ((foundnl || p - in > ctx->obuf_size) && p - in > 0) + { +#ifdef DEBUG +BIO_write(b->next_bio, "<*<", 3); +#endif + i=BIO_write(b->next_bio,in,p - in); + if (i <= 0) + { + BIO_copy_next_retry(b); +#ifdef DEBUG +BIO_write(b->next_bio, ">*>", 3); +#endif + if (i < 0) return((num > 0)?num:i); + if (i == 0) return(num); + } +#ifdef DEBUG +BIO_write(b->next_bio, ">*>", 3); +#endif + num+=i; + in+=i; + inl-=i; + } + } + while(foundnl && inl > 0); + /* We've written as much as we can. The rest of the input buffer, if + any, is text that doesn't and with a NL and therefore needs to be + saved for the next trip. */ + if (inl > 0) + { + memcpy(&(ctx->obuf[ctx->obuf_len]), in, inl); + ctx->obuf_len += inl; + num += inl; + } + return num; + } + +static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr) + { + BIO *dbio; + BIO_LINEBUFFER_CTX *ctx; + long ret=1; + char *p; + int r; + int obs; + + ctx=(BIO_LINEBUFFER_CTX *)b->ptr; + + switch (cmd) + { + case BIO_CTRL_RESET: + ctx->obuf_len=0; + if (b->next_bio == NULL) return(0); + ret=BIO_ctrl(b->next_bio,cmd,num,ptr); + break; + case BIO_CTRL_INFO: + ret=(long)ctx->obuf_len; + break; + case BIO_CTRL_WPENDING: + ret=(long)ctx->obuf_len; + if (ret == 0) + { + if (b->next_bio == NULL) return(0); + ret=BIO_ctrl(b->next_bio,cmd,num,ptr); + } + break; + case BIO_C_SET_BUFF_SIZE: + obs=(int)num; + p=ctx->obuf; + if ((obs > DEFAULT_LINEBUFFER_SIZE) && (obs != ctx->obuf_size)) + { + p=(char *)OPENSSL_malloc((int)num); + if (p == NULL) + goto malloc_error; + } + if (ctx->obuf != p) + { + if (ctx->obuf_len > obs) + { + ctx->obuf_len = obs; + } + memcpy(p, ctx->obuf, ctx->obuf_len); + OPENSSL_free(ctx->obuf); + ctx->obuf=p; + ctx->obuf_size=obs; + } + break; + case BIO_C_DO_STATE_MACHINE: + if (b->next_bio == NULL) return(0); + BIO_clear_retry_flags(b); + ret=BIO_ctrl(b->next_bio,cmd,num,ptr); + BIO_copy_next_retry(b); + break; + + case BIO_CTRL_FLUSH: + if (b->next_bio == NULL) return(0); + if (ctx->obuf_len <= 0) + { + ret=BIO_ctrl(b->next_bio,cmd,num,ptr); + break; + } + + for (;;) + { + BIO_clear_retry_flags(b); + if (ctx->obuf_len > 0) + { + r=BIO_write(b->next_bio, + ctx->obuf, ctx->obuf_len); +#if 0 +fprintf(stderr,"FLUSH %3d -> %3d\n",ctx->obuf_len,r); +#endif + BIO_copy_next_retry(b); + if (r <= 0) return((long)r); + if (r < ctx->obuf_len) + memmove(ctx->obuf, ctx->obuf + r, + ctx->obuf_len - r); + ctx->obuf_len-=r; + } + else + { + ctx->obuf_len=0; + ret=1; + break; + } + } + ret=BIO_ctrl(b->next_bio,cmd,num,ptr); + break; + case BIO_CTRL_DUP: + dbio=(BIO *)ptr; + if ( !BIO_set_write_buffer_size(dbio,ctx->obuf_size)) + ret=0; + break; + default: + if (b->next_bio == NULL) return(0); + ret=BIO_ctrl(b->next_bio,cmd,num,ptr); + break; + } + return(ret); +malloc_error: + BIOerr(BIO_F_LINEBUFFER_CTRL,ERR_R_MALLOC_FAILURE); + return(0); + } + +static long linebuffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) + { + long ret=1; + + if (b->next_bio == NULL) return(0); + switch (cmd) + { + default: + ret=BIO_callback_ctrl(b->next_bio,cmd,fp); + break; + } + return(ret); + } + +static int linebuffer_gets(BIO *b, char *buf, int size) + { + if (b->next_bio == NULL) return(0); + return(BIO_gets(b->next_bio,buf,size)); + } + +static int linebuffer_puts(BIO *b, const char *str) + { + return(linebuffer_write(b,str,strlen(str))); + } + diff --git a/lib/libssl/src/crypto/bn/asm/pa-risc2W.s b/lib/libssl/src/crypto/bn/asm/pa-risc2W.s new file mode 100644 index 00000000000..54b6606252e --- /dev/null +++ b/lib/libssl/src/crypto/bn/asm/pa-risc2W.s @@ -0,0 +1,1605 @@ +; +; PA-RISC 64-bit implementation of bn_asm code +; +; This code is approximately 2x faster than the C version +; for RSA/DSA. +; +; See http://devresource.hp.com/ for more details on the PA-RISC +; architecture. Also see the book "PA-RISC 2.0 Architecture" +; by Gerry Kane for information on the instruction set architecture. +; +; Code written by Chris Ruemmler (with some help from the HP C +; compiler). +; +; The code compiles with HP's assembler +; + + .level 2.0W + .space $TEXT$ + .subspa $CODE$,QUAD=0,ALIGN=8,ACCESS=0x2c,CODE_ONLY + +; +; Global Register definitions used for the routines. +; +; Some information about HP's runtime architecture for 64-bits. +; +; "Caller save" means the calling function must save the register +; if it wants the register to be preserved. +; "Callee save" means if a function uses the register, it must save +; the value before using it. +; +; For the floating point registers +; +; "caller save" registers: fr4-fr11, fr22-fr31 +; "callee save" registers: fr12-fr21 +; "special" registers: fr0-fr3 (status and exception registers) +; +; For the integer registers +; value zero : r0 +; "caller save" registers: r1,r19-r26 +; "callee save" registers: r3-r18 +; return register : r2 (rp) +; return values ; r28 (ret0,ret1) +; Stack pointer ; r30 (sp) +; global data pointer ; r27 (dp) +; argument pointer ; r29 (ap) +; millicode return ptr ; r31 (also a caller save register) + + +; +; Arguments to the routines +; +r_ptr .reg %r26 +a_ptr .reg %r25 +b_ptr .reg %r24 +num .reg %r24 +w .reg %r23 +n .reg %r23 + + +; +; Globals used in some routines +; + +top_overflow .reg %r29 +high_mask .reg %r22 ; value 0xffffffff80000000L + + +;------------------------------------------------------------------------------ +; +; bn_mul_add_words +; +;BN_ULONG bn_mul_add_words(BN_ULONG *r_ptr, BN_ULONG *a_ptr, +; int num, BN_ULONG w) +; +; arg0 = r_ptr +; arg1 = a_ptr +; arg2 = num +; arg3 = w +; +; Local register definitions +; + +fm1 .reg %fr22 +fm .reg %fr23 +ht_temp .reg %fr24 +ht_temp_1 .reg %fr25 +lt_temp .reg %fr26 +lt_temp_1 .reg %fr27 +fm1_1 .reg %fr28 +fm_1 .reg %fr29 + +fw_h .reg %fr7L +fw_l .reg %fr7R +fw .reg %fr7 + +fht_0 .reg %fr8L +flt_0 .reg %fr8R +t_float_0 .reg %fr8 + +fht_1 .reg %fr9L +flt_1 .reg %fr9R +t_float_1 .reg %fr9 + +tmp_0 .reg %r31 +tmp_1 .reg %r21 +m_0 .reg %r20 +m_1 .reg %r19 +ht_0 .reg %r1 +ht_1 .reg %r3 +lt_0 .reg %r4 +lt_1 .reg %r5 +m1_0 .reg %r6 +m1_1 .reg %r7 +rp_val .reg %r8 +rp_val_1 .reg %r9 + +bn_mul_add_words + .export bn_mul_add_words,entry,NO_RELOCATION,LONG_RETURN + .proc + .callinfo frame=128 + .entry + .align 64 + + STD %r3,0(%sp) ; save r3 + STD %r4,8(%sp) ; save r4 + NOP ; Needed to make the loop 16-byte aligned + NOP ; Needed to make the loop 16-byte aligned + + STD %r5,16(%sp) ; save r5 + STD %r6,24(%sp) ; save r6 + STD %r7,32(%sp) ; save r7 + STD %r8,40(%sp) ; save r8 + + STD %r9,48(%sp) ; save r9 + COPY %r0,%ret0 ; return 0 by default + DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32 + STD w,56(%sp) ; store w on stack + + CMPIB,>= 0,num,bn_mul_add_words_exit ; if (num <= 0) then exit + LDO 128(%sp),%sp ; bump stack + + ; + ; The loop is unrolled twice, so if there is only 1 number + ; then go straight to the cleanup code. + ; + CMPIB,= 1,num,bn_mul_add_words_single_top + FLDD -72(%sp),fw ; load up w into fp register fw (fw_h/fw_l) + + ; + ; This loop is unrolled 2 times (64-byte aligned as well) + ; + ; PA-RISC 2.0 chips have two fully pipelined multipliers, thus + ; two 32-bit mutiplies can be issued per cycle. + ; +bn_mul_add_words_unroll2 + + FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R) + FLDD 8(a_ptr),t_float_1 ; load up 64-bit value (fr8L) ht(L)/lt(R) + LDD 0(r_ptr),rp_val ; rp[0] + LDD 8(r_ptr),rp_val_1 ; rp[1] + + XMPYU fht_0,fw_l,fm1 ; m1[0] = fht_0*fw_l + XMPYU fht_1,fw_l,fm1_1 ; m1[1] = fht_1*fw_l + FSTD fm1,-16(%sp) ; -16(sp) = m1[0] + FSTD fm1_1,-48(%sp) ; -48(sp) = m1[1] + + XMPYU flt_0,fw_h,fm ; m[0] = flt_0*fw_h + XMPYU flt_1,fw_h,fm_1 ; m[1] = flt_1*fw_h + FSTD fm,-8(%sp) ; -8(sp) = m[0] + FSTD fm_1,-40(%sp) ; -40(sp) = m[1] + + XMPYU fht_0,fw_h,ht_temp ; ht_temp = fht_0*fw_h + XMPYU fht_1,fw_h,ht_temp_1 ; ht_temp_1 = fht_1*fw_h + FSTD ht_temp,-24(%sp) ; -24(sp) = ht_temp + FSTD ht_temp_1,-56(%sp) ; -56(sp) = ht_temp_1 + + XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l + XMPYU flt_1,fw_l,lt_temp_1 ; lt_temp = lt*fw_l + FSTD lt_temp,-32(%sp) ; -32(sp) = lt_temp + FSTD lt_temp_1,-64(%sp) ; -64(sp) = lt_temp_1 + + LDD -8(%sp),m_0 ; m[0] + LDD -40(%sp),m_1 ; m[1] + LDD -16(%sp),m1_0 ; m1[0] + LDD -48(%sp),m1_1 ; m1[1] + + LDD -24(%sp),ht_0 ; ht[0] + LDD -56(%sp),ht_1 ; ht[1] + ADD,L m1_0,m_0,tmp_0 ; tmp_0 = m[0] + m1[0]; + ADD,L m1_1,m_1,tmp_1 ; tmp_1 = m[1] + m1[1]; + + LDD -32(%sp),lt_0 + LDD -64(%sp),lt_1 + CMPCLR,*>>= tmp_0,m1_0, %r0 ; if (m[0] < m1[0]) + ADD,L ht_0,top_overflow,ht_0 ; ht[0] += (1<<32) + + CMPCLR,*>>= tmp_1,m1_1,%r0 ; if (m[1] < m1[1]) + ADD,L ht_1,top_overflow,ht_1 ; ht[1] += (1<<32) + EXTRD,U tmp_0,31,32,m_0 ; m[0]>>32 + DEPD,Z tmp_0,31,32,m1_0 ; m1[0] = m[0]<<32 + + EXTRD,U tmp_1,31,32,m_1 ; m[1]>>32 + DEPD,Z tmp_1,31,32,m1_1 ; m1[1] = m[1]<<32 + ADD,L ht_0,m_0,ht_0 ; ht[0]+= (m[0]>>32) + ADD,L ht_1,m_1,ht_1 ; ht[1]+= (m[1]>>32) + + ADD lt_0,m1_0,lt_0 ; lt[0] = lt[0]+m1[0]; + ADD,DC ht_0,%r0,ht_0 ; ht[0]++ + ADD lt_1,m1_1,lt_1 ; lt[1] = lt[1]+m1[1]; + ADD,DC ht_1,%r0,ht_1 ; ht[1]++ + + ADD %ret0,lt_0,lt_0 ; lt[0] = lt[0] + c; + ADD,DC ht_0,%r0,ht_0 ; ht[0]++ + ADD lt_0,rp_val,lt_0 ; lt[0] = lt[0]+rp[0] + ADD,DC ht_0,%r0,ht_0 ; ht[0]++ + + LDO -2(num),num ; num = num - 2; + ADD ht_0,lt_1,lt_1 ; lt[1] = lt[1] + ht_0 (c); + ADD,DC ht_1,%r0,ht_1 ; ht[1]++ + STD lt_0,0(r_ptr) ; rp[0] = lt[0] + + ADD lt_1,rp_val_1,lt_1 ; lt[1] = lt[1]+rp[1] + ADD,DC ht_1,%r0,%ret0 ; ht[1]++ + LDO 16(a_ptr),a_ptr ; a_ptr += 2 + + STD lt_1,8(r_ptr) ; rp[1] = lt[1] + CMPIB,<= 2,num,bn_mul_add_words_unroll2 ; go again if more to do + LDO 16(r_ptr),r_ptr ; r_ptr += 2 + + CMPIB,=,N 0,num,bn_mul_add_words_exit ; are we done, or cleanup last one + + ; + ; Top of loop aligned on 64-byte boundary + ; +bn_mul_add_words_single_top + FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R) + LDD 0(r_ptr),rp_val ; rp[0] + LDO 8(a_ptr),a_ptr ; a_ptr++ + XMPYU fht_0,fw_l,fm1 ; m1 = ht*fw_l + FSTD fm1,-16(%sp) ; -16(sp) = m1 + XMPYU flt_0,fw_h,fm ; m = lt*fw_h + FSTD fm,-8(%sp) ; -8(sp) = m + XMPYU fht_0,fw_h,ht_temp ; ht_temp = ht*fw_h + FSTD ht_temp,-24(%sp) ; -24(sp) = ht + XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l + FSTD lt_temp,-32(%sp) ; -32(sp) = lt + + LDD -8(%sp),m_0 + LDD -16(%sp),m1_0 ; m1 = temp1 + ADD,L m_0,m1_0,tmp_0 ; tmp_0 = m + m1; + LDD -24(%sp),ht_0 + LDD -32(%sp),lt_0 + + CMPCLR,*>>= tmp_0,m1_0,%r0 ; if (m < m1) + ADD,L ht_0,top_overflow,ht_0 ; ht += (1<<32) + + EXTRD,U tmp_0,31,32,m_0 ; m>>32 + DEPD,Z tmp_0,31,32,m1_0 ; m1 = m<<32 + + ADD,L ht_0,m_0,ht_0 ; ht+= (m>>32) + ADD lt_0,m1_0,tmp_0 ; tmp_0 = lt+m1; + ADD,DC ht_0,%r0,ht_0 ; ht++ + ADD %ret0,tmp_0,lt_0 ; lt = lt + c; + ADD,DC ht_0,%r0,ht_0 ; ht++ + ADD lt_0,rp_val,lt_0 ; lt = lt+rp[0] + ADD,DC ht_0,%r0,%ret0 ; ht++ + STD lt_0,0(r_ptr) ; rp[0] = lt + +bn_mul_add_words_exit + .EXIT + LDD -80(%sp),%r9 ; restore r9 + LDD -88(%sp),%r8 ; restore r8 + LDD -96(%sp),%r7 ; restore r7 + LDD -104(%sp),%r6 ; restore r6 + LDD -112(%sp),%r5 ; restore r5 + LDD -120(%sp),%r4 ; restore r4 + BVE (%rp) + LDD,MB -128(%sp),%r3 ; restore r3 + .PROCEND ;in=23,24,25,26,29;out=28; + +;---------------------------------------------------------------------------- +; +;BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) +; +; arg0 = rp +; arg1 = ap +; arg2 = num +; arg3 = w + +bn_mul_words + .proc + .callinfo frame=128 + .entry + .EXPORT bn_mul_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .align 64 + + STD %r3,0(%sp) ; save r3 + STD %r4,8(%sp) ; save r4 + STD %r5,16(%sp) ; save r5 + STD %r6,24(%sp) ; save r6 + + STD %r7,32(%sp) ; save r7 + COPY %r0,%ret0 ; return 0 by default + DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32 + STD w,56(%sp) ; w on stack + + CMPIB,>= 0,num,bn_mul_words_exit + LDO 128(%sp),%sp ; bump stack + + ; + ; See if only 1 word to do, thus just do cleanup + ; + CMPIB,= 1,num,bn_mul_words_single_top + FLDD -72(%sp),fw ; load up w into fp register fw (fw_h/fw_l) + + ; + ; This loop is unrolled 2 times (64-byte aligned as well) + ; + ; PA-RISC 2.0 chips have two fully pipelined multipliers, thus + ; two 32-bit mutiplies can be issued per cycle. + ; +bn_mul_words_unroll2 + + FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R) + FLDD 8(a_ptr),t_float_1 ; load up 64-bit value (fr8L) ht(L)/lt(R) + XMPYU fht_0,fw_l,fm1 ; m1[0] = fht_0*fw_l + XMPYU fht_1,fw_l,fm1_1 ; m1[1] = ht*fw_l + + FSTD fm1,-16(%sp) ; -16(sp) = m1 + FSTD fm1_1,-48(%sp) ; -48(sp) = m1 + XMPYU flt_0,fw_h,fm ; m = lt*fw_h + XMPYU flt_1,fw_h,fm_1 ; m = lt*fw_h + + FSTD fm,-8(%sp) ; -8(sp) = m + FSTD fm_1,-40(%sp) ; -40(sp) = m + XMPYU fht_0,fw_h,ht_temp ; ht_temp = fht_0*fw_h + XMPYU fht_1,fw_h,ht_temp_1 ; ht_temp = ht*fw_h + + FSTD ht_temp,-24(%sp) ; -24(sp) = ht + FSTD ht_temp_1,-56(%sp) ; -56(sp) = ht + XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l + XMPYU flt_1,fw_l,lt_temp_1 ; lt_temp = lt*fw_l + + FSTD lt_temp,-32(%sp) ; -32(sp) = lt + FSTD lt_temp_1,-64(%sp) ; -64(sp) = lt + LDD -8(%sp),m_0 + LDD -40(%sp),m_1 + + LDD -16(%sp),m1_0 + LDD -48(%sp),m1_1 + LDD -24(%sp),ht_0 + LDD -56(%sp),ht_1 + + ADD,L m1_0,m_0,tmp_0 ; tmp_0 = m + m1; + ADD,L m1_1,m_1,tmp_1 ; tmp_1 = m + m1; + LDD -32(%sp),lt_0 + LDD -64(%sp),lt_1 + + CMPCLR,*>>= tmp_0,m1_0, %r0 ; if (m < m1) + ADD,L ht_0,top_overflow,ht_0 ; ht += (1<<32) + CMPCLR,*>>= tmp_1,m1_1,%r0 ; if (m < m1) + ADD,L ht_1,top_overflow,ht_1 ; ht += (1<<32) + + EXTRD,U tmp_0,31,32,m_0 ; m>>32 + DEPD,Z tmp_0,31,32,m1_0 ; m1 = m<<32 + EXTRD,U tmp_1,31,32,m_1 ; m>>32 + DEPD,Z tmp_1,31,32,m1_1 ; m1 = m<<32 + + ADD,L ht_0,m_0,ht_0 ; ht+= (m>>32) + ADD,L ht_1,m_1,ht_1 ; ht+= (m>>32) + ADD lt_0,m1_0,lt_0 ; lt = lt+m1; + ADD,DC ht_0,%r0,ht_0 ; ht++ + + ADD lt_1,m1_1,lt_1 ; lt = lt+m1; + ADD,DC ht_1,%r0,ht_1 ; ht++ + ADD %ret0,lt_0,lt_0 ; lt = lt + c (ret0); + ADD,DC ht_0,%r0,ht_0 ; ht++ + + ADD ht_0,lt_1,lt_1 ; lt = lt + c (ht_0) + ADD,DC ht_1,%r0,ht_1 ; ht++ + STD lt_0,0(r_ptr) ; rp[0] = lt + STD lt_1,8(r_ptr) ; rp[1] = lt + + COPY ht_1,%ret0 ; carry = ht + LDO -2(num),num ; num = num - 2; + LDO 16(a_ptr),a_ptr ; ap += 2 + CMPIB,<= 2,num,bn_mul_words_unroll2 + LDO 16(r_ptr),r_ptr ; rp++ + + CMPIB,=,N 0,num,bn_mul_words_exit ; are we done? + + ; + ; Top of loop aligned on 64-byte boundary + ; +bn_mul_words_single_top + FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R) + + XMPYU fht_0,fw_l,fm1 ; m1 = ht*fw_l + FSTD fm1,-16(%sp) ; -16(sp) = m1 + XMPYU flt_0,fw_h,fm ; m = lt*fw_h + FSTD fm,-8(%sp) ; -8(sp) = m + XMPYU fht_0,fw_h,ht_temp ; ht_temp = ht*fw_h + FSTD ht_temp,-24(%sp) ; -24(sp) = ht + XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l + FSTD lt_temp,-32(%sp) ; -32(sp) = lt + + LDD -8(%sp),m_0 + LDD -16(%sp),m1_0 + ADD,L m_0,m1_0,tmp_0 ; tmp_0 = m + m1; + LDD -24(%sp),ht_0 + LDD -32(%sp),lt_0 + + CMPCLR,*>>= tmp_0,m1_0,%r0 ; if (m < m1) + ADD,L ht_0,top_overflow,ht_0 ; ht += (1<<32) + + EXTRD,U tmp_0,31,32,m_0 ; m>>32 + DEPD,Z tmp_0,31,32,m1_0 ; m1 = m<<32 + + ADD,L ht_0,m_0,ht_0 ; ht+= (m>>32) + ADD lt_0,m1_0,lt_0 ; lt= lt+m1; + ADD,DC ht_0,%r0,ht_0 ; ht++ + + ADD %ret0,lt_0,lt_0 ; lt = lt + c; + ADD,DC ht_0,%r0,ht_0 ; ht++ + + COPY ht_0,%ret0 ; copy carry + STD lt_0,0(r_ptr) ; rp[0] = lt + +bn_mul_words_exit + .EXIT + LDD -96(%sp),%r7 ; restore r7 + LDD -104(%sp),%r6 ; restore r6 + LDD -112(%sp),%r5 ; restore r5 + LDD -120(%sp),%r4 ; restore r4 + BVE (%rp) + LDD,MB -128(%sp),%r3 ; restore r3 + .PROCEND ;in=23,24,25,26,29;out=28; + +;---------------------------------------------------------------------------- +; +;void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num) +; +; arg0 = rp +; arg1 = ap +; arg2 = num +; + +bn_sqr_words + .proc + .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE + .EXPORT bn_sqr_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .entry + .align 64 + + STD %r3,0(%sp) ; save r3 + STD %r4,8(%sp) ; save r4 + NOP + STD %r5,16(%sp) ; save r5 + + CMPIB,>= 0,num,bn_sqr_words_exit + LDO 128(%sp),%sp ; bump stack + + ; + ; If only 1, the goto straight to cleanup + ; + CMPIB,= 1,num,bn_sqr_words_single_top + DEPDI,Z -1,32,33,high_mask ; Create Mask 0xffffffff80000000L + + ; + ; This loop is unrolled 2 times (64-byte aligned as well) + ; + +bn_sqr_words_unroll2 + FLDD 0(a_ptr),t_float_0 ; a[0] + FLDD 8(a_ptr),t_float_1 ; a[1] + XMPYU fht_0,flt_0,fm ; m[0] + XMPYU fht_1,flt_1,fm_1 ; m[1] + + FSTD fm,-24(%sp) ; store m[0] + FSTD fm_1,-56(%sp) ; store m[1] + XMPYU flt_0,flt_0,lt_temp ; lt[0] + XMPYU flt_1,flt_1,lt_temp_1 ; lt[1] + + FSTD lt_temp,-16(%sp) ; store lt[0] + FSTD lt_temp_1,-48(%sp) ; store lt[1] + XMPYU fht_0,fht_0,ht_temp ; ht[0] + XMPYU fht_1,fht_1,ht_temp_1 ; ht[1] + + FSTD ht_temp,-8(%sp) ; store ht[0] + FSTD ht_temp_1,-40(%sp) ; store ht[1] + LDD -24(%sp),m_0 + LDD -56(%sp),m_1 + + AND m_0,high_mask,tmp_0 ; m[0] & Mask + AND m_1,high_mask,tmp_1 ; m[1] & Mask + DEPD,Z m_0,30,31,m_0 ; m[0] << 32+1 + DEPD,Z m_1,30,31,m_1 ; m[1] << 32+1 + + LDD -16(%sp),lt_0 + LDD -48(%sp),lt_1 + EXTRD,U tmp_0,32,33,tmp_0 ; tmp_0 = m[0]&Mask >> 32-1 + EXTRD,U tmp_1,32,33,tmp_1 ; tmp_1 = m[1]&Mask >> 32-1 + + LDD -8(%sp),ht_0 + LDD -40(%sp),ht_1 + ADD,L ht_0,tmp_0,ht_0 ; ht[0] += tmp_0 + ADD,L ht_1,tmp_1,ht_1 ; ht[1] += tmp_1 + + ADD lt_0,m_0,lt_0 ; lt = lt+m + ADD,DC ht_0,%r0,ht_0 ; ht[0]++ + STD lt_0,0(r_ptr) ; rp[0] = lt[0] + STD ht_0,8(r_ptr) ; rp[1] = ht[1] + + ADD lt_1,m_1,lt_1 ; lt = lt+m + ADD,DC ht_1,%r0,ht_1 ; ht[1]++ + STD lt_1,16(r_ptr) ; rp[2] = lt[1] + STD ht_1,24(r_ptr) ; rp[3] = ht[1] + + LDO -2(num),num ; num = num - 2; + LDO 16(a_ptr),a_ptr ; ap += 2 + CMPIB,<= 2,num,bn_sqr_words_unroll2 + LDO 32(r_ptr),r_ptr ; rp += 4 + + CMPIB,=,N 0,num,bn_sqr_words_exit ; are we done? + + ; + ; Top of loop aligned on 64-byte boundary + ; +bn_sqr_words_single_top + FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R) + + XMPYU fht_0,flt_0,fm ; m + FSTD fm,-24(%sp) ; store m + + XMPYU flt_0,flt_0,lt_temp ; lt + FSTD lt_temp,-16(%sp) ; store lt + + XMPYU fht_0,fht_0,ht_temp ; ht + FSTD ht_temp,-8(%sp) ; store ht + + LDD -24(%sp),m_0 ; load m + AND m_0,high_mask,tmp_0 ; m & Mask + DEPD,Z m_0,30,31,m_0 ; m << 32+1 + LDD -16(%sp),lt_0 ; lt + + LDD -8(%sp),ht_0 ; ht + EXTRD,U tmp_0,32,33,tmp_0 ; tmp_0 = m&Mask >> 32-1 + ADD m_0,lt_0,lt_0 ; lt = lt+m + ADD,L ht_0,tmp_0,ht_0 ; ht += tmp_0 + ADD,DC ht_0,%r0,ht_0 ; ht++ + + STD lt_0,0(r_ptr) ; rp[0] = lt + STD ht_0,8(r_ptr) ; rp[1] = ht + +bn_sqr_words_exit + .EXIT + LDD -112(%sp),%r5 ; restore r5 + LDD -120(%sp),%r4 ; restore r4 + BVE (%rp) + LDD,MB -128(%sp),%r3 + .PROCEND ;in=23,24,25,26,29;out=28; + + +;---------------------------------------------------------------------------- +; +;BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) +; +; arg0 = rp +; arg1 = ap +; arg2 = bp +; arg3 = n + +t .reg %r22 +b .reg %r21 +l .reg %r20 + +bn_add_words + .proc + .entry + .callinfo + .EXPORT bn_add_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .align 64 + + CMPIB,>= 0,n,bn_add_words_exit + COPY %r0,%ret0 ; return 0 by default + + ; + ; If 2 or more numbers do the loop + ; + CMPIB,= 1,n,bn_add_words_single_top + NOP + + ; + ; This loop is unrolled 2 times (64-byte aligned as well) + ; +bn_add_words_unroll2 + LDD 0(a_ptr),t + LDD 0(b_ptr),b + ADD t,%ret0,t ; t = t+c; + ADD,DC %r0,%r0,%ret0 ; set c to carry + ADD t,b,l ; l = t + b[0] + ADD,DC %ret0,%r0,%ret0 ; c+= carry + STD l,0(r_ptr) + + LDD 8(a_ptr),t + LDD 8(b_ptr),b + ADD t,%ret0,t ; t = t+c; + ADD,DC %r0,%r0,%ret0 ; set c to carry + ADD t,b,l ; l = t + b[0] + ADD,DC %ret0,%r0,%ret0 ; c+= carry + STD l,8(r_ptr) + + LDO -2(n),n + LDO 16(a_ptr),a_ptr + LDO 16(b_ptr),b_ptr + + CMPIB,<= 2,n,bn_add_words_unroll2 + LDO 16(r_ptr),r_ptr + + CMPIB,=,N 0,n,bn_add_words_exit ; are we done? + +bn_add_words_single_top + LDD 0(a_ptr),t + LDD 0(b_ptr),b + + ADD t,%ret0,t ; t = t+c; + ADD,DC %r0,%r0,%ret0 ; set c to carry (could use CMPCLR??) + ADD t,b,l ; l = t + b[0] + ADD,DC %ret0,%r0,%ret0 ; c+= carry + STD l,0(r_ptr) + +bn_add_words_exit + .EXIT + BVE (%rp) + NOP + .PROCEND ;in=23,24,25,26,29;out=28; + +;---------------------------------------------------------------------------- +; +;BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) +; +; arg0 = rp +; arg1 = ap +; arg2 = bp +; arg3 = n + +t1 .reg %r22 +t2 .reg %r21 +sub_tmp1 .reg %r20 +sub_tmp2 .reg %r19 + + +bn_sub_words + .proc + .callinfo + .EXPORT bn_sub_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .entry + .align 64 + + CMPIB,>= 0,n,bn_sub_words_exit + COPY %r0,%ret0 ; return 0 by default + + ; + ; If 2 or more numbers do the loop + ; + CMPIB,= 1,n,bn_sub_words_single_top + NOP + + ; + ; This loop is unrolled 2 times (64-byte aligned as well) + ; +bn_sub_words_unroll2 + LDD 0(a_ptr),t1 + LDD 0(b_ptr),t2 + SUB t1,t2,sub_tmp1 ; t3 = t1-t2; + SUB sub_tmp1,%ret0,sub_tmp1 ; t3 = t3- c; + + CMPCLR,*>> t1,t2,sub_tmp2 ; clear if t1 > t2 + LDO 1(%r0),sub_tmp2 + + CMPCLR,*= t1,t2,%r0 + COPY sub_tmp2,%ret0 + STD sub_tmp1,0(r_ptr) + + LDD 8(a_ptr),t1 + LDD 8(b_ptr),t2 + SUB t1,t2,sub_tmp1 ; t3 = t1-t2; + SUB sub_tmp1,%ret0,sub_tmp1 ; t3 = t3- c; + CMPCLR,*>> t1,t2,sub_tmp2 ; clear if t1 > t2 + LDO 1(%r0),sub_tmp2 + + CMPCLR,*= t1,t2,%r0 + COPY sub_tmp2,%ret0 + STD sub_tmp1,8(r_ptr) + + LDO -2(n),n + LDO 16(a_ptr),a_ptr + LDO 16(b_ptr),b_ptr + + CMPIB,<= 2,n,bn_sub_words_unroll2 + LDO 16(r_ptr),r_ptr + + CMPIB,=,N 0,n,bn_sub_words_exit ; are we done? + +bn_sub_words_single_top + LDD 0(a_ptr),t1 + LDD 0(b_ptr),t2 + SUB t1,t2,sub_tmp1 ; t3 = t1-t2; + SUB sub_tmp1,%ret0,sub_tmp1 ; t3 = t3- c; + CMPCLR,*>> t1,t2,sub_tmp2 ; clear if t1 > t2 + LDO 1(%r0),sub_tmp2 + + CMPCLR,*= t1,t2,%r0 + COPY sub_tmp2,%ret0 + + STD sub_tmp1,0(r_ptr) + +bn_sub_words_exit + .EXIT + BVE (%rp) + NOP + .PROCEND ;in=23,24,25,26,29;out=28; + +;------------------------------------------------------------------------------ +; +; unsigned long bn_div_words(unsigned long h, unsigned long l, unsigned long d) +; +; arg0 = h +; arg1 = l +; arg2 = d +; +; This is mainly just modified assembly from the compiler, thus the +; lack of variable names. +; +;------------------------------------------------------------------------------ +bn_div_words + .proc + .callinfo CALLER,FRAME=272,ENTRY_GR=%r10,SAVE_RP,ARGS_SAVED,ORDERING_AWARE + .EXPORT bn_div_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .IMPORT BN_num_bits_word,CODE,NO_RELOCATION + .IMPORT __iob,DATA + .IMPORT fprintf,CODE,NO_RELOCATION + .IMPORT abort,CODE,NO_RELOCATION + .IMPORT $$div2U,MILLICODE + .entry + STD %r2,-16(%r30) + STD,MA %r3,352(%r30) + STD %r4,-344(%r30) + STD %r5,-336(%r30) + STD %r6,-328(%r30) + STD %r7,-320(%r30) + STD %r8,-312(%r30) + STD %r9,-304(%r30) + STD %r10,-296(%r30) + + STD %r27,-288(%r30) ; save gp + + COPY %r24,%r3 ; save d + COPY %r26,%r4 ; save h (high 64-bits) + LDO -1(%r0),%ret0 ; return -1 by default + + CMPB,*= %r0,%arg2,$D3 ; if (d == 0) + COPY %r25,%r5 ; save l (low 64-bits) + + LDO -48(%r30),%r29 ; create ap + .CALL ;in=26,29;out=28; + B,L BN_num_bits_word,%r2 + COPY %r3,%r26 + LDD -288(%r30),%r27 ; restore gp + LDI 64,%r21 + + CMPB,= %r21,%ret0,$00000012 ;if (i == 64) (forward) + COPY %ret0,%r24 ; i + MTSARCM %r24 + DEPDI,Z -1,%sar,1,%r29 + CMPB,*<<,N %r29,%r4,bn_div_err_case ; if (h > 1<= d) + SUB %r4,%r3,%r4 ; h -= d + CMPB,= %r31,%r0,$0000001A ; if (i) + COPY %r0,%r10 ; ret = 0 + MTSARCM %r31 ; i to shift + DEPD,Z %r3,%sar,64,%r3 ; d <<= i; + SUBI 64,%r31,%r19 ; 64 - i; redundent + MTSAR %r19 ; (64 -i) to shift + SHRPD %r4,%r5,%sar,%r4 ; l>> (64-i) + MTSARCM %r31 ; i to shift + DEPD,Z %r5,%sar,64,%r5 ; l <<= i; + +$0000001A + DEPDI,Z -1,31,32,%r19 + EXTRD,U %r3,31,32,%r6 ; dh=(d&0xfff)>>32 + EXTRD,U %r3,63,32,%r8 ; dl = d&0xffffff + LDO 2(%r0),%r9 + STD %r3,-280(%r30) ; "d" to stack + +$0000001C + DEPDI,Z -1,63,32,%r29 ; + EXTRD,U %r4,31,32,%r31 ; h >> 32 + CMPB,*=,N %r31,%r6,$D2 ; if ((h>>32) != dh)(forward) div + COPY %r4,%r26 + EXTRD,U %r4,31,32,%r25 + COPY %r6,%r24 + .CALL ;in=23,24,25,26;out=20,21,22,28,29; (MILLICALL) + B,L $$div2U,%r2 + EXTRD,U %r6,31,32,%r23 + DEPD %r28,31,32,%r29 +$D2 + STD %r29,-272(%r30) ; q + AND %r5,%r19,%r24 ; t & 0xffffffff00000000; + EXTRD,U %r24,31,32,%r24 ; ??? + FLDD -272(%r30),%fr7 ; q + FLDD -280(%r30),%fr8 ; d + XMPYU %fr8L,%fr7L,%fr10 + FSTD %fr10,-256(%r30) + XMPYU %fr8L,%fr7R,%fr22 + FSTD %fr22,-264(%r30) + XMPYU %fr8R,%fr7L,%fr11 + XMPYU %fr8R,%fr7R,%fr23 + FSTD %fr11,-232(%r30) + FSTD %fr23,-240(%r30) + LDD -256(%r30),%r28 + DEPD,Z %r28,31,32,%r2 + LDD -264(%r30),%r20 + ADD,L %r20,%r2,%r31 + LDD -232(%r30),%r22 + DEPD,Z %r22,31,32,%r22 + LDD -240(%r30),%r21 + B $00000024 ; enter loop + ADD,L %r21,%r22,%r23 + +$0000002A + LDO -1(%r29),%r29 + SUB %r23,%r8,%r23 +$00000024 + SUB %r4,%r31,%r25 + AND %r25,%r19,%r26 + CMPB,*<>,N %r0,%r26,$00000046 ; (forward) + DEPD,Z %r25,31,32,%r20 + OR %r20,%r24,%r21 + CMPB,*<<,N %r21,%r23,$0000002A ;(backward) + SUB %r31,%r6,%r31 +;-------------Break path--------------------- + +$00000046 + DEPD,Z %r23,31,32,%r25 ;tl + EXTRD,U %r23,31,32,%r26 ;t + AND %r25,%r19,%r24 ;tl = (tl<<32)&0xfffffff0000000L + ADD,L %r31,%r26,%r31 ;th += t; + CMPCLR,*>>= %r5,%r24,%r0 ;if (l>32)); + DEPD,Z %r29,31,32,%r10 ; ret = q<<32 + b $0000001C + DEPD,Z %r28,31,32,%r5 ; l = l << 32 + +$D1 + OR %r10,%r29,%r28 ; ret |= q +$D3 + LDD -368(%r30),%r2 +$D0 + LDD -296(%r30),%r10 + LDD -304(%r30),%r9 + LDD -312(%r30),%r8 + LDD -320(%r30),%r7 + LDD -328(%r30),%r6 + LDD -336(%r30),%r5 + LDD -344(%r30),%r4 + BVE (%r2) + .EXIT + LDD,MB -352(%r30),%r3 + +bn_div_err_case + MFIA %r6 + ADDIL L'bn_div_words-bn_div_err_case,%r6,%r1 + LDO R'bn_div_words-bn_div_err_case(%r1),%r6 + ADDIL LT'__iob,%r27,%r1 + LDD RT'__iob(%r1),%r26 + ADDIL L'C$4-bn_div_words,%r6,%r1 + LDO R'C$4-bn_div_words(%r1),%r25 + LDO 64(%r26),%r26 + .CALL ;in=24,25,26,29;out=28; + B,L fprintf,%r2 + LDO -48(%r30),%r29 + LDD -288(%r30),%r27 + .CALL ;in=29; + B,L abort,%r2 + LDO -48(%r30),%r29 + LDD -288(%r30),%r27 + B $D0 + LDD -368(%r30),%r2 + .PROCEND ;in=24,25,26,29;out=28; + +;---------------------------------------------------------------------------- +; +; Registers to hold 64-bit values to manipulate. The "L" part +; of the register corresponds to the upper 32-bits, while the "R" +; part corresponds to the lower 32-bits +; +; Note, that when using b6 and b7, the code must save these before +; using them because they are callee save registers +; +; +; Floating point registers to use to save values that +; are manipulated. These don't collide with ftemp1-6 and +; are all caller save registers +; +a0 .reg %fr22 +a0L .reg %fr22L +a0R .reg %fr22R + +a1 .reg %fr23 +a1L .reg %fr23L +a1R .reg %fr23R + +a2 .reg %fr24 +a2L .reg %fr24L +a2R .reg %fr24R + +a3 .reg %fr25 +a3L .reg %fr25L +a3R .reg %fr25R + +a4 .reg %fr26 +a4L .reg %fr26L +a4R .reg %fr26R + +a5 .reg %fr27 +a5L .reg %fr27L +a5R .reg %fr27R + +a6 .reg %fr28 +a6L .reg %fr28L +a6R .reg %fr28R + +a7 .reg %fr29 +a7L .reg %fr29L +a7R .reg %fr29R + +b0 .reg %fr30 +b0L .reg %fr30L +b0R .reg %fr30R + +b1 .reg %fr31 +b1L .reg %fr31L +b1R .reg %fr31R + +; +; Temporary floating point variables, these are all caller save +; registers +; +ftemp1 .reg %fr4 +ftemp2 .reg %fr5 +ftemp3 .reg %fr6 +ftemp4 .reg %fr7 + +; +; The B set of registers when used. +; + +b2 .reg %fr8 +b2L .reg %fr8L +b2R .reg %fr8R + +b3 .reg %fr9 +b3L .reg %fr9L +b3R .reg %fr9R + +b4 .reg %fr10 +b4L .reg %fr10L +b4R .reg %fr10R + +b5 .reg %fr11 +b5L .reg %fr11L +b5R .reg %fr11R + +b6 .reg %fr12 +b6L .reg %fr12L +b6R .reg %fr12R + +b7 .reg %fr13 +b7L .reg %fr13L +b7R .reg %fr13R + +c1 .reg %r21 ; only reg +temp1 .reg %r20 ; only reg +temp2 .reg %r19 ; only reg +temp3 .reg %r31 ; only reg + +m1 .reg %r28 +c2 .reg %r23 +high_one .reg %r1 +ht .reg %r6 +lt .reg %r5 +m .reg %r4 +c3 .reg %r3 + +SQR_ADD_C .macro A0L,A0R,C1,C2,C3 + XMPYU A0L,A0R,ftemp1 ; m + FSTD ftemp1,-24(%sp) ; store m + + XMPYU A0R,A0R,ftemp2 ; lt + FSTD ftemp2,-16(%sp) ; store lt + + XMPYU A0L,A0L,ftemp3 ; ht + FSTD ftemp3,-8(%sp) ; store ht + + LDD -24(%sp),m ; load m + AND m,high_mask,temp2 ; m & Mask + DEPD,Z m,30,31,temp3 ; m << 32+1 + LDD -16(%sp),lt ; lt + + LDD -8(%sp),ht ; ht + EXTRD,U temp2,32,33,temp1 ; temp1 = m&Mask >> 32-1 + ADD temp3,lt,lt ; lt = lt+m + ADD,L ht,temp1,ht ; ht += temp1 + ADD,DC ht,%r0,ht ; ht++ + + ADD C1,lt,C1 ; c1=c1+lt + ADD,DC ht,%r0,ht ; ht++ + + ADD C2,ht,C2 ; c2=c2+ht + ADD,DC C3,%r0,C3 ; c3++ +.endm + +SQR_ADD_C2 .macro A0L,A0R,A1L,A1R,C1,C2,C3 + XMPYU A0L,A1R,ftemp1 ; m1 = bl*ht + FSTD ftemp1,-16(%sp) ; + XMPYU A0R,A1L,ftemp2 ; m = bh*lt + FSTD ftemp2,-8(%sp) ; + XMPYU A0R,A1R,ftemp3 ; lt = bl*lt + FSTD ftemp3,-32(%sp) + XMPYU A0L,A1L,ftemp4 ; ht = bh*ht + FSTD ftemp4,-24(%sp) ; + + LDD -8(%sp),m ; r21 = m + LDD -16(%sp),m1 ; r19 = m1 + ADD,L m,m1,m ; m+m1 + + DEPD,Z m,31,32,temp3 ; (m+m1<<32) + LDD -24(%sp),ht ; r24 = ht + + CMPCLR,*>>= m,m1,%r0 ; if (m < m1) + ADD,L ht,high_one,ht ; ht+=high_one + + EXTRD,U m,31,32,temp1 ; m >> 32 + LDD -32(%sp),lt ; lt + ADD,L ht,temp1,ht ; ht+= m>>32 + ADD lt,temp3,lt ; lt = lt+m1 + ADD,DC ht,%r0,ht ; ht++ + + ADD ht,ht,ht ; ht=ht+ht; + ADD,DC C3,%r0,C3 ; add in carry (c3++) + + ADD lt,lt,lt ; lt=lt+lt; + ADD,DC ht,%r0,ht ; add in carry (ht++) + + ADD C1,lt,C1 ; c1=c1+lt + ADD,DC,*NUV ht,%r0,ht ; add in carry (ht++) + LDO 1(C3),C3 ; bump c3 if overflow,nullify otherwise + + ADD C2,ht,C2 ; c2 = c2 + ht + ADD,DC C3,%r0,C3 ; add in carry (c3++) +.endm + +; +;void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a) +; arg0 = r_ptr +; arg1 = a_ptr +; + +bn_sqr_comba8 + .PROC + .CALLINFO FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE + .EXPORT bn_sqr_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .ENTRY + .align 64 + + STD %r3,0(%sp) ; save r3 + STD %r4,8(%sp) ; save r4 + STD %r5,16(%sp) ; save r5 + STD %r6,24(%sp) ; save r6 + + ; + ; Zero out carries + ; + COPY %r0,c1 + COPY %r0,c2 + COPY %r0,c3 + + LDO 128(%sp),%sp ; bump stack + DEPDI,Z -1,32,33,high_mask ; Create Mask 0xffffffff80000000L + DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32 + + ; + ; Load up all of the values we are going to use + ; + FLDD 0(a_ptr),a0 + FLDD 8(a_ptr),a1 + FLDD 16(a_ptr),a2 + FLDD 24(a_ptr),a3 + FLDD 32(a_ptr),a4 + FLDD 40(a_ptr),a5 + FLDD 48(a_ptr),a6 + FLDD 56(a_ptr),a7 + + SQR_ADD_C a0L,a0R,c1,c2,c3 + STD c1,0(r_ptr) ; r[0] = c1; + COPY %r0,c1 + + SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1 + STD c2,8(r_ptr) ; r[1] = c2; + COPY %r0,c2 + + SQR_ADD_C a1L,a1R,c3,c1,c2 + SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2 + STD c3,16(r_ptr) ; r[2] = c3; + COPY %r0,c3 + + SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3 + SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3 + STD c1,24(r_ptr) ; r[3] = c1; + COPY %r0,c1 + + SQR_ADD_C a2L,a2R,c2,c3,c1 + SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1 + SQR_ADD_C2 a4L,a4R,a0L,a0R,c2,c3,c1 + STD c2,32(r_ptr) ; r[4] = c2; + COPY %r0,c2 + + SQR_ADD_C2 a5L,a5R,a0L,a0R,c3,c1,c2 + SQR_ADD_C2 a4L,a4R,a1L,a1R,c3,c1,c2 + SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2 + STD c3,40(r_ptr) ; r[5] = c3; + COPY %r0,c3 + + SQR_ADD_C a3L,a3R,c1,c2,c3 + SQR_ADD_C2 a4L,a4R,a2L,a2R,c1,c2,c3 + SQR_ADD_C2 a5L,a5R,a1L,a1R,c1,c2,c3 + SQR_ADD_C2 a6L,a6R,a0L,a0R,c1,c2,c3 + STD c1,48(r_ptr) ; r[6] = c1; + COPY %r0,c1 + + SQR_ADD_C2 a7L,a7R,a0L,a0R,c2,c3,c1 + SQR_ADD_C2 a6L,a6R,a1L,a1R,c2,c3,c1 + SQR_ADD_C2 a5L,a5R,a2L,a2R,c2,c3,c1 + SQR_ADD_C2 a4L,a4R,a3L,a3R,c2,c3,c1 + STD c2,56(r_ptr) ; r[7] = c2; + COPY %r0,c2 + + SQR_ADD_C a4L,a4R,c3,c1,c2 + SQR_ADD_C2 a5L,a5R,a3L,a3R,c3,c1,c2 + SQR_ADD_C2 a6L,a6R,a2L,a2R,c3,c1,c2 + SQR_ADD_C2 a7L,a7R,a1L,a1R,c3,c1,c2 + STD c3,64(r_ptr) ; r[8] = c3; + COPY %r0,c3 + + SQR_ADD_C2 a7L,a7R,a2L,a2R,c1,c2,c3 + SQR_ADD_C2 a6L,a6R,a3L,a3R,c1,c2,c3 + SQR_ADD_C2 a5L,a5R,a4L,a4R,c1,c2,c3 + STD c1,72(r_ptr) ; r[9] = c1; + COPY %r0,c1 + + SQR_ADD_C a5L,a5R,c2,c3,c1 + SQR_ADD_C2 a6L,a6R,a4L,a4R,c2,c3,c1 + SQR_ADD_C2 a7L,a7R,a3L,a3R,c2,c3,c1 + STD c2,80(r_ptr) ; r[10] = c2; + COPY %r0,c2 + + SQR_ADD_C2 a7L,a7R,a4L,a4R,c3,c1,c2 + SQR_ADD_C2 a6L,a6R,a5L,a5R,c3,c1,c2 + STD c3,88(r_ptr) ; r[11] = c3; + COPY %r0,c3 + + SQR_ADD_C a6L,a6R,c1,c2,c3 + SQR_ADD_C2 a7L,a7R,a5L,a5R,c1,c2,c3 + STD c1,96(r_ptr) ; r[12] = c1; + COPY %r0,c1 + + SQR_ADD_C2 a7L,a7R,a6L,a6R,c2,c3,c1 + STD c2,104(r_ptr) ; r[13] = c2; + COPY %r0,c2 + + SQR_ADD_C a7L,a7R,c3,c1,c2 + STD c3, 112(r_ptr) ; r[14] = c3 + STD c1, 120(r_ptr) ; r[15] = c1 + + .EXIT + LDD -104(%sp),%r6 ; restore r6 + LDD -112(%sp),%r5 ; restore r5 + LDD -120(%sp),%r4 ; restore r4 + BVE (%rp) + LDD,MB -128(%sp),%r3 + + .PROCEND + +;----------------------------------------------------------------------------- +; +;void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a) +; arg0 = r_ptr +; arg1 = a_ptr +; + +bn_sqr_comba4 + .proc + .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE + .EXPORT bn_sqr_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .entry + .align 64 + STD %r3,0(%sp) ; save r3 + STD %r4,8(%sp) ; save r4 + STD %r5,16(%sp) ; save r5 + STD %r6,24(%sp) ; save r6 + + ; + ; Zero out carries + ; + COPY %r0,c1 + COPY %r0,c2 + COPY %r0,c3 + + LDO 128(%sp),%sp ; bump stack + DEPDI,Z -1,32,33,high_mask ; Create Mask 0xffffffff80000000L + DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32 + + ; + ; Load up all of the values we are going to use + ; + FLDD 0(a_ptr),a0 + FLDD 8(a_ptr),a1 + FLDD 16(a_ptr),a2 + FLDD 24(a_ptr),a3 + FLDD 32(a_ptr),a4 + FLDD 40(a_ptr),a5 + FLDD 48(a_ptr),a6 + FLDD 56(a_ptr),a7 + + SQR_ADD_C a0L,a0R,c1,c2,c3 + + STD c1,0(r_ptr) ; r[0] = c1; + COPY %r0,c1 + + SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1 + + STD c2,8(r_ptr) ; r[1] = c2; + COPY %r0,c2 + + SQR_ADD_C a1L,a1R,c3,c1,c2 + SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2 + + STD c3,16(r_ptr) ; r[2] = c3; + COPY %r0,c3 + + SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3 + SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3 + + STD c1,24(r_ptr) ; r[3] = c1; + COPY %r0,c1 + + SQR_ADD_C a2L,a2R,c2,c3,c1 + SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1 + + STD c2,32(r_ptr) ; r[4] = c2; + COPY %r0,c2 + + SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2 + STD c3,40(r_ptr) ; r[5] = c3; + COPY %r0,c3 + + SQR_ADD_C a3L,a3R,c1,c2,c3 + STD c1,48(r_ptr) ; r[6] = c1; + STD c2,56(r_ptr) ; r[7] = c2; + + .EXIT + LDD -104(%sp),%r6 ; restore r6 + LDD -112(%sp),%r5 ; restore r5 + LDD -120(%sp),%r4 ; restore r4 + BVE (%rp) + LDD,MB -128(%sp),%r3 + + .PROCEND + + +;--------------------------------------------------------------------------- + +MUL_ADD_C .macro A0L,A0R,B0L,B0R,C1,C2,C3 + XMPYU A0L,B0R,ftemp1 ; m1 = bl*ht + FSTD ftemp1,-16(%sp) ; + XMPYU A0R,B0L,ftemp2 ; m = bh*lt + FSTD ftemp2,-8(%sp) ; + XMPYU A0R,B0R,ftemp3 ; lt = bl*lt + FSTD ftemp3,-32(%sp) + XMPYU A0L,B0L,ftemp4 ; ht = bh*ht + FSTD ftemp4,-24(%sp) ; + + LDD -8(%sp),m ; r21 = m + LDD -16(%sp),m1 ; r19 = m1 + ADD,L m,m1,m ; m+m1 + + DEPD,Z m,31,32,temp3 ; (m+m1<<32) + LDD -24(%sp),ht ; r24 = ht + + CMPCLR,*>>= m,m1,%r0 ; if (m < m1) + ADD,L ht,high_one,ht ; ht+=high_one + + EXTRD,U m,31,32,temp1 ; m >> 32 + LDD -32(%sp),lt ; lt + ADD,L ht,temp1,ht ; ht+= m>>32 + ADD lt,temp3,lt ; lt = lt+m1 + ADD,DC ht,%r0,ht ; ht++ + + ADD C1,lt,C1 ; c1=c1+lt + ADD,DC ht,%r0,ht ; bump c3 if overflow,nullify otherwise + + ADD C2,ht,C2 ; c2 = c2 + ht + ADD,DC C3,%r0,C3 ; add in carry (c3++) +.endm + + +; +;void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) +; arg0 = r_ptr +; arg1 = a_ptr +; arg2 = b_ptr +; + +bn_mul_comba8 + .proc + .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE + .EXPORT bn_mul_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .entry + .align 64 + + STD %r3,0(%sp) ; save r3 + STD %r4,8(%sp) ; save r4 + STD %r5,16(%sp) ; save r5 + STD %r6,24(%sp) ; save r6 + FSTD %fr12,32(%sp) ; save r6 + FSTD %fr13,40(%sp) ; save r7 + + ; + ; Zero out carries + ; + COPY %r0,c1 + COPY %r0,c2 + COPY %r0,c3 + + LDO 128(%sp),%sp ; bump stack + DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32 + + ; + ; Load up all of the values we are going to use + ; + FLDD 0(a_ptr),a0 + FLDD 8(a_ptr),a1 + FLDD 16(a_ptr),a2 + FLDD 24(a_ptr),a3 + FLDD 32(a_ptr),a4 + FLDD 40(a_ptr),a5 + FLDD 48(a_ptr),a6 + FLDD 56(a_ptr),a7 + + FLDD 0(b_ptr),b0 + FLDD 8(b_ptr),b1 + FLDD 16(b_ptr),b2 + FLDD 24(b_ptr),b3 + FLDD 32(b_ptr),b4 + FLDD 40(b_ptr),b5 + FLDD 48(b_ptr),b6 + FLDD 56(b_ptr),b7 + + MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3 + STD c1,0(r_ptr) + COPY %r0,c1 + + MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1 + MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1 + STD c2,8(r_ptr) + COPY %r0,c2 + + MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2 + MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2 + MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2 + STD c3,16(r_ptr) + COPY %r0,c3 + + MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3 + MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3 + MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3 + MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3 + STD c1,24(r_ptr) + COPY %r0,c1 + + MUL_ADD_C a4L,a4R,b0L,b0R,c2,c3,c1 + MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1 + MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1 + MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1 + MUL_ADD_C a0L,a0R,b4L,b4R,c2,c3,c1 + STD c2,32(r_ptr) + COPY %r0,c2 + + MUL_ADD_C a0L,a0R,b5L,b5R,c3,c1,c2 + MUL_ADD_C a1L,a1R,b4L,b4R,c3,c1,c2 + MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2 + MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2 + MUL_ADD_C a4L,a4R,b1L,b1R,c3,c1,c2 + MUL_ADD_C a5L,a5R,b0L,b0R,c3,c1,c2 + STD c3,40(r_ptr) + COPY %r0,c3 + + MUL_ADD_C a6L,a6R,b0L,b0R,c1,c2,c3 + MUL_ADD_C a5L,a5R,b1L,b1R,c1,c2,c3 + MUL_ADD_C a4L,a4R,b2L,b2R,c1,c2,c3 + MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3 + MUL_ADD_C a2L,a2R,b4L,b4R,c1,c2,c3 + MUL_ADD_C a1L,a1R,b5L,b5R,c1,c2,c3 + MUL_ADD_C a0L,a0R,b6L,b6R,c1,c2,c3 + STD c1,48(r_ptr) + COPY %r0,c1 + + MUL_ADD_C a0L,a0R,b7L,b7R,c2,c3,c1 + MUL_ADD_C a1L,a1R,b6L,b6R,c2,c3,c1 + MUL_ADD_C a2L,a2R,b5L,b5R,c2,c3,c1 + MUL_ADD_C a3L,a3R,b4L,b4R,c2,c3,c1 + MUL_ADD_C a4L,a4R,b3L,b3R,c2,c3,c1 + MUL_ADD_C a5L,a5R,b2L,b2R,c2,c3,c1 + MUL_ADD_C a6L,a6R,b1L,b1R,c2,c3,c1 + MUL_ADD_C a7L,a7R,b0L,b0R,c2,c3,c1 + STD c2,56(r_ptr) + COPY %r0,c2 + + MUL_ADD_C a7L,a7R,b1L,b1R,c3,c1,c2 + MUL_ADD_C a6L,a6R,b2L,b2R,c3,c1,c2 + MUL_ADD_C a5L,a5R,b3L,b3R,c3,c1,c2 + MUL_ADD_C a4L,a4R,b4L,b4R,c3,c1,c2 + MUL_ADD_C a3L,a3R,b5L,b5R,c3,c1,c2 + MUL_ADD_C a2L,a2R,b6L,b6R,c3,c1,c2 + MUL_ADD_C a1L,a1R,b7L,b7R,c3,c1,c2 + STD c3,64(r_ptr) + COPY %r0,c3 + + MUL_ADD_C a2L,a2R,b7L,b7R,c1,c2,c3 + MUL_ADD_C a3L,a3R,b6L,b6R,c1,c2,c3 + MUL_ADD_C a4L,a4R,b5L,b5R,c1,c2,c3 + MUL_ADD_C a5L,a5R,b4L,b4R,c1,c2,c3 + MUL_ADD_C a6L,a6R,b3L,b3R,c1,c2,c3 + MUL_ADD_C a7L,a7R,b2L,b2R,c1,c2,c3 + STD c1,72(r_ptr) + COPY %r0,c1 + + MUL_ADD_C a7L,a7R,b3L,b3R,c2,c3,c1 + MUL_ADD_C a6L,a6R,b4L,b4R,c2,c3,c1 + MUL_ADD_C a5L,a5R,b5L,b5R,c2,c3,c1 + MUL_ADD_C a4L,a4R,b6L,b6R,c2,c3,c1 + MUL_ADD_C a3L,a3R,b7L,b7R,c2,c3,c1 + STD c2,80(r_ptr) + COPY %r0,c2 + + MUL_ADD_C a4L,a4R,b7L,b7R,c3,c1,c2 + MUL_ADD_C a5L,a5R,b6L,b6R,c3,c1,c2 + MUL_ADD_C a6L,a6R,b5L,b5R,c3,c1,c2 + MUL_ADD_C a7L,a7R,b4L,b4R,c3,c1,c2 + STD c3,88(r_ptr) + COPY %r0,c3 + + MUL_ADD_C a7L,a7R,b5L,b5R,c1,c2,c3 + MUL_ADD_C a6L,a6R,b6L,b6R,c1,c2,c3 + MUL_ADD_C a5L,a5R,b7L,b7R,c1,c2,c3 + STD c1,96(r_ptr) + COPY %r0,c1 + + MUL_ADD_C a6L,a6R,b7L,b7R,c2,c3,c1 + MUL_ADD_C a7L,a7R,b6L,b6R,c2,c3,c1 + STD c2,104(r_ptr) + COPY %r0,c2 + + MUL_ADD_C a7L,a7R,b7L,b7R,c3,c1,c2 + STD c3,112(r_ptr) + STD c1,120(r_ptr) + + .EXIT + FLDD -88(%sp),%fr13 + FLDD -96(%sp),%fr12 + LDD -104(%sp),%r6 ; restore r6 + LDD -112(%sp),%r5 ; restore r5 + LDD -120(%sp),%r4 ; restore r4 + BVE (%rp) + LDD,MB -128(%sp),%r3 + + .PROCEND + +;----------------------------------------------------------------------------- +; +;void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) +; arg0 = r_ptr +; arg1 = a_ptr +; arg2 = b_ptr +; + +bn_mul_comba4 + .proc + .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE + .EXPORT bn_mul_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .entry + .align 64 + + STD %r3,0(%sp) ; save r3 + STD %r4,8(%sp) ; save r4 + STD %r5,16(%sp) ; save r5 + STD %r6,24(%sp) ; save r6 + FSTD %fr12,32(%sp) ; save r6 + FSTD %fr13,40(%sp) ; save r7 + + ; + ; Zero out carries + ; + COPY %r0,c1 + COPY %r0,c2 + COPY %r0,c3 + + LDO 128(%sp),%sp ; bump stack + DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32 + + ; + ; Load up all of the values we are going to use + ; + FLDD 0(a_ptr),a0 + FLDD 8(a_ptr),a1 + FLDD 16(a_ptr),a2 + FLDD 24(a_ptr),a3 + + FLDD 0(b_ptr),b0 + FLDD 8(b_ptr),b1 + FLDD 16(b_ptr),b2 + FLDD 24(b_ptr),b3 + + MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3 + STD c1,0(r_ptr) + COPY %r0,c1 + + MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1 + MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1 + STD c2,8(r_ptr) + COPY %r0,c2 + + MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2 + MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2 + MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2 + STD c3,16(r_ptr) + COPY %r0,c3 + + MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3 + MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3 + MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3 + MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3 + STD c1,24(r_ptr) + COPY %r0,c1 + + MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1 + MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1 + MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1 + STD c2,32(r_ptr) + COPY %r0,c2 + + MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2 + MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2 + STD c3,40(r_ptr) + COPY %r0,c3 + + MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3 + STD c1,48(r_ptr) + STD c2,56(r_ptr) + + .EXIT + FLDD -88(%sp),%fr13 + FLDD -96(%sp),%fr12 + LDD -104(%sp),%r6 ; restore r6 + LDD -112(%sp),%r5 ; restore r5 + LDD -120(%sp),%r4 ; restore r4 + BVE (%rp) + LDD,MB -128(%sp),%r3 + + .PROCEND + + + .SPACE $TEXT$ + .SUBSPA $CODE$ + .SPACE $PRIVATE$,SORT=16 + .IMPORT $global$,DATA + .SPACE $TEXT$ + .SUBSPA $CODE$ + .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=0x2c,SORT=16 +C$4 + .ALIGN 8 + .STRINGZ "Division would overflow (%d)\n" + .END diff --git a/lib/libssl/src/crypto/conf/conf_api.c b/lib/libssl/src/crypto/conf/conf_api.c new file mode 100644 index 00000000000..d05a778ff6f --- /dev/null +++ b/lib/libssl/src/crypto/conf/conf_api.c @@ -0,0 +1,289 @@ +/* conf_api.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.] + */ + +/* Part of the code in here was originally in conf.c, which is now removed */ + +#ifndef CONF_DEBUG +# undef NDEBUG /* avoid conflicting definitions */ +# define NDEBUG +#endif + +#include +#include +#include +#include + +static void value_free_hash(CONF_VALUE *a, LHASH *conf); +static void value_free_stack(CONF_VALUE *a,LHASH *conf); +static unsigned long hash(CONF_VALUE *v); +static int cmp_conf(CONF_VALUE *a,CONF_VALUE *b); + +/* Up until OpenSSL 0.9.5a, this was get_section */ +CONF_VALUE *_CONF_get_section(CONF *conf, char *section) + { + CONF_VALUE *v,vv; + + if ((conf == NULL) || (section == NULL)) return(NULL); + vv.name=NULL; + vv.section=section; + v=(CONF_VALUE *)lh_retrieve(conf->data,&vv); + return(v); + } + +/* Up until OpenSSL 0.9.5a, this was CONF_get_section */ +STACK_OF(CONF_VALUE) *_CONF_get_section_values(CONF *conf, char *section) + { + CONF_VALUE *v; + + v=_CONF_get_section(conf,section); + if (v != NULL) + return((STACK_OF(CONF_VALUE) *)v->value); + else + return(NULL); + } + +int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value) + { + CONF_VALUE *v = NULL; + STACK_OF(CONF_VALUE) *ts; + + ts = (STACK_OF(CONF_VALUE) *)section->value; + + value->section=section->section; + if (!sk_CONF_VALUE_push(ts,value)) + { + return 0; + } + + v = (CONF_VALUE *)lh_insert(conf->data, value); + if (v != NULL) + { + sk_CONF_VALUE_delete_ptr(ts,v); + OPENSSL_free(v->name); + OPENSSL_free(v->value); + OPENSSL_free(v); + } + return 1; + } + +char *_CONF_get_string(CONF *conf, char *section, char *name) + { + CONF_VALUE *v,vv; + char *p; + + if (name == NULL) return(NULL); + if (conf != NULL) + { + if (section != NULL) + { + vv.name=name; + vv.section=section; + v=(CONF_VALUE *)lh_retrieve(conf->data,&vv); + if (v != NULL) return(v->value); + if (strcmp(section,"ENV") == 0) + { + p=Getenv(name); + if (p != NULL) return(p); + } + } + vv.section="default"; + vv.name=name; + v=(CONF_VALUE *)lh_retrieve(conf->data,&vv); + if (v != NULL) + return(v->value); + else + return(NULL); + } + else + return(Getenv(name)); + } + +long _CONF_get_number(CONF *conf, char *section, char *name) + { + char *str; + long ret=0; + + str=_CONF_get_string(conf,section,name); + if (str == NULL) return(0); + for (;;) + { + if (conf->meth->is_number(conf, *str)) + ret=ret*10+conf->meth->to_int(conf, *str); + else + return(ret); + str++; + } + } + +int _CONF_new_data(CONF *conf) + { + if (conf == NULL) + { + return 0; + } + if (conf->data == NULL) + if ((conf->data = lh_new(hash,cmp_conf)) == NULL) + { + return 0; + } + return 1; + } + +void _CONF_free_data(CONF *conf) + { + if (conf == NULL || conf->data == NULL) return; + + conf->data->down_load=0; /* evil thing to make sure the 'OPENSSL_free()' + * works as expected */ + lh_doall_arg(conf->data,(void (*)())value_free_hash,conf->data); + + /* We now have only 'section' entries in the hash table. + * Due to problems with */ + + lh_doall_arg(conf->data,(void (*)())value_free_stack,conf->data); + lh_free(conf->data); + } + +static void value_free_hash(CONF_VALUE *a, LHASH *conf) + { + if (a->name != NULL) + { + a=(CONF_VALUE *)lh_delete(conf,a); + } + } + +static void value_free_stack(CONF_VALUE *a, LHASH *conf) + { + CONF_VALUE *vv; + STACK *sk; + int i; + + if (a->name != NULL) return; + + sk=(STACK *)a->value; + for (i=sk_num(sk)-1; i>=0; i--) + { + vv=(CONF_VALUE *)sk_value(sk,i); + OPENSSL_free(vv->value); + OPENSSL_free(vv->name); + OPENSSL_free(vv); + } + if (sk != NULL) sk_free(sk); + OPENSSL_free(a->section); + OPENSSL_free(a); + } + +static unsigned long hash(CONF_VALUE *v) + { + return((lh_strhash(v->section)<<2)^lh_strhash(v->name)); + } + +static int cmp_conf(CONF_VALUE *a, CONF_VALUE *b) + { + int i; + + if (a->section != b->section) + { + i=strcmp(a->section,b->section); + if (i) return(i); + } + + if ((a->name != NULL) && (b->name != NULL)) + { + i=strcmp(a->name,b->name); + return(i); + } + else if (a->name == b->name) + return(0); + else + return((a->name == NULL)?-1:1); + } + +/* Up until OpenSSL 0.9.5a, this was new_section */ +CONF_VALUE *_CONF_new_section(CONF *conf, char *section) + { + STACK *sk=NULL; + int ok=0,i; + CONF_VALUE *v=NULL,*vv; + + if ((sk=sk_new_null()) == NULL) + goto err; + if ((v=(CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE))) == NULL) + goto err; + i=strlen(section)+1; + if ((v->section=(char *)OPENSSL_malloc(i)) == NULL) + goto err; + + memcpy(v->section,section,i); + v->name=NULL; + v->value=(char *)sk; + + vv=(CONF_VALUE *)lh_insert(conf->data,v); + assert(vv == NULL); + ok=1; +err: + if (!ok) + { + if (sk != NULL) sk_free(sk); + if (v != NULL) OPENSSL_free(v); + v=NULL; + } + return(v); + } + +IMPLEMENT_STACK_OF(CONF_VALUE) diff --git a/lib/libssl/src/crypto/conf/conf_api.h b/lib/libssl/src/crypto/conf/conf_api.h new file mode 100644 index 00000000000..a5cc17b233a --- /dev/null +++ b/lib/libssl/src/crypto/conf/conf_api.h @@ -0,0 +1,87 @@ +/* conf_api.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CONF_API_H +#define HEADER_CONF_API_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Up until OpenSSL 0.9.5a, this was new_section */ +CONF_VALUE *_CONF_new_section(CONF *conf, char *section); +/* Up until OpenSSL 0.9.5a, this was get_section */ +CONF_VALUE *_CONF_get_section(CONF *conf, char *section); +/* Up until OpenSSL 0.9.5a, this was CONF_get_section */ +STACK_OF(CONF_VALUE) *_CONF_get_section_values(CONF *conf, char *section); + +int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value); +char *_CONF_get_string(CONF *conf, char *section, char *name); +long _CONF_get_number(CONF *conf, char *section, char *name); + +int _CONF_new_data(CONF *conf); +void _CONF_free_data(CONF *conf); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/lib/libssl/src/crypto/conf/conf_def.c b/lib/libssl/src/crypto/conf/conf_def.c new file mode 100644 index 00000000000..773df32c681 --- /dev/null +++ b/lib/libssl/src/crypto/conf/conf_def.c @@ -0,0 +1,703 @@ +/* crypto/conf/conf.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.] + */ + +/* Part of the code in here was originally in conf.c, which is now removed */ + +#include +#include +#include +#include +#include +#include +#include "conf_def.h" +#include +#include + +static char *eat_ws(CONF *conf, char *p); +static char *eat_alpha_numeric(CONF *conf, char *p); +static void clear_comments(CONF *conf, char *p); +static int str_copy(CONF *conf,char *section,char **to, char *from); +static char *scan_quote(CONF *conf, char *p); +static char *scan_dquote(CONF *conf, char *p); +#define scan_esc(conf,p) (((IS_EOF((conf),(p)[1]))?((p)+1):((p)+2))) + +static CONF *def_create(CONF_METHOD *meth); +static int def_init_default(CONF *conf); +static int def_init_WIN32(CONF *conf); +static int def_destroy(CONF *conf); +static int def_destroy_data(CONF *conf); +static int def_load(CONF *conf, BIO *bp, long *eline); +static int def_dump(CONF *conf, BIO *bp); +static int def_is_number(CONF *conf, char c); +static int def_to_int(CONF *conf, char c); + +const char *CONF_def_version="CONF_def" OPENSSL_VERSION_PTEXT; + +static CONF_METHOD default_method = { + "OpenSSL default", + def_create, + def_init_default, + def_destroy, + def_destroy_data, + def_load, + def_dump, + def_is_number, + def_to_int + }; + +static CONF_METHOD WIN32_method = { + "WIN32", + def_create, + def_init_WIN32, + def_destroy, + def_destroy_data, + def_load, + def_dump, + def_is_number, + def_to_int + }; + +CONF_METHOD *NCONF_default() + { + return &default_method; + } +CONF_METHOD *NCONF_WIN32() + { + return &WIN32_method; + } + +static CONF *def_create(CONF_METHOD *meth) + { + CONF *ret; + + ret = (CONF *)OPENSSL_malloc(sizeof(CONF) + sizeof(unsigned short *)); + if (ret) + if (meth->init(ret) == 0) + { + OPENSSL_free(ret); + ret = NULL; + } + return ret; + } + +static int def_init_default(CONF *conf) + { + if (conf == NULL) + return 0; + + conf->meth = &default_method; + conf->meth_data = (void *)CONF_type_default; + conf->data = NULL; + + return 1; + } + +static int def_init_WIN32(CONF *conf) + { + if (conf == NULL) + return 0; + + conf->meth = &WIN32_method; + conf->meth_data = (void *)CONF_type_win32; + conf->data = NULL; + + return 1; + } + +static int def_destroy(CONF *conf) + { + if (def_destroy_data(conf)) + { + OPENSSL_free(conf); + return 1; + } + return 0; + } + +static int def_destroy_data(CONF *conf) + { + if (conf == NULL) + return 0; + _CONF_free_data(conf); + return 1; + } + +static int def_load(CONF *conf, BIO *in, long *line) + { +#define BUFSIZE 512 + char btmp[16]; + int bufnum=0,i,ii; + BUF_MEM *buff=NULL; + char *s,*p,*end; + int again,n; + long eline=0; + CONF_VALUE *v=NULL,*tv; + CONF_VALUE *sv=NULL; + char *section=NULL,*buf; + STACK_OF(CONF_VALUE) *section_sk=NULL,*ts; + char *start,*psection,*pname; + void *h = (void *)(conf->data); + + if ((buff=BUF_MEM_new()) == NULL) + { + CONFerr(CONF_F_CONF_LOAD_BIO,ERR_R_BUF_LIB); + goto err; + } + + section=(char *)OPENSSL_malloc(10); + if (section == NULL) + { + CONFerr(CONF_F_CONF_LOAD_BIO,ERR_R_MALLOC_FAILURE); + goto err; + } + strcpy(section,"default"); + + if (_CONF_new_data(conf) == 0) + { + CONFerr(CONF_F_CONF_LOAD_BIO,ERR_R_MALLOC_FAILURE); + goto err; + } + + sv=_CONF_new_section(conf,section); + if (sv == NULL) + { + CONFerr(CONF_F_CONF_LOAD_BIO, + CONF_R_UNABLE_TO_CREATE_NEW_SECTION); + goto err; + } + section_sk=(STACK_OF(CONF_VALUE) *)sv->value; + + bufnum=0; + for (;;) + { + again=0; + if (!BUF_MEM_grow(buff,bufnum+BUFSIZE)) + { + CONFerr(CONF_F_CONF_LOAD_BIO,ERR_R_BUF_LIB); + goto err; + } + p= &(buff->data[bufnum]); + *p='\0'; + BIO_gets(in, p, BUFSIZE-1); + p[BUFSIZE-1]='\0'; + ii=i=strlen(p); + if (i == 0) break; + while (i > 0) + { + if ((p[i-1] != '\r') && (p[i-1] != '\n')) + break; + else + i--; + } + /* we removed some trailing stuff so there is a new + * line on the end. */ + if (i == ii) + again=1; /* long line */ + else + { + p[i]='\0'; + eline++; /* another input line */ + } + + /* we now have a line with trailing \r\n removed */ + + /* i is the number of bytes */ + bufnum+=i; + + v=NULL; + /* check for line continuation */ + if (bufnum >= 1) + { + /* If we have bytes and the last char '\\' and + * second last char is not '\\' */ + p= &(buff->data[bufnum-1]); + if (IS_ESC(conf,p[0]) && + ((bufnum <= 1) || !IS_ESC(conf,p[-1]))) + { + bufnum--; + again=1; + } + } + if (again) continue; + bufnum=0; + buf=buff->data; + + clear_comments(conf, buf); + n=strlen(buf); + s=eat_ws(conf, buf); + if (IS_EOF(conf,*s)) continue; /* blank line */ + if (*s == '[') + { + char *ss; + + s++; + start=eat_ws(conf, s); + ss=start; +again: + end=eat_alpha_numeric(conf, ss); + p=eat_ws(conf, end); + if (*p != ']') + { + if (*p != '\0') + { + ss=p; + goto again; + } + CONFerr(CONF_F_CONF_LOAD_BIO, + CONF_R_MISSING_CLOSE_SQUARE_BRACKET); + goto err; + } + *end='\0'; + if (!str_copy(conf,NULL,§ion,start)) goto err; + if ((sv=_CONF_get_section(conf,section)) == NULL) + sv=_CONF_new_section(conf,section); + if (sv == NULL) + { + CONFerr(CONF_F_CONF_LOAD_BIO, + CONF_R_UNABLE_TO_CREATE_NEW_SECTION); + goto err; + } + section_sk=(STACK_OF(CONF_VALUE) *)sv->value; + continue; + } + else + { + pname=s; + psection=NULL; + end=eat_alpha_numeric(conf, s); + if ((end[0] == ':') && (end[1] == ':')) + { + *end='\0'; + end+=2; + psection=pname; + pname=end; + end=eat_alpha_numeric(conf, end); + } + p=eat_ws(conf, end); + if (*p != '=') + { + CONFerr(CONF_F_CONF_LOAD_BIO, + CONF_R_MISSING_EQUAL_SIGN); + goto err; + } + *end='\0'; + p++; + start=eat_ws(conf, p); + while (!IS_EOF(conf,*p)) + p++; + p--; + while ((p != start) && (IS_WS(conf,*p))) + p--; + p++; + *p='\0'; + + if (!(v=(CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) + { + CONFerr(CONF_F_CONF_LOAD_BIO, + ERR_R_MALLOC_FAILURE); + goto err; + } + if (psection == NULL) psection=section; + v->name=(char *)OPENSSL_malloc(strlen(pname)+1); + v->value=NULL; + if (v->name == NULL) + { + CONFerr(CONF_F_CONF_LOAD_BIO, + ERR_R_MALLOC_FAILURE); + goto err; + } + strcpy(v->name,pname); + if (!str_copy(conf,psection,&(v->value),start)) goto err; + + if (strcmp(psection,section) != 0) + { + if ((tv=_CONF_get_section(conf,psection)) + == NULL) + tv=_CONF_new_section(conf,psection); + if (tv == NULL) + { + CONFerr(CONF_F_CONF_LOAD_BIO, + CONF_R_UNABLE_TO_CREATE_NEW_SECTION); + goto err; + } + ts=(STACK_OF(CONF_VALUE) *)tv->value; + } + else + { + tv=sv; + ts=section_sk; + } +#if 1 + if (_CONF_add_string(conf, tv, v) == 0) + { + CONFerr(CONF_F_CONF_LOAD_BIO, + ERR_R_MALLOC_FAILURE); + goto err; + } +#else + v->section=tv->section; + if (!sk_CONF_VALUE_push(ts,v)) + { + CONFerr(CONF_F_CONF_LOAD_BIO, + ERR_R_MALLOC_FAILURE); + goto err; + } + vv=(CONF_VALUE *)lh_insert(conf->data,v); + if (vv != NULL) + { + sk_CONF_VALUE_delete_ptr(ts,vv); + OPENSSL_free(vv->name); + OPENSSL_free(vv->value); + OPENSSL_free(vv); + } +#endif + v=NULL; + } + } + if (buff != NULL) BUF_MEM_free(buff); + if (section != NULL) OPENSSL_free(section); + return(1); +err: + if (buff != NULL) BUF_MEM_free(buff); + if (section != NULL) OPENSSL_free(section); + if (line != NULL) *line=eline; + sprintf(btmp,"%ld",eline); + ERR_add_error_data(2,"line ",btmp); + if ((h != conf->data) && (conf->data != NULL)) CONF_free(conf->data); + if (v != NULL) + { + if (v->name != NULL) OPENSSL_free(v->name); + if (v->value != NULL) OPENSSL_free(v->value); + if (v != NULL) OPENSSL_free(v); + } + return(0); + } + +static void clear_comments(CONF *conf, char *p) + { + char *to; + + to=p; + for (;;) + { + if (IS_FCOMMENT(conf,*p)) + { + *p='\0'; + return; + } + if (!IS_WS(conf,*p)) + { + break; + } + p++; + } + + for (;;) + { + if (IS_COMMENT(conf,*p)) + { + *p='\0'; + return; + } + if (IS_DQUOTE(conf,*p)) + { + p=scan_dquote(conf, p); + continue; + } + if (IS_QUOTE(conf,*p)) + { + p=scan_quote(conf, p); + continue; + } + if (IS_ESC(conf,*p)) + { + p=scan_esc(conf,p); + continue; + } + if (IS_EOF(conf,*p)) + return; + else + p++; + } + } + +static int str_copy(CONF *conf, char *section, char **pto, char *from) + { + int q,r,rr=0,to=0,len=0; + char *s,*e,*rp,*p,*rrp,*np,*cp,v; + BUF_MEM *buf; + + if ((buf=BUF_MEM_new()) == NULL) return(0); + + len=strlen(from)+1; + if (!BUF_MEM_grow(buf,len)) goto err; + + for (;;) + { + if (IS_QUOTE(conf,*from)) + { + q= *from; + from++; + while (!IS_EOF(conf,*from) && (*from != q)) + { + if (IS_ESC(conf,*from)) + { + from++; + if (IS_EOF(conf,*from)) break; + } + buf->data[to++]= *(from++); + } + if (*from == q) from++; + } + else if (IS_DQUOTE(conf,*from)) + { + q= *from; + from++; + while (!IS_EOF(conf,*from)) + { + if (*from == q) + { + if (*(from+1) == q) + { + from++; + } + else + { + break; + } + } + buf->data[to++]= *(from++); + } + if (*from == q) from++; + } + else if (IS_ESC(conf,*from)) + { + from++; + v= *(from++); + if (IS_EOF(conf,v)) break; + else if (v == 'r') v='\r'; + else if (v == 'n') v='\n'; + else if (v == 'b') v='\b'; + else if (v == 't') v='\t'; + buf->data[to++]= v; + } + else if (IS_EOF(conf,*from)) + break; + else if (*from == '$') + { + /* try to expand it */ + rrp=NULL; + s= &(from[1]); + if (*s == '{') + q='}'; + else if (*s == '(') + q=')'; + else q=0; + + if (q) s++; + cp=section; + e=np=s; + while (IS_ALPHA_NUMERIC(conf,*e)) + e++; + if ((e[0] == ':') && (e[1] == ':')) + { + cp=np; + rrp=e; + rr= *e; + *rrp='\0'; + e+=2; + np=e; + while (IS_ALPHA_NUMERIC(conf,*e)) + e++; + } + r= *e; + *e='\0'; + rp=e; + if (q) + { + if (r != q) + { + CONFerr(CONF_F_STR_COPY,CONF_R_NO_CLOSE_BRACE); + goto err; + } + e++; + } + /* So at this point we have + * ns which is the start of the name string which is + * '\0' terminated. + * cs which is the start of the section string which is + * '\0' terminated. + * e is the 'next point after'. + * r and s are the chars replaced by the '\0' + * rp and sp is where 'r' and 's' came from. + */ + p=_CONF_get_string(conf,cp,np); + if (rrp != NULL) *rrp=rr; + *rp=r; + if (p == NULL) + { + CONFerr(CONF_F_STR_COPY,CONF_R_VARIABLE_HAS_NO_VALUE); + goto err; + } + BUF_MEM_grow(buf,(strlen(p)+len-(e-from))); + while (*p) + buf->data[to++]= *(p++); + from=e; + } + else + buf->data[to++]= *(from++); + } + buf->data[to]='\0'; + if (*pto != NULL) OPENSSL_free(*pto); + *pto=buf->data; + OPENSSL_free(buf); + return(1); +err: + if (buf != NULL) BUF_MEM_free(buf); + return(0); + } + +static char *eat_ws(CONF *conf, char *p) + { + while (IS_WS(conf,*p) && (!IS_EOF(conf,*p))) + p++; + return(p); + } + +static char *eat_alpha_numeric(CONF *conf, char *p) + { + for (;;) + { + if (IS_ESC(conf,*p)) + { + p=scan_esc(conf,p); + continue; + } + if (!IS_ALPHA_NUMERIC_PUNCT(conf,*p)) + return(p); + p++; + } + } + +static char *scan_quote(CONF *conf, char *p) + { + int q= *p; + + p++; + while (!(IS_EOF(conf,*p)) && (*p != q)) + { + if (IS_ESC(conf,*p)) + { + p++; + if (IS_EOF(conf,*p)) return(p); + } + p++; + } + if (*p == q) p++; + return(p); + } + + +static char *scan_dquote(CONF *conf, char *p) + { + int q= *p; + + p++; + while (!(IS_EOF(conf,*p))) + { + if (*p == q) + { + if (*(p+1) == q) + { + p++; + } + else + { + break; + } + } + p++; + } + if (*p == q) p++; + return(p); + } + +static void dump_value(CONF_VALUE *a, BIO *out) + { + if (a->name) + BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value); + else + BIO_printf(out, "[[%s]]\n", a->section); + } + +static int def_dump(CONF *conf, BIO *out) + { + lh_doall_arg(conf->data, (void (*)())dump_value, out); + return 1; + } + +static int def_is_number(CONF *conf, char c) + { + return IS_NUMBER(conf,c); + } + +static int def_to_int(CONF *conf, char c) + { + return c - '0'; + } + diff --git a/lib/libssl/src/crypto/conf/conf_def.h b/lib/libssl/src/crypto/conf/conf_def.h new file mode 100644 index 00000000000..3244d9a331c --- /dev/null +++ b/lib/libssl/src/crypto/conf/conf_def.h @@ -0,0 +1,145 @@ +/* crypto/conf/conf_def.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.] + */ + +/* THIS FILE WAS AUTOMAGICALLY GENERATED! + Please modify and use keysets.pl to regenerate it. */ + +#define CONF_NUMBER 1 +#define CONF_UPPER 2 +#define CONF_LOWER 4 +#define CONF_UNDER 256 +#define CONF_PUNCTUATION 512 +#define CONF_WS 16 +#define CONF_ESC 32 +#define CONF_QUOTE 64 +#define CONF_DQUOTE 1024 +#define CONF_COMMENT 128 +#define CONF_FCOMMENT 2048 +#define CONF_EOF 8 +#define CONF_ALPHA (CONF_UPPER|CONF_LOWER) +#define CONF_ALPHA_NUMERIC (CONF_ALPHA|CONF_NUMBER|CONF_UNDER) +#define CONF_ALPHA_NUMERIC_PUNCT (CONF_ALPHA|CONF_NUMBER|CONF_UNDER| \ + CONF_PUNCTUATION) + +#define KEYTYPES(c) ((unsigned short *)((c)->meth_data)) +#ifndef CHARSET_EBCDIC +#define IS_COMMENT(c,a) (KEYTYPES(c)[(a)&0x7f]&CONF_COMMENT) +#define IS_FCOMMENT(c,a) (KEYTYPES(c)[(a)&0x7f]&CONF_FCOMMENT) +#define IS_EOF(c,a) (KEYTYPES(c)[(a)&0x7f]&CONF_EOF) +#define IS_ESC(c,a) (KEYTYPES(c)[(a)&0x7f]&CONF_ESC) +#define IS_NUMBER(c,a) (KEYTYPES(c)[(a)&0x7f]&CONF_NUMBER) +#define IS_WS(c,a) (KEYTYPES(c)[(a)&0x7f]&CONF_WS) +#define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[(a)&0x7f]&CONF_ALPHA_NUMERIC) +#define IS_ALPHA_NUMERIC_PUNCT(c,a) \ + (KEYTYPES(c)[(a)&0x7f]&CONF_ALPHA_NUMERIC_PUNCT) +#define IS_QUOTE(c,a) (KEYTYPES(c)[(a)&0x7f]&CONF_QUOTE) +#define IS_DQUOTE(c,a) (KEYTYPES(c)[(a)&0x7f]&CONF_DQUOTE) + +#else /*CHARSET_EBCDIC*/ + +#define IS_COMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0x7f]&CONF_COMMENT) +#define IS_FCOMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0x7f]&CONF_FCOMMENT) +#define IS_EOF(c,a) (KEYTYPES(c)[os_toascii[a]&0x7f]&CONF_EOF) +#define IS_ESC(c,a) (KEYTYPES(c)[os_toascii[a]&0x7f]&CONF_ESC) +#define IS_NUMBER(c,a) (KEYTYPES(c)[os_toascii[a]&0x7f]&CONF_NUMBER) +#define IS_WS(c,a) (KEYTYPES(c)[os_toascii[a]&0x7f]&CONF_WS) +#define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[os_toascii[a]&0x7f]&CONF_ALPHA_NUMERIC) +#define IS_ALPHA_NUMERIC_PUNCT(c,a) \ + (KEYTYPES(c)[os_toascii[a]&0x7f]&CONF_ALPHA_NUMERIC_PUNCT) +#define IS_QUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0x7f]&CONF_QUOTE) +#define IS_DQUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0x7f]&CONF_DQUOTE) +#endif /*CHARSET_EBCDIC*/ + +static unsigned short CONF_type_default[128]={ + 0x008,0x000,0x000,0x000,0x000,0x000,0x000,0x000, + 0x000,0x010,0x010,0x000,0x000,0x010,0x000,0x000, + 0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, + 0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, + 0x010,0x200,0x040,0x080,0x000,0x200,0x200,0x040, + 0x000,0x000,0x200,0x200,0x200,0x200,0x200,0x200, + 0x001,0x001,0x001,0x001,0x001,0x001,0x001,0x001, + 0x001,0x001,0x000,0x200,0x000,0x000,0x000,0x200, + 0x200,0x002,0x002,0x002,0x002,0x002,0x002,0x002, + 0x002,0x002,0x002,0x002,0x002,0x002,0x002,0x002, + 0x002,0x002,0x002,0x002,0x002,0x002,0x002,0x002, + 0x002,0x002,0x002,0x000,0x020,0x000,0x200,0x100, + 0x040,0x004,0x004,0x004,0x004,0x004,0x004,0x004, + 0x004,0x004,0x004,0x004,0x004,0x004,0x004,0x004, + 0x004,0x004,0x004,0x004,0x004,0x004,0x004,0x004, + 0x004,0x004,0x004,0x000,0x200,0x000,0x200,0x000, + }; + +static unsigned short CONF_type_win32[128]={ + 0x008,0x000,0x000,0x000,0x000,0x000,0x000,0x000, + 0x000,0x010,0x010,0x000,0x000,0x010,0x000,0x000, + 0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, + 0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, + 0x010,0x200,0x400,0x000,0x000,0x200,0x200,0x000, + 0x000,0x000,0x200,0x200,0x200,0x200,0x200,0x200, + 0x001,0x001,0x001,0x001,0x001,0x001,0x001,0x001, + 0x001,0x001,0x000,0xA00,0x000,0x000,0x000,0x200, + 0x200,0x002,0x002,0x002,0x002,0x002,0x002,0x002, + 0x002,0x002,0x002,0x002,0x002,0x002,0x002,0x002, + 0x002,0x002,0x002,0x002,0x002,0x002,0x002,0x002, + 0x002,0x002,0x002,0x000,0x000,0x000,0x200,0x100, + 0x000,0x004,0x004,0x004,0x004,0x004,0x004,0x004, + 0x004,0x004,0x004,0x004,0x004,0x004,0x004,0x004, + 0x004,0x004,0x004,0x004,0x004,0x004,0x004,0x004, + 0x004,0x004,0x004,0x000,0x200,0x000,0x200,0x000, + }; + diff --git a/lib/libssl/src/crypto/conf/conf_lib.c b/lib/libssl/src/crypto/conf/conf_lib.c new file mode 100644 index 00000000000..4c8ca9e9ae4 --- /dev/null +++ b/lib/libssl/src/crypto/conf/conf_lib.c @@ -0,0 +1,352 @@ +/* conf_lib.c */ +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 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 + * 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). + * + */ + +#include +#include +#include +#include +#include +#include + +const char *CONF_version="CONF" OPENSSL_VERSION_PTEXT; + +static CONF_METHOD *default_CONF_method=NULL; + +/* The following section contains the "CONF classic" functions, + rewritten in terms of the new CONF interface. */ + +int CONF_set_default_method(CONF_METHOD *meth) + { + default_CONF_method = meth; + return 1; + } + +LHASH *CONF_load(LHASH *conf, const char *file, long *eline) + { + LHASH *ltmp; + BIO *in=NULL; + +#ifdef VMS + in=BIO_new_file(file, "r"); +#else + in=BIO_new_file(file, "rb"); +#endif + if (in == NULL) + { + CONFerr(CONF_F_CONF_LOAD,ERR_R_SYS_LIB); + return NULL; + } + + ltmp = CONF_load_bio(conf, in, eline); + BIO_free(in); + + return ltmp; + } + +#ifndef NO_FP_API +LHASH *CONF_load_fp(LHASH *conf, FILE *fp,long *eline) + { + BIO *btmp; + LHASH *ltmp; + if(!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) { + CONFerr(CONF_F_CONF_LOAD_FP,ERR_R_BUF_LIB); + return NULL; + } + ltmp = CONF_load_bio(conf, btmp, eline); + BIO_free(btmp); + return ltmp; + } +#endif + +LHASH *CONF_load_bio(LHASH *conf, BIO *bp,long *eline) + { + CONF ctmp; + int ret; + + if (default_CONF_method == NULL) + default_CONF_method = NCONF_default(); + + default_CONF_method->init(&ctmp); + ctmp.data = conf; + ret = NCONF_load_bio(&ctmp, bp, eline); + if (ret) + return ctmp.data; + return NULL; + } + +STACK_OF(CONF_VALUE) *CONF_get_section(LHASH *conf,char *section) + { + CONF ctmp; + + if (default_CONF_method == NULL) + default_CONF_method = NCONF_default(); + + default_CONF_method->init(&ctmp); + ctmp.data = conf; + return NCONF_get_section(&ctmp, section); + } + +char *CONF_get_string(LHASH *conf,char *group,char *name) + { + CONF ctmp; + + if (default_CONF_method == NULL) + default_CONF_method = NCONF_default(); + + default_CONF_method->init(&ctmp); + ctmp.data = conf; + return NCONF_get_string(&ctmp, group, name); + } + +long CONF_get_number(LHASH *conf,char *group,char *name) + { + CONF ctmp; + + if (default_CONF_method == NULL) + default_CONF_method = NCONF_default(); + + default_CONF_method->init(&ctmp); + ctmp.data = conf; + return NCONF_get_number(&ctmp, group, name); + } + +void CONF_free(LHASH *conf) + { + CONF ctmp; + + if (default_CONF_method == NULL) + default_CONF_method = NCONF_default(); + + default_CONF_method->init(&ctmp); + ctmp.data = conf; + NCONF_free_data(&ctmp); + } + +#ifndef NO_FP_API +int CONF_dump_fp(LHASH *conf, FILE *out) + { + BIO *btmp; + int ret; + + if(!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) { + CONFerr(CONF_F_CONF_DUMP_FP,ERR_R_BUF_LIB); + return 0; + } + ret = CONF_dump_bio(conf, btmp); + BIO_free(btmp); + return ret; + } +#endif + +int CONF_dump_bio(LHASH *conf, BIO *out) + { + CONF ctmp; + + if (default_CONF_method == NULL) + default_CONF_method = NCONF_default(); + + default_CONF_method->init(&ctmp); + ctmp.data = conf; + return NCONF_dump_bio(&ctmp, out); + } + +/* The following section contains the "New CONF" functions. They are + completely centralised around a new CONF structure that may contain + basically anything, but at least a method pointer and a table of data. + These functions are also written in terms of the bridge functions used + by the "CONF classic" functions, for consistency. */ + +CONF *NCONF_new(CONF_METHOD *meth) + { + CONF *ret; + + if (meth == NULL) + meth = NCONF_default(); + + ret = meth->create(meth); + if (ret == NULL) + { + CONFerr(CONF_F_NCONF_NEW,ERR_R_MALLOC_FAILURE); + return(NULL); + } + + return ret; + } + +void NCONF_free(CONF *conf) + { + if (conf == NULL) + return; + conf->meth->destroy(conf); + } + +void NCONF_free_data(CONF *conf) + { + if (conf == NULL) + return; + conf->meth->destroy_data(conf); + } + +int NCONF_load(CONF *conf, const char *file, long *eline) + { + int ret; + BIO *in=NULL; + +#ifdef VMS + in=BIO_new_file(file, "r"); +#else + in=BIO_new_file(file, "rb"); +#endif + if (in == NULL) + { + CONFerr(CONF_F_CONF_LOAD,ERR_R_SYS_LIB); + return 0; + } + + ret = NCONF_load_bio(conf, in, eline); + BIO_free(in); + + return ret; + } + +#ifndef NO_FP_API +int NCONF_load_fp(CONF *conf, FILE *fp,long *eline) + { + BIO *btmp; + int ret; + if(!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) + { + CONFerr(CONF_F_CONF_LOAD_FP,ERR_R_BUF_LIB); + return 0; + } + ret = NCONF_load_bio(conf, btmp, eline); + BIO_free(btmp); + return ret; + } +#endif + +int NCONF_load_bio(CONF *conf, BIO *bp,long *eline) + { + if (conf == NULL) + { + CONFerr(CONF_F_NCONF_LOAD_BIO,CONF_R_NO_CONF); + return 0; + } + + return conf->meth->load(conf, bp, eline); + } + +STACK_OF(CONF_VALUE) *NCONF_get_section(CONF *conf,char *section) + { + if (conf == NULL) + { + CONFerr(CONF_F_NCONF_GET_SECTION,CONF_R_NO_CONF); + return NULL; + } + + return _CONF_get_section_values(conf, section); + } + +char *NCONF_get_string(CONF *conf,char *group,char *name) + { + if (conf == NULL) + { + CONFerr(CONF_F_NCONF_GET_STRING,CONF_R_NO_CONF); + return NULL; + } + + return _CONF_get_string(conf, group, name); + } + +long NCONF_get_number(CONF *conf,char *group,char *name) + { + if (conf == NULL) + { + CONFerr(CONF_F_NCONF_GET_NUMBER,CONF_R_NO_CONF); + return 0; + } + + return _CONF_get_number(conf, group, name); + } + +#ifndef NO_FP_API +int NCONF_dump_fp(CONF *conf, FILE *out) + { + BIO *btmp; + int ret; + if(!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) { + CONFerr(CONF_F_NCONF_DUMP_FP,ERR_R_BUF_LIB); + return 0; + } + ret = NCONF_dump_bio(conf, btmp); + BIO_free(btmp); + return ret; + } +#endif + +int NCONF_dump_bio(CONF *conf, BIO *out) + { + if (conf == NULL) + { + CONFerr(CONF_F_NCONF_DUMP_BIO,CONF_R_NO_CONF); + return 0; + } + + return conf->meth->dump(conf, out); + } + diff --git a/lib/libssl/src/crypto/dso/Makefile.ssl b/lib/libssl/src/crypto/dso/Makefile.ssl new file mode 100644 index 00000000000..effc46d2dc9 --- /dev/null +++ b/lib/libssl/src/crypto/dso/Makefile.ssl @@ -0,0 +1,140 @@ +# +# SSLeay/crypto/dso/Makefile +# + +DIR= dso +TOP= ../.. +CC= cc +INCLUDES= -I.. -I../../include +CFLAG=-g +INSTALL_PREFIX= +OPENSSLDIR= /usr/local/ssl +INSTALLTOP=/usr/local/ssl +MAKE= make -f Makefile.ssl +MAKEDEPEND= $(TOP)/util/domd $(TOP) +MAKEFILE= Makefile.ssl +AR= ar r + +CFLAGS= $(INCLUDES) $(CFLAG) + +GENERAL=Makefile +TEST= +APPS= + +LIB=$(TOP)/libcrypto.a +LIBSRC= dso_dl.c dso_dlfcn.c dso_err.c dso_lib.c dso_null.c \ + dso_openssl.c dso_win32.c dso_vms.c +LIBOBJ= dso_dl.o dso_dlfcn.o dso_err.o dso_lib.o dso_null.o \ + dso_openssl.o dso_win32.o dso_vms.o + +SRC= $(LIBSRC) + +EXHEADER= dso.h +HEADER= $(EXHEADER) + +ALL= $(GENERAL) $(SRC) $(HEADER) + +top: + (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all) + +all: lib + +lib: $(LIBOBJ) + $(AR) $(LIB) $(LIBOBJ) + $(RANLIB) $(LIB) + @touch lib + +files: + $(PERL) $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO + +links: + @$(TOP)/util/point.sh Makefile.ssl Makefile + @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST) + @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS) + +install: + @for i in $(EXHEADER) ; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done; + +tags: + ctags $(SRC) + +tests: + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + $(MAKEDEPEND) $(INCLUDES) $(DEPFLAG) $(PROGS) $(LIBSRC) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +dso_dl.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +dso_dl.o: ../../include/openssl/crypto.h ../../include/openssl/dso.h +dso_dl.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h +dso_dl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h +dso_dl.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h +dso_dl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +dso_dl.o: ../../include/openssl/symhacks.h ../cryptlib.h +dso_dlfcn.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +dso_dlfcn.o: ../../include/openssl/crypto.h ../../include/openssl/dso.h +dso_dlfcn.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h +dso_dlfcn.o: ../../include/openssl/err.h ../../include/openssl/lhash.h +dso_dlfcn.o: ../../include/openssl/opensslconf.h +dso_dlfcn.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h +dso_dlfcn.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +dso_dlfcn.o: ../cryptlib.h +dso_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h +dso_err.o: ../../include/openssl/dso.h ../../include/openssl/err.h +dso_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslv.h +dso_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +dso_err.o: ../../include/openssl/symhacks.h +dso_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +dso_lib.o: ../../include/openssl/crypto.h ../../include/openssl/dso.h +dso_lib.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h +dso_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h +dso_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h +dso_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +dso_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h +dso_null.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +dso_null.o: ../../include/openssl/crypto.h ../../include/openssl/dso.h +dso_null.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h +dso_null.o: ../../include/openssl/err.h ../../include/openssl/lhash.h +dso_null.o: ../../include/openssl/opensslconf.h +dso_null.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h +dso_null.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +dso_null.o: ../cryptlib.h +dso_openssl.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +dso_openssl.o: ../../include/openssl/crypto.h ../../include/openssl/dso.h +dso_openssl.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h +dso_openssl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h +dso_openssl.o: ../../include/openssl/opensslconf.h +dso_openssl.o: ../../include/openssl/opensslv.h +dso_openssl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +dso_openssl.o: ../../include/openssl/symhacks.h ../cryptlib.h +dso_vms.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +dso_vms.o: ../../include/openssl/crypto.h ../../include/openssl/dso.h +dso_vms.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h +dso_vms.o: ../../include/openssl/err.h ../../include/openssl/lhash.h +dso_vms.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h +dso_vms.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +dso_vms.o: ../../include/openssl/symhacks.h ../cryptlib.h +dso_win32.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +dso_win32.o: ../../include/openssl/crypto.h ../../include/openssl/dso.h +dso_win32.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h +dso_win32.o: ../../include/openssl/err.h ../../include/openssl/lhash.h +dso_win32.o: ../../include/openssl/opensslconf.h +dso_win32.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h +dso_win32.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +dso_win32.o: ../cryptlib.h diff --git a/lib/libssl/src/crypto/dso/README b/lib/libssl/src/crypto/dso/README new file mode 100644 index 00000000000..6ba03c5631d --- /dev/null +++ b/lib/libssl/src/crypto/dso/README @@ -0,0 +1,24 @@ +TODO +---- + +Find a way where name-translation can be done in a way that is +sensitive to particular methods (ie. generic code could still do +different path/filename substitutions on win32 to what it does on +*nix) but doesn't assume some canonical form. Already one case +exists where the "blah -> (libblah.so,blah.dll)" mapping doesn't +suffice. I suspect a callback with an enumerated (or string?) +parameter could be the way to go here ... DSO_ctrl the callback +into place and it can be invoked to handle name translation with +some clue to the calling code as to what kind of system it is. + +NOTES +----- + +I've checked out HPUX (well, version 11 at least) and shl_t is +a pointer type so it's safe to use in the way it has been in +dso_dl.c. On the other hand, HPUX11 support dlfcn too and +according to their man page, prefer developers to move to that. +I'll leave Richard's changes there as I guess dso_dl is needed +for HPUX10.20. + + diff --git a/lib/libssl/src/crypto/dso/dso.h b/lib/libssl/src/crypto/dso/dso.h new file mode 100644 index 00000000000..bed7c464a64 --- /dev/null +++ b/lib/libssl/src/crypto/dso/dso.h @@ -0,0 +1,250 @@ +/* dso.h */ +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 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 + * 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). + * + */ + +#ifndef HEADER_DSO_H +#define HEADER_DSO_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* These values are used as commands to DSO_ctrl() */ +#define DSO_CTRL_GET_FLAGS 1 +#define DSO_CTRL_SET_FLAGS 2 +#define DSO_CTRL_OR_FLAGS 3 + +/* These flags control the translation of file-names from canonical to + * native. Eg. in the CryptoSwift support, the "dl" and "dlfcn" + * methods will translate "swift" -> "libswift.so" whereas the "win32" + * method will translate "swift" -> "swift.dll". NB: Until I can figure + * out how to be more "conventional" with this, the methods will only + * honour this flag if it looks like it was passed a file without any + * path and if the filename is small enough. + */ +#define DSO_FLAG_NAME_TRANSLATION 0x01 + +/* The following flag controls the translation of symbol names to upper + * case. This is currently only being implemented for OpenVMS. + */ +#define DSO_FLAG_UPCASE_SYMBOL 0x02 + + +typedef void (*DSO_FUNC_TYPE)(void); + +typedef struct dso_st DSO; + +typedef struct dso_meth_st + { + const char *name; + /* Loads a shared library */ + int (*dso_load)(DSO *dso, const char *filename); + /* Unloads a shared library */ + int (*dso_unload)(DSO *dso); + /* Binds a variable */ + void *(*dso_bind_var)(DSO *dso, const char *symname); + /* Binds a function - assumes a return type of DSO_FUNC_TYPE. + * This should be cast to the real function prototype by the + * caller. Platforms that don't have compatible representations + * for different prototypes (this is possible within ANSI C) + * are highly unlikely to have shared libraries at all, let + * alone a DSO_METHOD implemented for them. */ + DSO_FUNC_TYPE (*dso_bind_func)(DSO *dso, const char *symname); + +/* I don't think this would actually be used in any circumstances. */ +#if 0 + /* Unbinds a variable */ + int (*dso_unbind_var)(DSO *dso, char *symname, void *symptr); + /* Unbinds a function */ + int (*dso_unbind_func)(DSO *dso, char *symname, DSO_FUNC_TYPE symptr); +#endif + /* The generic (yuck) "ctrl()" function. NB: Negative return + * values (rather than zero) indicate errors. */ + long (*dso_ctrl)(DSO *dso, int cmd, long larg, void *parg); + + /* [De]Initialisation handlers. */ + int (*init)(DSO *dso); + int (*finish)(DSO *dso); + } DSO_METHOD; + +/**********************************************************************/ +/* The low-level handle type used to refer to a loaded shared library */ + +struct dso_st + { + DSO_METHOD *meth; + /* Standard dlopen uses a (void *). Win32 uses a HANDLE. VMS + * doesn't use anything but will need to cache the filename + * for use in the dso_bind handler. All in all, let each + * method control its own destiny. "Handles" and such go in + * a STACK. */ + STACK *meth_data; + int references; + int flags; + /* For use by applications etc ... use this for your bits'n'pieces, + * don't touch meth_data! */ + CRYPTO_EX_DATA ex_data; + }; + + +DSO * DSO_new(void); +DSO * DSO_new_method(DSO_METHOD *method); +int DSO_free(DSO *dso); +int DSO_flags(DSO *dso); +int DSO_up(DSO *dso); +long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg); + +void DSO_set_default_method(DSO_METHOD *meth); +DSO_METHOD *DSO_get_default_method(void); +DSO_METHOD *DSO_get_method(DSO *dso); +DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth); + +/* The all-singing all-dancing load function, you normally pass NULL + * for the first and third parameters. Use DSO_up and DSO_free for + * subsequent reference count handling. Any flags passed in will be set + * in the constructed DSO after its init() function but before the + * load operation. This will be done with; + * DSO_ctrl(dso, DSO_CTRL_SET_FLAGS, flags, NULL); */ +DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags); + +/* This function binds to a variable inside a shared library. */ +void *DSO_bind_var(DSO *dso, const char *symname); + +/* This function binds to a function inside a shared library. */ +DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname); + +/* This method is the default, but will beg, borrow, or steal whatever + * method should be the default on any particular platform (including + * DSO_METH_null() if necessary). */ +DSO_METHOD *DSO_METHOD_openssl(void); + +/* This method is defined for all platforms - if a platform has no + * DSO support then this will be the only method! */ +DSO_METHOD *DSO_METHOD_null(void); + +/* If DSO_DLFCN is defined, the standard dlfcn.h-style functions + * (dlopen, dlclose, dlsym, etc) will be used and incorporated into + * this method. If not, this method will return NULL. */ +DSO_METHOD *DSO_METHOD_dlfcn(void); + +/* If DSO_DL is defined, the standard dl.h-style functions (shl_load, + * shl_unload, shl_findsym, etc) will be used and incorporated into + * this method. If not, this method will return NULL. */ +DSO_METHOD *DSO_METHOD_dl(void); + +/* If WIN32 is defined, use DLLs. If not, return NULL. */ +DSO_METHOD *DSO_METHOD_win32(void); + +/* If VMS is defined, use shared images. If not, return NULL. */ +DSO_METHOD *DSO_METHOD_vms(void); + +void ERR_load_DSO_strings(void); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ + +/* Error codes for the DSO functions. */ + +/* Function codes. */ +#define DSO_F_DLFCN_BIND_FUNC 100 +#define DSO_F_DLFCN_BIND_VAR 101 +#define DSO_F_DLFCN_CTRL 102 +#define DSO_F_DLFCN_LOAD 103 +#define DSO_F_DLFCN_UNLOAD 104 +#define DSO_F_DL_BIND_FUNC 105 +#define DSO_F_DL_BIND_VAR 106 +#define DSO_F_DL_CTRL 107 +#define DSO_F_DL_LOAD 108 +#define DSO_F_DL_UNLOAD 109 +#define DSO_F_DSO_BIND_FUNC 110 +#define DSO_F_DSO_BIND_VAR 111 +#define DSO_F_DSO_CTRL 112 +#define DSO_F_DSO_FREE 113 +#define DSO_F_DSO_LOAD 114 +#define DSO_F_DSO_NEW_METHOD 115 +#define DSO_F_DSO_UP 116 +#define DSO_F_VMS_BIND_VAR 122 +#define DSO_F_VMS_CTRL 123 +#define DSO_F_VMS_LOAD 124 +#define DSO_F_VMS_UNLOAD 125 +#define DSO_F_WIN32_BIND_FUNC 117 +#define DSO_F_WIN32_BIND_VAR 118 +#define DSO_F_WIN32_CTRL 119 +#define DSO_F_WIN32_LOAD 120 +#define DSO_F_WIN32_UNLOAD 121 + +/* Reason codes. */ +#define DSO_R_CTRL_FAILED 100 +#define DSO_R_FILENAME_TOO_BIG 109 +#define DSO_R_FINISH_FAILED 101 +#define DSO_R_LOAD_FAILED 102 +#define DSO_R_NULL_HANDLE 103 +#define DSO_R_STACK_ERROR 104 +#define DSO_R_SYM_FAILURE 105 +#define DSO_R_UNKNOWN_COMMAND 106 +#define DSO_R_UNLOAD_FAILED 107 +#define DSO_R_UNSUPPORTED 108 + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/lib/libssl/src/crypto/dso/dso_dl.c b/lib/libssl/src/crypto/dso/dso_dl.c new file mode 100644 index 00000000000..69810fc3bb9 --- /dev/null +++ b/lib/libssl/src/crypto/dso/dso_dl.c @@ -0,0 +1,251 @@ +/* dso_dl.c */ +/* Written by Richard Levitte (levitte@openssl.org) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 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 + * 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). + * + */ + +#include +#include "cryptlib.h" +#include + +#ifndef DSO_DL +DSO_METHOD *DSO_METHOD_dl(void) + { + return NULL; + } +#else + +#include + +/* Part of the hack in "dl_load" ... */ +#define DSO_MAX_TRANSLATED_SIZE 256 + +static int dl_load(DSO *dso, const char *filename); +static int dl_unload(DSO *dso); +static void *dl_bind_var(DSO *dso, const char *symname); +static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname); +#if 0 +static int dl_unbind_var(DSO *dso, char *symname, void *symptr); +static int dl_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr); +static int dl_init(DSO *dso); +static int dl_finish(DSO *dso); +#endif +static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg); + +static DSO_METHOD dso_meth_dl = { + "OpenSSL 'dl' shared library method", + dl_load, + dl_unload, + dl_bind_var, + dl_bind_func, +/* For now, "unbind" doesn't exist */ +#if 0 + NULL, /* unbind_var */ + NULL, /* unbind_func */ +#endif + dl_ctrl, + NULL, /* init */ + NULL /* finish */ + }; + +DSO_METHOD *DSO_METHOD_dl(void) + { + return(&dso_meth_dl); + } + +/* For this DSO_METHOD, our meth_data STACK will contain; + * (i) the handle (shl_t) returned from shl_load(). + * NB: I checked on HPUX11 and shl_t is itself a pointer + * type so the cast is safe. + */ + +static int dl_load(DSO *dso, const char *filename) + { + shl_t ptr; + char translated[DSO_MAX_TRANSLATED_SIZE]; + int len; + + /* The same comment as in dlfcn_load applies here. bleurgh. */ + len = strlen(filename); + if((dso->flags & DSO_FLAG_NAME_TRANSLATION) && + (len + 6 < DSO_MAX_TRANSLATED_SIZE) && + (strstr(filename, "/") == NULL)) + { + sprintf(translated, "lib%s.so", filename); + ptr = shl_load(translated, BIND_IMMEDIATE, NULL); + } + else + ptr = shl_load(filename, BIND_IMMEDIATE, NULL); + if(ptr == NULL) + { + DSOerr(DSO_F_DL_LOAD,DSO_R_LOAD_FAILED); + return(0); + } + if(!sk_push(dso->meth_data, (char *)ptr)) + { + DSOerr(DSO_F_DL_LOAD,DSO_R_STACK_ERROR); + shl_unload(ptr); + return(0); + } + return(1); + } + +static int dl_unload(DSO *dso) + { + shl_t ptr; + if(dso == NULL) + { + DSOerr(DSO_F_DL_UNLOAD,ERR_R_PASSED_NULL_PARAMETER); + return(0); + } + if(sk_num(dso->meth_data) < 1) + return(1); + /* Is this statement legal? */ + ptr = (shl_t)sk_pop(dso->meth_data); + if(ptr == NULL) + { + DSOerr(DSO_F_DL_UNLOAD,DSO_R_NULL_HANDLE); + /* Should push the value back onto the stack in + * case of a retry. */ + sk_push(dso->meth_data, (char *)ptr); + return(0); + } + shl_unload(ptr); + return(1); + } + +static void *dl_bind_var(DSO *dso, const char *symname) + { + shl_t ptr; + void *sym; + + if((dso == NULL) || (symname == NULL)) + { + DSOerr(DSO_F_DL_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER); + return(NULL); + } + if(sk_num(dso->meth_data) < 1) + { + DSOerr(DSO_F_DL_BIND_VAR,DSO_R_STACK_ERROR); + return(NULL); + } + ptr = (shl_t)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); + if(ptr == NULL) + { + DSOerr(DSO_F_DL_BIND_VAR,DSO_R_NULL_HANDLE); + return(NULL); + } + if (shl_findsym(ptr, symname, TYPE_UNDEFINED, &sym) < 0) + { + DSOerr(DSO_F_DL_BIND_VAR,DSO_R_SYM_FAILURE); + return(NULL); + } + return(sym); + } + +static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname) + { + shl_t ptr; + void *sym; + + if((dso == NULL) || (symname == NULL)) + { + DSOerr(DSO_F_DL_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER); + return(NULL); + } + if(sk_num(dso->meth_data) < 1) + { + DSOerr(DSO_F_DL_BIND_FUNC,DSO_R_STACK_ERROR); + return(NULL); + } + ptr = (shl_t)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); + if(ptr == NULL) + { + DSOerr(DSO_F_DL_BIND_FUNC,DSO_R_NULL_HANDLE); + return(NULL); + } + if (shl_findsym(ptr, symname, TYPE_UNDEFINED, &sym) < 0) + { + DSOerr(DSO_F_DL_BIND_FUNC,DSO_R_SYM_FAILURE); + return(NULL); + } + return((DSO_FUNC_TYPE)sym); + } + +static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg) + { + if(dso == NULL) + { + DSOerr(DSO_F_DL_CTRL,ERR_R_PASSED_NULL_PARAMETER); + return(-1); + } + switch(cmd) + { + case DSO_CTRL_GET_FLAGS: + return dso->flags; + case DSO_CTRL_SET_FLAGS: + dso->flags = (int)larg; + return(0); + case DSO_CTRL_OR_FLAGS: + dso->flags |= (int)larg; + return(0); + default: + break; + } + DSOerr(DSO_F_DL_CTRL,DSO_R_UNKNOWN_COMMAND); + return(-1); + } + +#endif /* DSO_DL */ diff --git a/lib/libssl/src/crypto/dso/dso_dlfcn.c b/lib/libssl/src/crypto/dso/dso_dlfcn.c new file mode 100644 index 00000000000..e709c721cc3 --- /dev/null +++ b/lib/libssl/src/crypto/dso/dso_dlfcn.c @@ -0,0 +1,276 @@ +/* dso_dlfcn.c */ +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 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 + * 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). + * + */ + +#include +#include "cryptlib.h" +#include + +#ifndef DSO_DLFCN +DSO_METHOD *DSO_METHOD_dlfcn(void) + { + return NULL; + } +#else + +#ifdef HAVE_DLFCN_H +#include +#endif + +/* Part of the hack in "dlfcn_load" ... */ +#define DSO_MAX_TRANSLATED_SIZE 256 + +static int dlfcn_load(DSO *dso, const char *filename); +static int dlfcn_unload(DSO *dso); +static void *dlfcn_bind_var(DSO *dso, const char *symname); +static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname); +#if 0 +static int dlfcn_unbind(DSO *dso, char *symname, void *symptr); +static int dlfcn_init(DSO *dso); +static int dlfcn_finish(DSO *dso); +#endif +static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg); + +static DSO_METHOD dso_meth_dlfcn = { + "OpenSSL 'dlfcn' shared library method", + dlfcn_load, + dlfcn_unload, + dlfcn_bind_var, + dlfcn_bind_func, +/* For now, "unbind" doesn't exist */ +#if 0 + NULL, /* unbind_var */ + NULL, /* unbind_func */ +#endif + dlfcn_ctrl, + NULL, /* init */ + NULL /* finish */ + }; + +DSO_METHOD *DSO_METHOD_dlfcn(void) + { + return(&dso_meth_dlfcn); + } + +/* Prior to using the dlopen() function, we should decide on the flag + * we send. There's a few different ways of doing this and it's a + * messy venn-diagram to match up which platforms support what. So + * as we don't have autoconf yet, I'm implementing a hack that could + * be hacked further relatively easily to deal with cases as we find + * them. Initially this is to cope with OpenBSD. */ +#ifdef __OpenBSD__ +# ifdef DL_LAZY +# define DLOPEN_FLAG DL_LAZY +# else +# ifdef RTLD_NOW +# define DLOPEN_FLAG RTLD_NOW +# else +# define DLOPEN_FLAG 0 +# endif +# endif +#else +# define DLOPEN_FLAG RTLD_NOW /* Hope this works everywhere else */ +#endif + +/* For this DSO_METHOD, our meth_data STACK will contain; + * (i) the handle (void*) returned from dlopen(). + */ + +static int dlfcn_load(DSO *dso, const char *filename) + { + void *ptr; + char translated[DSO_MAX_TRANSLATED_SIZE]; + int len; + + /* NB: This is a hideous hack, but I'm not yet sure what + * to replace it with. This attempts to convert any filename, + * that looks like it has no path information, into a + * translated form, e. "blah" -> "libblah.so" */ + len = strlen(filename); + if((dso->flags & DSO_FLAG_NAME_TRANSLATION) && + (len + 6 < DSO_MAX_TRANSLATED_SIZE) && + (strstr(filename, "/") == NULL)) + { + sprintf(translated, "lib%s.so", filename); + ptr = dlopen(translated, DLOPEN_FLAG); + } + else + { + ptr = dlopen(filename, DLOPEN_FLAG); + } + if(ptr == NULL) + { + DSOerr(DSO_F_DLFCN_LOAD,DSO_R_LOAD_FAILED); + return(0); + } + if(!sk_push(dso->meth_data, (char *)ptr)) + { + DSOerr(DSO_F_DLFCN_LOAD,DSO_R_STACK_ERROR); + dlclose(ptr); + return(0); + } + return(1); + } + +static int dlfcn_unload(DSO *dso) + { + void *ptr; + if(dso == NULL) + { + DSOerr(DSO_F_DLFCN_UNLOAD,ERR_R_PASSED_NULL_PARAMETER); + return(0); + } + if(sk_num(dso->meth_data) < 1) + return(1); + ptr = (void *)sk_pop(dso->meth_data); + if(ptr == NULL) + { + DSOerr(DSO_F_DLFCN_UNLOAD,DSO_R_NULL_HANDLE); + /* Should push the value back onto the stack in + * case of a retry. */ + sk_push(dso->meth_data, (char *)ptr); + return(0); + } + /* For now I'm not aware of any errors associated with dlclose() */ + dlclose(ptr); + return(1); + } + +static void *dlfcn_bind_var(DSO *dso, const char *symname) + { + void *ptr, *sym; + + if((dso == NULL) || (symname == NULL)) + { + DSOerr(DSO_F_DLFCN_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER); + return(NULL); + } + if(sk_num(dso->meth_data) < 1) + { + DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_STACK_ERROR); + return(NULL); + } + ptr = (void *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); + if(ptr == NULL) + { + DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_NULL_HANDLE); + return(NULL); + } + sym = dlsym(ptr, symname); + if(sym == NULL) + { + DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_SYM_FAILURE); + return(NULL); + } + return(sym); + } + +static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname) + { + void *ptr; + DSO_FUNC_TYPE sym; + + if((dso == NULL) || (symname == NULL)) + { + DSOerr(DSO_F_DLFCN_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER); + return(NULL); + } + if(sk_num(dso->meth_data) < 1) + { + DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_STACK_ERROR); + return(NULL); + } + ptr = (void *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); + if(ptr == NULL) + { + DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_NULL_HANDLE); + return(NULL); + } + sym = (DSO_FUNC_TYPE)dlsym(ptr, symname); + if(sym == NULL) + { + DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_SYM_FAILURE); + return(NULL); + } + return(sym); + } + +static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg) + { + if(dso == NULL) + { + DSOerr(DSO_F_DLFCN_CTRL,ERR_R_PASSED_NULL_PARAMETER); + return(-1); + } + switch(cmd) + { + case DSO_CTRL_GET_FLAGS: + return dso->flags; + case DSO_CTRL_SET_FLAGS: + dso->flags = (int)larg; + return(0); + case DSO_CTRL_OR_FLAGS: + dso->flags |= (int)larg; + return(0); + default: + break; + } + DSOerr(DSO_F_DLFCN_CTRL,DSO_R_UNKNOWN_COMMAND); + return(-1); + } + +#endif /* DSO_DLFCN */ diff --git a/lib/libssl/src/crypto/dso/dso_err.c b/lib/libssl/src/crypto/dso/dso_err.c new file mode 100644 index 00000000000..a3d7321c9b8 --- /dev/null +++ b/lib/libssl/src/crypto/dso/dso_err.c @@ -0,0 +1,128 @@ +/* crypto/dso/dso_err.c */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef NO_ERR +static ERR_STRING_DATA DSO_str_functs[]= + { +{ERR_PACK(0,DSO_F_DLFCN_BIND_FUNC,0), "DLFCN_BIND_FUNC"}, +{ERR_PACK(0,DSO_F_DLFCN_BIND_VAR,0), "DLFCN_BIND_VAR"}, +{ERR_PACK(0,DSO_F_DLFCN_CTRL,0), "DLFCN_CTRL"}, +{ERR_PACK(0,DSO_F_DLFCN_LOAD,0), "DLFCN_LOAD"}, +{ERR_PACK(0,DSO_F_DLFCN_UNLOAD,0), "DLFCN_UNLOAD"}, +{ERR_PACK(0,DSO_F_DL_BIND_FUNC,0), "DL_BIND_FUNC"}, +{ERR_PACK(0,DSO_F_DL_BIND_VAR,0), "DL_BIND_VAR"}, +{ERR_PACK(0,DSO_F_DL_CTRL,0), "DL_CTRL"}, +{ERR_PACK(0,DSO_F_DL_LOAD,0), "DL_LOAD"}, +{ERR_PACK(0,DSO_F_DL_UNLOAD,0), "DL_UNLOAD"}, +{ERR_PACK(0,DSO_F_DSO_BIND_FUNC,0), "DSO_bind_func"}, +{ERR_PACK(0,DSO_F_DSO_BIND_VAR,0), "DSO_bind_var"}, +{ERR_PACK(0,DSO_F_DSO_CTRL,0), "DSO_ctrl"}, +{ERR_PACK(0,DSO_F_DSO_FREE,0), "DSO_free"}, +{ERR_PACK(0,DSO_F_DSO_LOAD,0), "DSO_load"}, +{ERR_PACK(0,DSO_F_DSO_NEW_METHOD,0), "DSO_new_method"}, +{ERR_PACK(0,DSO_F_DSO_UP,0), "DSO_up"}, +{ERR_PACK(0,DSO_F_VMS_BIND_VAR,0), "VMS_BIND_VAR"}, +{ERR_PACK(0,DSO_F_VMS_CTRL,0), "VMS_CTRL"}, +{ERR_PACK(0,DSO_F_VMS_LOAD,0), "VMS_LOAD"}, +{ERR_PACK(0,DSO_F_VMS_UNLOAD,0), "VMS_UNLOAD"}, +{ERR_PACK(0,DSO_F_WIN32_BIND_FUNC,0), "WIN32_BIND_FUNC"}, +{ERR_PACK(0,DSO_F_WIN32_BIND_VAR,0), "WIN32_BIND_VAR"}, +{ERR_PACK(0,DSO_F_WIN32_CTRL,0), "WIN32_CTRL"}, +{ERR_PACK(0,DSO_F_WIN32_LOAD,0), "WIN32_LOAD"}, +{ERR_PACK(0,DSO_F_WIN32_UNLOAD,0), "WIN32_UNLOAD"}, +{0,NULL} + }; + +static ERR_STRING_DATA DSO_str_reasons[]= + { +{DSO_R_CTRL_FAILED ,"control command failed"}, +{DSO_R_FILENAME_TOO_BIG ,"filename too big"}, +{DSO_R_FINISH_FAILED ,"cleanup method function failed"}, +{DSO_R_LOAD_FAILED ,"could not load the shared library"}, +{DSO_R_NULL_HANDLE ,"a null shared library handle was used"}, +{DSO_R_STACK_ERROR ,"the meth_data stack is corrupt"}, +{DSO_R_SYM_FAILURE ,"could not bind to the requested symbol name"}, +{DSO_R_UNKNOWN_COMMAND ,"unknown control command"}, +{DSO_R_UNLOAD_FAILED ,"could not unload the shared library"}, +{DSO_R_UNSUPPORTED ,"functionality not supported"}, +{0,NULL} + }; + +#endif + +void ERR_load_DSO_strings(void) + { + static int init=1; + + if (init) + { + init=0; +#ifndef NO_ERR + ERR_load_strings(ERR_LIB_DSO,DSO_str_functs); + ERR_load_strings(ERR_LIB_DSO,DSO_str_reasons); +#endif + + } + } diff --git a/lib/libssl/src/crypto/dso/dso_lib.c b/lib/libssl/src/crypto/dso/dso_lib.c new file mode 100644 index 00000000000..acd166697eb --- /dev/null +++ b/lib/libssl/src/crypto/dso/dso_lib.c @@ -0,0 +1,306 @@ +/* dso_lib.c */ +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 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 + * 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). + * + */ + +#include +#include +#include "cryptlib.h" +#include + +static DSO_METHOD *default_DSO_meth = NULL; + +DSO *DSO_new(void) + { + return(DSO_new_method(NULL)); + } + +void DSO_set_default_method(DSO_METHOD *meth) + { + default_DSO_meth = meth; + } + +DSO_METHOD *DSO_get_default_method(void) + { + return(default_DSO_meth); + } + +DSO_METHOD *DSO_get_method(DSO *dso) + { + return(dso->meth); + } + +DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth) + { + DSO_METHOD *mtmp; + mtmp = dso->meth; + dso->meth = meth; + return(mtmp); + } + +DSO *DSO_new_method(DSO_METHOD *meth) + { + DSO *ret; + + if(default_DSO_meth == NULL) + /* We default to DSO_METH_openssl() which in turn defaults + * to stealing the "best available" method. Will fallback + * to DSO_METH_null() in the worst case. */ + default_DSO_meth = DSO_METHOD_openssl(); + ret = (DSO *)OPENSSL_malloc(sizeof(DSO)); + if(ret == NULL) + { + DSOerr(DSO_F_DSO_NEW_METHOD,ERR_R_MALLOC_FAILURE); + return(NULL); + } + memset(ret, 0, sizeof(DSO)); + ret->meth_data = sk_new_null(); + if((ret->meth_data = sk_new_null()) == NULL) + { + /* sk_new doesn't generate any errors so we do */ + DSOerr(DSO_F_DSO_NEW_METHOD,ERR_R_MALLOC_FAILURE); + OPENSSL_free(ret); + return(NULL); + } + if(meth == NULL) + ret->meth = default_DSO_meth; + else + ret->meth = meth; + ret->references = 1; + if((ret->meth->init != NULL) && !ret->meth->init(ret)) + { + OPENSSL_free(ret); + ret=NULL; + } + return(ret); + } + +int DSO_free(DSO *dso) + { + int i; + + if(dso == NULL) + { + DSOerr(DSO_F_DSO_FREE,ERR_R_PASSED_NULL_PARAMETER); + return(0); + } + + i=CRYPTO_add(&dso->references,-1,CRYPTO_LOCK_DSO); +#ifdef REF_PRINT + REF_PRINT("DSO",dso); +#endif + if(i > 0) return(1); +#ifdef REF_CHECK + if(i < 0) + { + fprintf(stderr,"DSO_free, bad reference count\n"); + abort(); + } +#endif + + if((dso->meth->dso_unload != NULL) && !dso->meth->dso_unload(dso)) + { + DSOerr(DSO_F_DSO_FREE,DSO_R_UNLOAD_FAILED); + return(0); + } + + if((dso->meth->finish != NULL) && !dso->meth->finish(dso)) + { + DSOerr(DSO_F_DSO_FREE,DSO_R_FINISH_FAILED); + return(0); + } + + sk_free(dso->meth_data); + + OPENSSL_free(dso); + return(1); + } + +int DSO_flags(DSO *dso) + { + return((dso == NULL) ? 0 : dso->flags); + } + + +int DSO_up(DSO *dso) + { + if (dso == NULL) + { + DSOerr(DSO_F_DSO_UP,ERR_R_PASSED_NULL_PARAMETER); + return(0); + } + + CRYPTO_add(&dso->references,1,CRYPTO_LOCK_DSO); + return(1); + } + +DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags) + { + DSO *ret; + int allocated = 0; + + if(filename == NULL) + { + DSOerr(DSO_F_DSO_LOAD,ERR_R_PASSED_NULL_PARAMETER); + return(NULL); + } + if(dso == NULL) + { + ret = DSO_new_method(meth); + if(ret == NULL) + { + DSOerr(DSO_F_DSO_LOAD,ERR_R_MALLOC_FAILURE); + return(NULL); + } + allocated = 1; + } + else + ret = dso; + /* Bleurgh ... have to check for negative return values for + * errors. */ + if(DSO_ctrl(ret, DSO_CTRL_SET_FLAGS, flags, NULL) < 0) + { + DSOerr(DSO_F_DSO_LOAD,DSO_R_CTRL_FAILED); + if(allocated) + DSO_free(ret); + return(NULL); + } + if(ret->meth->dso_load == NULL) + { + DSOerr(DSO_F_DSO_LOAD,DSO_R_UNSUPPORTED); + if(allocated) + DSO_free(ret); + return(NULL); + } + if(!ret->meth->dso_load(ret, filename)) + { + DSOerr(DSO_F_DSO_LOAD,DSO_R_LOAD_FAILED); + if(allocated) + DSO_free(ret); + return(NULL); + } + /* Load succeeded */ + return(ret); + } + +void *DSO_bind_var(DSO *dso, const char *symname) + { + void *ret = NULL; + + if((dso == NULL) || (symname == NULL)) + { + DSOerr(DSO_F_DSO_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER); + return(NULL); + } + if(dso->meth->dso_bind_var == NULL) + { + DSOerr(DSO_F_DSO_BIND_VAR,DSO_R_UNSUPPORTED); + return(NULL); + } + if((ret = dso->meth->dso_bind_var(dso, symname)) == NULL) + { + DSOerr(DSO_F_DSO_BIND_VAR,DSO_R_SYM_FAILURE); + return(NULL); + } + /* Success */ + return(ret); + } + +DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname) + { + DSO_FUNC_TYPE ret = NULL; + + if((dso == NULL) || (symname == NULL)) + { + DSOerr(DSO_F_DSO_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER); + return(NULL); + } + if(dso->meth->dso_bind_func == NULL) + { + DSOerr(DSO_F_DSO_BIND_FUNC,DSO_R_UNSUPPORTED); + return(NULL); + } + if((ret = dso->meth->dso_bind_func(dso, symname)) == NULL) + { + DSOerr(DSO_F_DSO_BIND_FUNC,DSO_R_SYM_FAILURE); + return(NULL); + } + /* Success */ + return(ret); + } + +/* I don't really like these *_ctrl functions very much to be perfectly + * honest. For one thing, I think I have to return a negative value for + * any error because possible DSO_ctrl() commands may return values + * such as "size"s that can legitimately be zero (making the standard + * "if(DSO_cmd(...))" form that works almost everywhere else fail at + * odd times. I'd prefer "output" values to be passed by reference and + * the return value as success/failure like usual ... but we conform + * when we must... :-) */ +long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg) + { + if(dso == NULL) + { + DSOerr(DSO_F_DSO_CTRL,ERR_R_PASSED_NULL_PARAMETER); + return(-1); + } + if((dso->meth == NULL) || (dso->meth->dso_ctrl == NULL)) + { + DSOerr(DSO_F_DSO_CTRL,DSO_R_UNSUPPORTED); + return(-1); + } + return(dso->meth->dso_ctrl(dso,cmd,larg,parg)); + } diff --git a/lib/libssl/src/crypto/dso/dso_null.c b/lib/libssl/src/crypto/dso/dso_null.c new file mode 100644 index 00000000000..fa13a7cb0f1 --- /dev/null +++ b/lib/libssl/src/crypto/dso/dso_null.c @@ -0,0 +1,86 @@ +/* dso_null.c */ +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 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 + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* This "NULL" method is provided as the fallback for systems that have + * no appropriate support for "shared-libraries". */ + +#include +#include "cryptlib.h" +#include + +static DSO_METHOD dso_meth_null = { + "NULL shared library method", + NULL, /* load */ + NULL, /* unload */ + NULL, /* bind_var */ + NULL, /* bind_func */ +/* For now, "unbind" doesn't exist */ +#if 0 + NULL, /* unbind_var */ + NULL, /* unbind_func */ +#endif + NULL, /* ctrl */ + NULL, /* init */ + NULL /* finish */ + }; + +DSO_METHOD *DSO_METHOD_null(void) + { + return(&dso_meth_null); + } + diff --git a/lib/libssl/src/crypto/dso/dso_openssl.c b/lib/libssl/src/crypto/dso/dso_openssl.c new file mode 100644 index 00000000000..a4395ebffec --- /dev/null +++ b/lib/libssl/src/crypto/dso/dso_openssl.c @@ -0,0 +1,81 @@ +/* dso_openssl.c */ +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 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 + * 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). + * + */ + +#include +#include "cryptlib.h" +#include + +/* We just pinch the method from an appropriate "default" method. */ + +DSO_METHOD *DSO_METHOD_openssl(void) + { +#ifdef DEF_DSO_METHOD + return(DEF_DSO_METHOD()); +#elif defined(DSO_DLFCN) + return(DSO_METHOD_dlfcn()); +#elif defined(DSO_DL) + return(DSO_METHOD_dl()); +#elif defined(DSO_WIN32) + return(DSO_METHOD_win32()); +#elif defined(DSO_VMS) + return(DSO_METHOD_vms()); +#else + return(DSO_METHOD_null()); +#endif + } + diff --git a/lib/libssl/src/crypto/dso/dso_vms.c b/lib/libssl/src/crypto/dso/dso_vms.c new file mode 100644 index 00000000000..8ff7090129c --- /dev/null +++ b/lib/libssl/src/crypto/dso/dso_vms.c @@ -0,0 +1,371 @@ +/* dso_vms.c */ +/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 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 + * 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). + * + */ + +#include +#include +#include +#ifdef VMS +#pragma message disable DOLLARID +#include +#include +#include +#include +#include +#endif +#include "cryptlib.h" +#include + +#ifndef VMS +DSO_METHOD *DSO_METHOD_vms(void) + { + return NULL; + } +#else +#pragma message disable DOLLARID + +static int vms_load(DSO *dso, const char *filename); +static int vms_unload(DSO *dso); +static void *vms_bind_var(DSO *dso, const char *symname); +static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname); +#if 0 +static int vms_unbind_var(DSO *dso, char *symname, void *symptr); +static int vms_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr); +static int vms_init(DSO *dso); +static int vms_finish(DSO *dso); +#endif +static long vms_ctrl(DSO *dso, int cmd, long larg, void *parg); + +static DSO_METHOD dso_meth_vms = { + "OpenSSL 'VMS' shared library method", + vms_load, + NULL, /* unload */ + vms_bind_var, + vms_bind_func, +/* For now, "unbind" doesn't exist */ +#if 0 + NULL, /* unbind_var */ + NULL, /* unbind_func */ +#endif + vms_ctrl, + NULL, /* init */ + NULL /* finish */ + }; + +/* On VMS, the only "handle" is the file name. LIB$FIND_IMAGE_SYMBOL depends + * on the reference to the file name being the same for all calls regarding + * one shared image, so we'll just store it in an instance of the following + * structure and put a pointer to that instance in the meth_data stack. + */ +typedef struct dso_internal_st + { + /* This should contain the name only, no directory, + * no extension, nothing but a name. */ + struct dsc$descriptor_s filename_dsc; + char filename[FILENAME_MAX+1]; + /* This contains whatever is not in filename, if needed. + * Normally not defined. */ + struct dsc$descriptor_s imagename_dsc; + char imagename[FILENAME_MAX+1]; + } DSO_VMS_INTERNAL; + + +DSO_METHOD *DSO_METHOD_vms(void) + { + return(&dso_meth_vms); + } + +static int vms_load(DSO *dso, const char *filename) + { + DSO_VMS_INTERNAL *p; + const char *sp1, *sp2; /* Search result */ + + /* A file specification may look like this: + * + * node::dev:[dir-spec]name.type;ver + * + * or (for compatibility with TOPS-20): + * + * node::dev:name.type;ver + * + * and the dir-spec uses '.' as separator. Also, a dir-spec + * may consist of several parts, with mixed use of [] and <>: + * + * [dir1.] + * + * We need to split the file specification into the name and + * the rest (both before and after the name itself). + */ + /* Start with trying to find the end of a dir-spec, and save the + position of the byte after in sp1 */ + sp1 = strrchr(filename, ']'); + sp2 = strrchr(filename, '>'); + if (sp1 == NULL) sp1 = sp2; + if (sp2 != NULL && sp2 > sp1) sp1 = sp2; + if (sp1 == NULL) sp1 = strrchr(filename, ':'); + if (sp1 == NULL) + sp1 = filename; + else + sp1++; /* The byte after the found character */ + /* Now, let's see if there's a type, and save the position in sp2 */ + sp2 = strchr(sp1, '.'); + /* If we found it, that's where we'll cut. Otherwise, look for a + version number and save the position in sp2 */ + if (sp2 == NULL) sp2 = strchr(sp1, ';'); + /* If there was still nothing to find, set sp2 to point at the end of + the string */ + if (sp2 == NULL) sp2 = sp1 + strlen(sp1); + + /* Check that we won't get buffer overflows */ + if (sp2 - sp1 > FILENAME_MAX + || (sp1 - filename) + strlen(sp2) > FILENAME_MAX) + { + DSOerr(DSO_F_VMS_LOAD,DSO_R_FILENAME_TOO_BIG); + return(0); + } + + p = (DSO_VMS_INTERNAL *)OPENSSL_malloc(sizeof(DSO_VMS_INTERNAL)); + if(p == NULL) + { + DSOerr(DSO_F_VMS_LOAD,ERR_R_MALLOC_FAILURE); + return(0); + } + + strncpy(p->filename, sp1, sp2-sp1); + p->filename[sp2-sp1] = '\0'; + + strncpy(p->imagename, filename, sp1-filename); + p->imagename[sp1-filename] = '\0'; + strcat(p->imagename, sp2); + + p->filename_dsc.dsc$w_length = strlen(p->filename); + p->filename_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + p->filename_dsc.dsc$b_class = DSC$K_CLASS_S; + p->filename_dsc.dsc$a_pointer = p->filename; + p->imagename_dsc.dsc$w_length = strlen(p->imagename); + p->imagename_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + p->imagename_dsc.dsc$b_class = DSC$K_CLASS_S; + p->imagename_dsc.dsc$a_pointer = p->imagename; + + if(!sk_push(dso->meth_data, (char *)p)) + { + DSOerr(DSO_F_VMS_LOAD,DSO_R_STACK_ERROR); + OPENSSL_free(p); + return(0); + } + return(1); + } + +/* Note that this doesn't actually unload the shared image, as there is no + * such thing in VMS. Next time it get loaded again, a new copy will + * actually be loaded. + */ +static int vms_unload(DSO *dso) + { + DSO_VMS_INTERNAL *p; + if(dso == NULL) + { + DSOerr(DSO_F_VMS_UNLOAD,ERR_R_PASSED_NULL_PARAMETER); + return(0); + } + if(sk_num(dso->meth_data) < 1) + return(1); + p = (DSO_VMS_INTERNAL *)sk_pop(dso->meth_data); + if(p == NULL) + { + DSOerr(DSO_F_VMS_UNLOAD,DSO_R_NULL_HANDLE); + return(0); + } + /* Cleanup */ + OPENSSL_free(p); + return(1); + } + +/* We must do this in a separate function because of the way the exception + handler works (it makes this function return */ +static int do_find_symbol(DSO_VMS_INTERNAL *ptr, + struct dsc$descriptor_s *symname_dsc, void **sym, + unsigned long flags) + { + /* Make sure that signals are caught and returned instead of + aborting the program. The exception handler gets unestablished + automatically on return from this function. */ + lib$establish(lib$sig_to_ret); + + if(ptr->imagename_dsc.dsc$w_length) + return lib$find_image_symbol(&ptr->filename_dsc, + symname_dsc, sym, + &ptr->imagename_dsc, flags); + else + return lib$find_image_symbol(&ptr->filename_dsc, + symname_dsc, sym, + 0, flags); + } + +void vms_bind_sym(DSO *dso, const char *symname, void **sym) + { + DSO_VMS_INTERNAL *ptr; + int status; + int flags = LIB$M_FIS_MIXEDCASE; + struct dsc$descriptor_s symname_dsc; + *sym = NULL; + + symname_dsc.dsc$w_length = strlen(symname); + symname_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + symname_dsc.dsc$b_class = DSC$K_CLASS_S; + symname_dsc.dsc$a_pointer = (char *)symname; /* The cast is needed */ + + if((dso == NULL) || (symname == NULL)) + { + DSOerr(DSO_F_VMS_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER); + return; + } + if(sk_num(dso->meth_data) < 1) + { + DSOerr(DSO_F_VMS_BIND_VAR,DSO_R_STACK_ERROR); + return; + } + ptr = (DSO_VMS_INTERNAL *)sk_value(dso->meth_data, + sk_num(dso->meth_data) - 1); + if(ptr == NULL) + { + DSOerr(DSO_F_VMS_BIND_VAR,DSO_R_NULL_HANDLE); + return; + } + + if(dso->flags & DSO_FLAG_UPCASE_SYMBOL) flags = 0; + + status = do_find_symbol(ptr, &symname_dsc, sym, flags); + + if(!$VMS_STATUS_SUCCESS(status)) + { + unsigned short length; + char errstring[257]; + struct dsc$descriptor_s errstring_dsc; + + errstring_dsc.dsc$w_length = sizeof(errstring); + errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + errstring_dsc.dsc$b_class = DSC$K_CLASS_S; + errstring_dsc.dsc$a_pointer = errstring; + + *sym = NULL; + + status = sys$getmsg(status, &length, &errstring_dsc, 1, 0); + + if (!$VMS_STATUS_SUCCESS(status)) + lib$signal(status); /* This is really bad. Abort! */ + else + { + errstring[length] = '\0'; + + DSOerr(DSO_F_VMS_BIND_VAR,DSO_R_SYM_FAILURE); + if (ptr->imagename_dsc.dsc$w_length) + ERR_add_error_data(9, + "Symbol ", symname, + " in ", ptr->filename, + " (", ptr->imagename, ")", + ": ", errstring); + else + ERR_add_error_data(6, + "Symbol ", symname, + " in ", ptr->filename, + ": ", errstring); + } + return; + } + return; + } + +static void *vms_bind_var(DSO *dso, const char *symname) + { + void *sym = 0; + vms_bind_sym(dso, symname, &sym); + return sym; + } + +static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname) + { + DSO_FUNC_TYPE sym = 0; + vms_bind_sym(dso, symname, (void **)&sym); + return sym; + } + +static long vms_ctrl(DSO *dso, int cmd, long larg, void *parg) + { + if(dso == NULL) + { + DSOerr(DSO_F_VMS_CTRL,ERR_R_PASSED_NULL_PARAMETER); + return(-1); + } + switch(cmd) + { + case DSO_CTRL_GET_FLAGS: + return dso->flags; + case DSO_CTRL_SET_FLAGS: + dso->flags = (int)larg; + return(0); + case DSO_CTRL_OR_FLAGS: + dso->flags |= (int)larg; + return(0); + default: + break; + } + DSOerr(DSO_F_VMS_CTRL,DSO_R_UNKNOWN_COMMAND); + return(-1); + } + +#endif /* VMS */ diff --git a/lib/libssl/src/crypto/dso/dso_win32.c b/lib/libssl/src/crypto/dso/dso_win32.c new file mode 100644 index 00000000000..7f1d9048061 --- /dev/null +++ b/lib/libssl/src/crypto/dso/dso_win32.c @@ -0,0 +1,273 @@ +/* dso_win32.c */ +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 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 + * 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). + * + */ + +#include +#include +#include "cryptlib.h" +#include + +#ifndef WIN32 +DSO_METHOD *DSO_METHOD_win32(void) + { + return NULL; + } +#else + +/* Part of the hack in "win32_load" ... */ +#define DSO_MAX_TRANSLATED_SIZE 256 + +static int win32_load(DSO *dso, const char *filename); +static int win32_unload(DSO *dso); +static void *win32_bind_var(DSO *dso, const char *symname); +static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname); +#if 0 +static int win32_unbind_var(DSO *dso, char *symname, void *symptr); +static int win32_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr); +static int win32_init(DSO *dso); +static int win32_finish(DSO *dso); +#endif +static long win32_ctrl(DSO *dso, int cmd, long larg, void *parg); + +static DSO_METHOD dso_meth_win32 = { + "OpenSSL 'win32' shared library method", + win32_load, + win32_unload, + win32_bind_var, + win32_bind_func, +/* For now, "unbind" doesn't exist */ +#if 0 + NULL, /* unbind_var */ + NULL, /* unbind_func */ +#endif + win32_ctrl, + NULL, /* init */ + NULL /* finish */ + }; + +DSO_METHOD *DSO_METHOD_win32(void) + { + return(&dso_meth_win32); + } + +/* For this DSO_METHOD, our meth_data STACK will contain; + * (i) a pointer to the handle (HINSTANCE) returned from + * LoadLibrary(), and copied. + */ + +static int win32_load(DSO *dso, const char *filename) + { + HINSTANCE h, *p; + char translated[DSO_MAX_TRANSLATED_SIZE]; + int len; + + /* NB: This is a hideous hack, but I'm not yet sure what + * to replace it with. This attempts to convert any filename, + * that looks like it has no path information, into a + * translated form, e. "blah" -> "blah.dll" ... I'm more + * comfortable putting hacks into win32 code though ;-) */ + len = strlen(filename); + if((dso->flags & DSO_FLAG_NAME_TRANSLATION) && + (len + 4 < DSO_MAX_TRANSLATED_SIZE) && + (strstr(filename, "/") == NULL) && + (strstr(filename, "\\") == NULL) && + (strstr(filename, ":") == NULL)) + { + sprintf(translated, "%s.dll", filename); + h = LoadLibrary(translated); + } + else + h = LoadLibrary(filename); + if(h == NULL) + { + DSOerr(DSO_F_WIN32_LOAD,DSO_R_LOAD_FAILED); + return(0); + } + p = (HINSTANCE *)OPENSSL_malloc(sizeof(HINSTANCE)); + if(p == NULL) + { + DSOerr(DSO_F_WIN32_LOAD,ERR_R_MALLOC_FAILURE); + FreeLibrary(h); + return(0); + } + *p = h; + if(!sk_push(dso->meth_data, (char *)p)) + { + DSOerr(DSO_F_WIN32_LOAD,DSO_R_STACK_ERROR); + FreeLibrary(h); + OPENSSL_free(p); + return(0); + } + return(1); + } + +static int win32_unload(DSO *dso) + { + HINSTANCE *p; + if(dso == NULL) + { + DSOerr(DSO_F_WIN32_UNLOAD,ERR_R_PASSED_NULL_PARAMETER); + return(0); + } + if(sk_num(dso->meth_data) < 1) + return(1); + p = (HINSTANCE *)sk_pop(dso->meth_data); + if(p == NULL) + { + DSOerr(DSO_F_WIN32_UNLOAD,DSO_R_NULL_HANDLE); + return(0); + } + if(!FreeLibrary(*p)) + { + DSOerr(DSO_F_WIN32_UNLOAD,DSO_R_UNLOAD_FAILED); + /* We should push the value back onto the stack in + * case of a retry. */ + sk_push(dso->meth_data, (char *)p); + return(0); + } + /* Cleanup */ + OPENSSL_free(p); + return(1); + } + +/* Using GetProcAddress for variables? TODO: Check this out in + * the Win32 API docs, there's probably a variant for variables. */ +static void *win32_bind_var(DSO *dso, const char *symname) + { + HINSTANCE *ptr; + void *sym; + + if((dso == NULL) || (symname == NULL)) + { + DSOerr(DSO_F_WIN32_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER); + return(NULL); + } + if(sk_num(dso->meth_data) < 1) + { + DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_STACK_ERROR); + return(NULL); + } + ptr = (HINSTANCE *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); + if(ptr == NULL) + { + DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_NULL_HANDLE); + return(NULL); + } + sym = GetProcAddress(*ptr, symname); + if(sym == NULL) + { + DSOerr(DSO_F_WIN32_BIND_VAR,DSO_R_SYM_FAILURE); + return(NULL); + } + return(sym); + } + +static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname) + { + HINSTANCE *ptr; + void *sym; + + if((dso == NULL) || (symname == NULL)) + { + DSOerr(DSO_F_WIN32_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER); + return(NULL); + } + if(sk_num(dso->meth_data) < 1) + { + DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_STACK_ERROR); + return(NULL); + } + ptr = (HINSTANCE *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); + if(ptr == NULL) + { + DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_NULL_HANDLE); + return(NULL); + } + sym = GetProcAddress(*ptr, symname); + if(sym == NULL) + { + DSOerr(DSO_F_WIN32_BIND_FUNC,DSO_R_SYM_FAILURE); + return(NULL); + } + return((DSO_FUNC_TYPE)sym); + } + +static long win32_ctrl(DSO *dso, int cmd, long larg, void *parg) + { + if(dso == NULL) + { + DSOerr(DSO_F_WIN32_CTRL,ERR_R_PASSED_NULL_PARAMETER); + return(-1); + } + switch(cmd) + { + case DSO_CTRL_GET_FLAGS: + return dso->flags; + case DSO_CTRL_SET_FLAGS: + dso->flags = (int)larg; + return(0); + case DSO_CTRL_OR_FLAGS: + dso->flags |= (int)larg; + return(0); + default: + break; + } + DSOerr(DSO_F_WIN32_CTRL,DSO_R_UNKNOWN_COMMAND); + return(-1); + } + +#endif /* WIN32 */ diff --git a/lib/libssl/src/crypto/engine/Makefile.ssl b/lib/libssl/src/crypto/engine/Makefile.ssl new file mode 100644 index 00000000000..7a0ffe755d9 --- /dev/null +++ b/lib/libssl/src/crypto/engine/Makefile.ssl @@ -0,0 +1,220 @@ +# +# OpenSSL/crypto/engine/Makefile +# + +DIR= engine +TOP= ../.. +CC= cc +INCLUDES= -I.. -I../../include +CFLAG=-g +INSTALL_PREFIX= +OPENSSLDIR= /usr/local/ssl +INSTALLTOP=/usr/local/ssl +MAKE= make -f Makefile.ssl +MAKEDEPEND= $(TOP)/util/domd $(TOP) +MAKEFILE= Makefile.ssl +AR= ar r + +CFLAGS= $(INCLUDES) $(CFLAG) + +GENERAL=Makefile +TEST= enginetest.c +APPS= + +LIB=$(TOP)/libcrypto.a +LIBSRC= engine_err.c engine_lib.c engine_list.c engine_openssl.c \ + hw_atalla.c hw_cswift.c hw_ncipher.c +LIBOBJ= engine_err.o engine_lib.o engine_list.o engine_openssl.o \ + hw_atalla.o hw_cswift.o hw_ncipher.o + +SRC= $(LIBSRC) + +EXHEADER= engine.h +HEADER= $(EXHEADER) + +ALL= $(GENERAL) $(SRC) $(HEADER) + +top: + (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all) + +all: lib + +lib: $(LIBOBJ) + $(AR) $(LIB) $(LIBOBJ) + $(RANLIB) $(LIB) + @touch lib + +files: + $(PERL) $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO + +links: + @$(TOP)/util/point.sh Makefile.ssl Makefile + @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST) + @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS) + +install: + @for i in $(EXHEADER) ; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done; + +tags: + ctags $(SRC) + +tests: + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + $(MAKEDEPEND) $(INCLUDES) $(DEPFLAG) $(PROGS) $(LIBSRC) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +engine_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +engine_err.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h +engine_err.o: ../../include/openssl/cast.h ../../include/openssl/crypto.h +engine_err.o: ../../include/openssl/des.h ../../include/openssl/dh.h +engine_err.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h +engine_err.o: ../../include/openssl/engine.h ../../include/openssl/err.h +engine_err.o: ../../include/openssl/evp.h ../../include/openssl/idea.h +engine_err.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h +engine_err.o: ../../include/openssl/md4.h ../../include/openssl/md5.h +engine_err.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h +engine_err.o: ../../include/openssl/objects.h +engine_err.o: ../../include/openssl/opensslconf.h +engine_err.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h +engine_err.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h +engine_err.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h +engine_err.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h +engine_err.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +engine_err.o: ../../include/openssl/symhacks.h +engine_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +engine_lib.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h +engine_lib.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h +engine_lib.o: ../../include/openssl/crypto.h ../../include/openssl/des.h +engine_lib.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +engine_lib.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h +engine_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h +engine_lib.o: ../../include/openssl/evp.h ../../include/openssl/idea.h +engine_lib.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h +engine_lib.o: ../../include/openssl/md4.h ../../include/openssl/md5.h +engine_lib.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h +engine_lib.o: ../../include/openssl/objects.h +engine_lib.o: ../../include/openssl/opensslconf.h +engine_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h +engine_lib.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h +engine_lib.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h +engine_lib.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h +engine_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +engine_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h +engine_list.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +engine_list.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h +engine_list.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h +engine_list.o: ../../include/openssl/crypto.h ../../include/openssl/des.h +engine_list.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +engine_list.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h +engine_list.o: ../../include/openssl/engine.h ../../include/openssl/err.h +engine_list.o: ../../include/openssl/evp.h ../../include/openssl/idea.h +engine_list.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h +engine_list.o: ../../include/openssl/md4.h ../../include/openssl/md5.h +engine_list.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h +engine_list.o: ../../include/openssl/objects.h +engine_list.o: ../../include/openssl/opensslconf.h +engine_list.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h +engine_list.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h +engine_list.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h +engine_list.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h +engine_list.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +engine_list.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h +engine_openssl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +engine_openssl.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h +engine_openssl.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h +engine_openssl.o: ../../include/openssl/crypto.h ../../include/openssl/des.h +engine_openssl.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +engine_openssl.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h +engine_openssl.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h +engine_openssl.o: ../../include/openssl/err.h ../../include/openssl/evp.h +engine_openssl.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h +engine_openssl.o: ../../include/openssl/md2.h ../../include/openssl/md4.h +engine_openssl.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h +engine_openssl.o: ../../include/openssl/obj_mac.h +engine_openssl.o: ../../include/openssl/objects.h +engine_openssl.o: ../../include/openssl/opensslconf.h +engine_openssl.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h +engine_openssl.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h +engine_openssl.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h +engine_openssl.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h +engine_openssl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +engine_openssl.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h +hw_atalla.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +hw_atalla.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h +hw_atalla.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h +hw_atalla.o: ../../include/openssl/crypto.h ../../include/openssl/des.h +hw_atalla.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +hw_atalla.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h +hw_atalla.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h +hw_atalla.o: ../../include/openssl/err.h ../../include/openssl/evp.h +hw_atalla.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h +hw_atalla.o: ../../include/openssl/md2.h ../../include/openssl/md4.h +hw_atalla.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h +hw_atalla.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +hw_atalla.o: ../../include/openssl/opensslconf.h +hw_atalla.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h +hw_atalla.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h +hw_atalla.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h +hw_atalla.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h +hw_atalla.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +hw_atalla.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h +hw_atalla.o: vendor_defns/atalla.h +hw_cswift.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +hw_cswift.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h +hw_cswift.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h +hw_cswift.o: ../../include/openssl/crypto.h ../../include/openssl/des.h +hw_cswift.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +hw_cswift.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h +hw_cswift.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h +hw_cswift.o: ../../include/openssl/err.h ../../include/openssl/evp.h +hw_cswift.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h +hw_cswift.o: ../../include/openssl/md2.h ../../include/openssl/md4.h +hw_cswift.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h +hw_cswift.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +hw_cswift.o: ../../include/openssl/opensslconf.h +hw_cswift.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h +hw_cswift.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h +hw_cswift.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h +hw_cswift.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h +hw_cswift.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +hw_cswift.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h +hw_cswift.o: vendor_defns/cswift.h +hw_ncipher.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +hw_ncipher.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h +hw_ncipher.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h +hw_ncipher.o: ../../include/openssl/crypto.h ../../include/openssl/des.h +hw_ncipher.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +hw_ncipher.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h +hw_ncipher.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h +hw_ncipher.o: ../../include/openssl/err.h ../../include/openssl/evp.h +hw_ncipher.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h +hw_ncipher.o: ../../include/openssl/md2.h ../../include/openssl/md4.h +hw_ncipher.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h +hw_ncipher.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +hw_ncipher.o: ../../include/openssl/opensslconf.h +hw_ncipher.o: ../../include/openssl/opensslv.h ../../include/openssl/pem.h +hw_ncipher.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h +hw_ncipher.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h +hw_ncipher.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h +hw_ncipher.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h +hw_ncipher.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +hw_ncipher.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +hw_ncipher.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h +hw_ncipher.o: ../cryptlib.h engine_int.h vendor_defns/hwcryptohook.h diff --git a/lib/libssl/src/crypto/engine/README b/lib/libssl/src/crypto/engine/README new file mode 100644 index 00000000000..96595e6f35a --- /dev/null +++ b/lib/libssl/src/crypto/engine/README @@ -0,0 +1,278 @@ +NOTES, THOUGHTS, and EVERYTHING +------------------------------- + +(1) Concurrency and locking ... I made a change to the ENGINE_free code + because I spotted a potential hold-up in proceedings (doing too + much inside a lock including calling a callback), there may be + other bits like this. What do the speed/optimisation freaks think + of this aspect of the code and design? There's lots of locking for + manipulation functions and I need that to keep things nice and + solid, but this manipulation is mostly (de)initialisation, I would + think that most run-time locking is purely in the ENGINE_init and + ENGINE_finish calls that might be made when getting handles for + RSA (and friends') structures. These would be mostly reference + count operations as the functional references should always be 1 + or greater at run-time to prevent init/deinit thrashing. + +(2) nCipher support, via the HWCryptoHook API, is now in the code. + Apparently this hasn't been tested too much yet, but it looks + good. :-) Atalla support has been added too, but shares a lot in + common with Ben's original hooks in bn_exp.c (although it has been + ENGINE-ified, and error handling wrapped around it) and it's also + had some low-volume testing, so it should be usable. + +(3) Of more concern, we need to work out (a) how to put together usable + RAND_METHODs for units that just have one "get n or less random + bytes" function, (b) we also need to determine how to hook the code + in crypto/rand/ to use the ENGINE defaults in a way similar to what + has been done in crypto/rsa/, crypto/dsa/, etc. + +(4) ENGINE should really grow to encompass more than 3 public key + algorithms and randomness gathering. The structure/data level of + the engine code is hidden from code outside the crypto/engine/ + directory so change shouldn't be too viral. More important though + is how things should evolve ... this needs thought and discussion. + + +-----------------------------------==*==----------------------------------- + +More notes 2000-08-01 +--------------------- + +Geoff Thorpe, who designed the engine part, wrote a pretty good description +of the thoughts he had when he built it, good enough to include verbatim here +(with his permission) -- Richard Levitte + + +Date: Tue, 1 Aug 2000 16:54:08 +0100 (BST) +From: Geoff Thorpe +Subject: Re: The thoughts to merge BRANCH_engine into the main trunk are + emerging + +Hi there, + +I'm going to try and do some justice to this, but I'm a little short on +time and the there is an endless amount that could be discussed on this +subject. sigh ... please bear with me :-) + +> The changes in BRANCH_engine dig deep into the core of OpenSSL, for example +> into the RSA and RAND routines, adding a level of indirection which is needed +> to keep the abstraction, as far as I understand. It would be a good thing if +> those who do play with those things took a look at the changes that have been +> done in the branch and say out loud how much (or hopefully little) we've made +> fools of ourselves. + +The point here is that the code that has emerged in the BRANCH_engine +branch was based on some initial requirements of mine that I went in and +addressed, and Richard has picked up the ball and run with it too. It +would be really useful to get some review of the approach we've taken, but +first I think I need to describe as best I can the reasons behind what has +been done so far, in particular what issues we have tried to address when +doing this, and what issues we have intentionally (or necessarily) tried +to avoid. + +methods, engines, and evps +-------------------------- + +There has been some dicussion, particularly with Steve, about where this +ENGINE stuff might fit into the conceptual picture as/when we start to +abstract algorithms a little bit to make the library more extensible. In +particular, it would desirable to have algorithms (symmetric, hash, pkc, +etc) abstracted in some way that allows them to be just objects sitting in +a list (or database) ... it'll just happen that the "DSA" object doesn't +support encryption whereas the "RSA" object does. This requires a lot of +consideration to begin to know how to tackle it; in particular how +encapsulated should these things be? If the objects also understand their +own ASN1 encodings and what-not, then it would for example be possible to +add support for elliptic-curve DSA in as a new algorithm and automatically +have ECC-DSA certificates supported in SSL applications. Possible, but not +easy. :-) + +Whatever, it seems that the way to go (if I've grok'd Steve's comments on +this in the past) is to amalgamate these things in EVP as is already done +(I think) for ciphers or hashes (Steve, please correct/elaborate). I +certainly think something should be done in this direction because right +now we have different source directories, types, functions, and methods +for each algorithm - even when conceptually they are very much different +feathers of the same bird. (This is certainly all true for the public-key +stuff, and may be partially true for the other parts.) + +ENGINE was *not* conceived as a way of solving this, far from it. Nor was +it conceived as a way of replacing the various "***_METHOD"s. It was +conceived as an abstraction of a sort of "virtual crypto device". If we +lived in a world where "EVP_ALGO"s (or something like them) encapsulated +particular algorithms like RSA,DSA,MD5,RC4,etc, and "***_METHOD"s +encapsulated interfaces to algorithms (eg. some algo's might support a +PKC_METHOD, a HASH_METHOD, or a CIPHER_METHOD, who knows?), then I would +think that ENGINE would encapsulate an implementation of arbitrarily many +of those algorithms - perhaps as alternatives to existing algorithms +and/or perhaps as new previously unimplemented algorithms. An ENGINE could +be used to contain an alternative software implementation, a wrapper for a +hardware acceleration and/or key-management unit, a comms-wrapper for +distributing cryptographic operations to remote machines, or any other +"devices" your imagination can dream up. + +However, what has been done in the ENGINE branch so far is nothing more +than starting to get our toes wet. I had a couple of self-imposed +requirements when putting the initial abstraction together, and I may have +already posed these in one form or another on the list, but briefly; + + (i) only bother with public key algorithms for now, and maybe RAND too + (motivated by the need to get hardware support going and the fact + this was a comparitively easy subset to address to begin with). + + (ii) don't change (if at all possible) the existing crypto code, ie. the + implementations, the way the ***_METHODs work, etc. + + (iii) ensure that if no function from the ENGINE code is ever called then + things work the way they always did, and there is no memory + allocation (otherwise the failure to cleanup would be a problem - + this is part of the reason no STACKs were used, the other part of + the reason being I found them inappropriate). + + (iv) ensure that all the built-in crypto was encapsulated by one of + these "ENGINE"s and that this engine was automatically selected as + the default. + + (v) provide the minimum hooking possible in the existing crypto code + so that global functions (eg. RSA_public_encrypt) do not need any + extra parameter, yet will use whatever the current default ENGINE + for that RSA key is, and that the default can be set "per-key" + and globally (new keys will assume the global default, and keys + without their own default will be operated on using the global + default). NB: Try and make (v) conflict as little as possible with + (ii). :-) + + (vi) wrap the ENGINE code up in duct tape so you can't even see the + corners. Ie. expose no structures at all, just black-box pointers. + + (v) maintain internally a list of ENGINEs on which a calling + application can iterate, interrogate, etc. Allow a calling + application to hook in new ENGINEs, remove ENGINEs from the list, + and enforce uniqueness within the global list of each ENGINE's + "unique id". + + (vi) keep reference counts for everything - eg. this includes storing a + reference inside each RSA structure to the ENGINE that it uses. + This is freed when the RSA structure is destroyed, or has its + ENGINE explicitly changed. The net effect needs to be that at any + time, it is deterministic to know whether an ENGINE is in use or + can be safely removed (or unloaded in the case of the other type + of reference) without invalidating function pointers that may or + may not be used indavertently in the future. This was actually + one of the biggest problems to overcome in the existing OpenSSL + code - implementations had always been assumed to be ever-present, + so there was no trivial way to get round this. + + (vii) distinguish between structural references and functional + references. + +A *little* detail +----------------- + +While my mind is on it; I'll illustrate the bit in item (vii). This idea +turned out to be very handy - the ENGINEs themselves need to be operated +on and manipulated simply as objects without necessarily trying to +"enable" them for use. Eg. most host machines will not have the necessary +hardware or software to support all the engines one might compile into +OpenSSL, yet it needs to be possible to iterate across the ENGINEs, +querying their names, properties, etc - all happening in a thread-safe +manner that uses reference counts (if you imagine two threads iterating +through a list and one thread removing the ENGINE the other is currently +looking at - you can see the gotcha waiting to happen). For all of this, +*structural references* are used and operate much like the other reference +counts in OpenSSL. + +The other kind of reference count is for *functional* references - these +indicate a reference on which the caller can actually assume the +particular ENGINE to be initialised and usable to perform the operations +it implements. Any increment or decrement of the functional reference +count automatically invokes a corresponding change in the structural +reference count, as it is fairly obvious that a functional reference is a +restricted case of a structural reference. So struct_ref >= funct_ref at +all times. NB: functional references are usually obtained by a call to +ENGINE_init(), but can also be created implicitly by calls that require a +new functional reference to be created, eg. ENGINE_set_default(). Either +way the only time the underlying ENGINE's "init" function is really called +is when the (functional) reference count increases to 1, similarly the +underlying "finish" handler is only called as the count goes down to 0. +The effect of this, for example, is that if you set the default ENGINE for +RSA operations to be "cswift", then its functional reference count will +already be at least 1 so the CryptoSwift shared-library and the card will +stay loaded and initialised until such time as all RSA keys using the +cswift ENGINE are changed or destroyed and the default ENGINE for RSA +operations has been changed. This prevents repeated thrashing of init and +finish handling if the count keeps getting down as far as zero. + +Otherwise, the way the ENGINE code has been put together I think pretty +much reflects the above points. The reason for the ENGINE structure having +individual RSA_METHOD, DSA_METHOD, etc pointers is simply that it was the +easiest way to go about things for now, to hook it all into the raw +RSA,DSA,etc code, and I was trying to the keep the structure invisible +anyway so that the way this is internally managed could be easily changed +later on when we start to work out what's to be done about these other +abstractions. + +Down the line, if some EVP-based technique emerges for adequately +encapsulating algorithms and all their various bits and pieces, then I can +imagine that "ENGINE" would turn into a reference-counting database of +these EVP things, of which the default "openssl" ENGINE would be the +library's own object database of pre-built software implemented algorithms +(and such). It would also be cool to see the idea of "METHOD"s detached +from the algorithms themselves ... so RSA, DSA, ElGamal, etc can all +expose essentially the same METHOD (aka interface), which would include +any querying/flagging stuff to identify what the algorithm can/can't do, +its name, and other stuff like max/min block sizes, key sizes, etc. This +would result in ENGINE similarly detaching its internal database of +algorithm implementations from the function definitions that return +interfaces to them. I think ... + +As for DSOs etc. Well the DSO code is pretty handy (but could be made much +more so) for loading vendor's driver-libraries and talking to them in some +generic way, but right now there's still big problems associated with +actually putting OpenSSL code (ie. new ENGINEs, or anything else for that +matter) in dynamically loadable libraries. These problems won't go away in +a hurry so I don't think we should expect to have any kind of +shared-library extensions any time soon - but solving the problems is a +good thing to aim for, and would as a side-effect probably help make +OpenSSL more usable as a shared-library itself (looking at the things +needed to do this will show you why). + +One of the problems is that if you look at any of the ENGINE +implementations, eg. hw_cswift.c or hw_ncipher.c, you'll see how it needs +a variety of functionality and definitions from various areas of OpenSSL, +including crypto/bn/, crypto/err/, crypto/ itself (locking for example), +crypto/dso/, crypto/engine/, crypto/rsa, etc etc etc. So if similar code +were to be suctioned off into shared libraries, the shared libraries would +either have to duplicate all the definitions and code and avoid loader +conflicts, or OpenSSL would have to somehow expose all that functionality +to the shared-library. If this isn't a big enough problem, the issue of +binary compatibility will be - anyone writing Apache modules can tell you +that (Ralf? Ben? :-). However, I don't think OpenSSL would need to be +quite so forgiving as Apache should be, so OpenSSL could simply tell its +version to the DSO and leave the DSO with the problem of deciding whether +to proceed or bail out for fear of binary incompatibilities. + +Certainly one thing that would go a long way to addressing this is to +embark on a bit of an opaqueness mission. I've set the ENGINE code up with +this in mind - it's so draconian that even to declare your own ENGINE, you +have to get the engine code to create the underlying ENGINE structure, and +then feed in the new ENGINE's function/method pointers through various +"set" functions. The more of the code that takes on such a black-box +approach, the more of the code that will be (a) easy to expose to shared +libraries that need it, and (b) easy to expose to applications wanting to +use OpenSSL itself as a shared-library. From my own explorations in +OpenSSL, the biggest leviathan I've seen that is a problem in this respect +is the BIGNUM code. Trying to "expose" the bignum code through any kind of +organised "METHODs", let alone do all the necessary bignum operations +solely through functions rather than direct access to the structures and +macros, will be a massive pain in the "r"s. + +Anyway, I'm done for now - hope it was readable. Thoughts? + +Cheers, +Geoff + + +-----------------------------------==*==----------------------------------- + diff --git a/lib/libssl/src/crypto/engine/engine.h b/lib/libssl/src/crypto/engine/engine.h new file mode 100644 index 00000000000..2983f47034e --- /dev/null +++ b/lib/libssl/src/crypto/engine/engine.h @@ -0,0 +1,398 @@ +/* openssl/engine.h */ +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) 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). + * + */ + +#ifndef HEADER_ENGINE_H +#define HEADER_ENGINE_H + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* These flags are used to control combinations of algorithm (methods) + * by bitwise "OR"ing. */ +#define ENGINE_METHOD_RSA (unsigned int)0x0001 +#define ENGINE_METHOD_DSA (unsigned int)0x0002 +#define ENGINE_METHOD_DH (unsigned int)0x0004 +#define ENGINE_METHOD_RAND (unsigned int)0x0008 +#define ENGINE_METHOD_BN_MOD_EXP (unsigned int)0x0010 +#define ENGINE_METHOD_BN_MOD_EXP_CRT (unsigned int)0x0020 +/* Obvious all-or-nothing cases. */ +#define ENGINE_METHOD_ALL (unsigned int)0xFFFF +#define ENGINE_METHOD_NONE (unsigned int)0x0000 + +/* These flags are used to tell the ctrl function what should be done. + * All command numbers are shared between all engines, even if some don't + * make sense to some engines. In such a case, they do nothing but return + * the error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. */ +#define ENGINE_CTRL_SET_LOGSTREAM 1 +#define ENGINE_CTRL_SET_PASSWORD_CALLBACK 2 +/* Flags specific to the nCipher "chil" engine */ +#define ENGINE_CTRL_CHIL_SET_FORKCHECK 100 + /* Depending on the value of the (long)i argument, this sets or + * unsets the SimpleForkCheck flag in the CHIL API to enable or + * disable checking and workarounds for applications that fork(). + */ +#define ENGINE_CTRL_CHIL_NO_LOCKING 101 + /* This prevents the initialisation function from providing mutex + * callbacks to the nCipher library. */ + +/* As we're missing a BIGNUM_METHOD, we need a couple of locally + * defined function types that engines can implement. */ + +#ifndef HEADER_ENGINE_INT_H +/* mod_exp operation, calculates; r = a ^ p mod m + * NB: ctx can be NULL, but if supplied, the implementation may use + * it if it wishes. */ +typedef int (*BN_MOD_EXP)(BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); + +/* private key operation for RSA, provided seperately in case other + * RSA implementations wish to use it. */ +typedef int (*BN_MOD_EXP_CRT)(BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1, + const BIGNUM *iqmp, BN_CTX *ctx); + +/* Generic function pointer */ +typedef void (*ENGINE_GEN_FUNC_PTR)(); +/* Generic function pointer taking no arguments */ +typedef void (*ENGINE_GEN_INT_FUNC_PTR)(void); +/* Specific control function pointer */ +typedef int (*ENGINE_CTRL_FUNC_PTR)(int cmd, long i, void *p, void (*f)()); + +/* The list of "engine" types is a static array of (const ENGINE*) + * pointers (not dynamic because static is fine for now and we otherwise + * have to hook an appropriate load/unload function in to initialise and + * cleanup). */ +typedef struct engine_st ENGINE; +#endif + +/* STRUCTURE functions ... all of these functions deal with pointers to + * ENGINE structures where the pointers have a "structural reference". + * This means that their reference is to allow access to the structure + * but it does not imply that the structure is functional. To simply + * increment or decrement the structural reference count, use ENGINE_new + * and ENGINE_free. NB: This is not required when iterating using + * ENGINE_get_next as it will automatically decrement the structural + * reference count of the "current" ENGINE and increment the structural + * reference count of the ENGINE it returns (unless it is NULL). */ + +/* Get the first/last "ENGINE" type available. */ +ENGINE *ENGINE_get_first(void); +ENGINE *ENGINE_get_last(void); +/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */ +ENGINE *ENGINE_get_next(ENGINE *e); +ENGINE *ENGINE_get_prev(ENGINE *e); +/* Add another "ENGINE" type into the array. */ +int ENGINE_add(ENGINE *e); +/* Remove an existing "ENGINE" type from the array. */ +int ENGINE_remove(ENGINE *e); +/* Retrieve an engine from the list by its unique "id" value. */ +ENGINE *ENGINE_by_id(const char *id); + +/* These functions are useful for manufacturing new ENGINE + * structures. They don't address reference counting at all - + * one uses them to populate an ENGINE structure with personalised + * implementations of things prior to using it directly or adding + * it to the builtin ENGINE list in OpenSSL. These are also here + * so that the ENGINE structure doesn't have to be exposed and + * break binary compatibility! + * + * NB: I'm changing ENGINE_new to force the ENGINE structure to + * be allocated from within OpenSSL. See the comment for + * ENGINE_get_struct_size(). + */ +#if 0 +ENGINE *ENGINE_new(ENGINE *e); +#else +ENGINE *ENGINE_new(void); +#endif +int ENGINE_free(ENGINE *e); +int ENGINE_set_id(ENGINE *e, const char *id); +int ENGINE_set_name(ENGINE *e, const char *name); +int ENGINE_set_RSA(ENGINE *e, RSA_METHOD *rsa_meth); +int ENGINE_set_DSA(ENGINE *e, DSA_METHOD *dsa_meth); +int ENGINE_set_DH(ENGINE *e, DH_METHOD *dh_meth); +int ENGINE_set_RAND(ENGINE *e, RAND_METHOD *rand_meth); +int ENGINE_set_BN_mod_exp(ENGINE *e, BN_MOD_EXP bn_mod_exp); +int ENGINE_set_BN_mod_exp_crt(ENGINE *e, BN_MOD_EXP_CRT bn_mod_exp_crt); +int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f); +int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f); +int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f); + +/* These return values from within the ENGINE structure. These can + * be useful with functional references as well as structural + * references - it depends which you obtained. Using the result + * for functional purposes if you only obtained a structural + * reference may be problematic! */ +const char *ENGINE_get_id(ENGINE *e); +const char *ENGINE_get_name(ENGINE *e); +RSA_METHOD *ENGINE_get_RSA(ENGINE *e); +DSA_METHOD *ENGINE_get_DSA(ENGINE *e); +DH_METHOD *ENGINE_get_DH(ENGINE *e); +RAND_METHOD *ENGINE_get_RAND(ENGINE *e); +BN_MOD_EXP ENGINE_get_BN_mod_exp(ENGINE *e); +BN_MOD_EXP_CRT ENGINE_get_BN_mod_exp_crt(ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(ENGINE *e); +ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(ENGINE *e); + +/* ENGINE_new is normally passed a NULL in the first parameter because + * the calling code doesn't have access to the definition of the ENGINE + * structure (for good reason). However, if the caller wishes to use + * its own memory allocation or use a static array, the following call + * should be used to check the amount of memory the ENGINE structure + * will occupy. This will make the code more future-proof. + * + * NB: I'm "#if 0"-ing this out because it's better to force the use of + * internally allocated memory. See similar change in ENGINE_new(). + */ +#if 0 +int ENGINE_get_struct_size(void); +#endif + +/* FUNCTIONAL functions. These functions deal with ENGINE structures + * that have (or will) be initialised for use. Broadly speaking, the + * structural functions are useful for iterating the list of available + * engine types, creating new engine types, and other "list" operations. + * These functions actually deal with ENGINEs that are to be used. As + * such these functions can fail (if applicable) when particular + * engines are unavailable - eg. if a hardware accelerator is not + * attached or not functioning correctly. Each ENGINE has 2 reference + * counts; structural and functional. Every time a functional reference + * is obtained or released, a corresponding structural reference is + * automatically obtained or released too. */ + +/* Initialise a engine type for use (or up its reference count if it's + * already in use). This will fail if the engine is not currently + * operational and cannot initialise. */ +int ENGINE_init(ENGINE *e); +/* Free a functional reference to a engine type. This does not require + * a corresponding call to ENGINE_free as it also releases a structural + * reference. */ +int ENGINE_finish(ENGINE *e); +/* Send control parametrised commands to the engine. The possibilities + * to send down an integer, a pointer to data or a function pointer are + * provided. Any of the parameters may or may not be NULL, depending + * on the command number */ +/* WARNING: This is currently experimental and may change radically! */ +int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()); + +/* The following functions handle keys that are stored in some secondary + * location, handled by the engine. The storage may be on a card or + * whatever. */ +EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, + const char *passphrase); +EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, + const char *passphrase); + +/* This returns a pointer for the current ENGINE structure that + * is (by default) performing any RSA operations. The value returned + * is an incremented reference, so it should be free'd (ENGINE_finish) + * before it is discarded. */ +ENGINE *ENGINE_get_default_RSA(void); +/* Same for the other "methods" */ +ENGINE *ENGINE_get_default_DSA(void); +ENGINE *ENGINE_get_default_DH(void); +ENGINE *ENGINE_get_default_RAND(void); +ENGINE *ENGINE_get_default_BN_mod_exp(void); +ENGINE *ENGINE_get_default_BN_mod_exp_crt(void); + +/* This sets a new default ENGINE structure for performing RSA + * operations. If the result is non-zero (success) then the ENGINE + * structure will have had its reference count up'd so the caller + * should still free their own reference 'e'. */ +int ENGINE_set_default_RSA(ENGINE *e); +/* Same for the other "methods" */ +int ENGINE_set_default_DSA(ENGINE *e); +int ENGINE_set_default_DH(ENGINE *e); +int ENGINE_set_default_RAND(ENGINE *e); +int ENGINE_set_default_BN_mod_exp(ENGINE *e); +int ENGINE_set_default_BN_mod_exp_crt(ENGINE *e); + +/* The combination "set" - the flags are bitwise "OR"d from the + * ENGINE_METHOD_*** defines above. */ +int ENGINE_set_default(ENGINE *e, unsigned int flags); + +/* Obligatory error function. */ +void ERR_load_ENGINE_strings(void); + +/* + * Error codes for all engine functions. NB: We use "generic" + * function names instead of per-implementation ones because this + * levels the playing field for externally implemented bootstrapped + * support code. As the filename and line number is included, it's + * more important to indicate the type of function, so that + * bootstrapped code (that can't easily add its own errors in) can + * use the same error codes too. + */ + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ + +/* Error codes for the ENGINE functions. */ + +/* Function codes. */ +#define ENGINE_F_ATALLA_FINISH 135 +#define ENGINE_F_ATALLA_INIT 136 +#define ENGINE_F_ATALLA_MOD_EXP 137 +#define ENGINE_F_ATALLA_RSA_MOD_EXP 138 +#define ENGINE_F_CSWIFT_DSA_SIGN 133 +#define ENGINE_F_CSWIFT_DSA_VERIFY 134 +#define ENGINE_F_CSWIFT_FINISH 100 +#define ENGINE_F_CSWIFT_INIT 101 +#define ENGINE_F_CSWIFT_MOD_EXP 102 +#define ENGINE_F_CSWIFT_MOD_EXP_CRT 103 +#define ENGINE_F_CSWIFT_RSA_MOD_EXP 104 +#define ENGINE_F_ENGINE_ADD 105 +#define ENGINE_F_ENGINE_BY_ID 106 +#define ENGINE_F_ENGINE_CTRL 142 +#define ENGINE_F_ENGINE_FINISH 107 +#define ENGINE_F_ENGINE_FREE 108 +#define ENGINE_F_ENGINE_GET_BN_MOD_EXP 109 +#define ENGINE_F_ENGINE_GET_BN_MOD_EXP_CRT 110 +#define ENGINE_F_ENGINE_GET_CTRL_FUNCTION 144 +#define ENGINE_F_ENGINE_GET_DH 111 +#define ENGINE_F_ENGINE_GET_DSA 112 +#define ENGINE_F_ENGINE_GET_FINISH_FUNCTION 145 +#define ENGINE_F_ENGINE_GET_ID 113 +#define ENGINE_F_ENGINE_GET_INIT_FUNCTION 146 +#define ENGINE_F_ENGINE_GET_NAME 114 +#define ENGINE_F_ENGINE_GET_NEXT 115 +#define ENGINE_F_ENGINE_GET_PREV 116 +#define ENGINE_F_ENGINE_GET_RAND 117 +#define ENGINE_F_ENGINE_GET_RSA 118 +#define ENGINE_F_ENGINE_INIT 119 +#define ENGINE_F_ENGINE_LIST_ADD 120 +#define ENGINE_F_ENGINE_LIST_REMOVE 121 +#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150 +#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151 +#define ENGINE_F_ENGINE_NEW 122 +#define ENGINE_F_ENGINE_REMOVE 123 +#define ENGINE_F_ENGINE_SET_BN_MOD_EXP 124 +#define ENGINE_F_ENGINE_SET_BN_MOD_EXP_CRT 125 +#define ENGINE_F_ENGINE_SET_CTRL_FUNCTION 147 +#define ENGINE_F_ENGINE_SET_DEFAULT_TYPE 126 +#define ENGINE_F_ENGINE_SET_DH 127 +#define ENGINE_F_ENGINE_SET_DSA 128 +#define ENGINE_F_ENGINE_SET_FINISH_FUNCTION 148 +#define ENGINE_F_ENGINE_SET_ID 129 +#define ENGINE_F_ENGINE_SET_INIT_FUNCTION 149 +#define ENGINE_F_ENGINE_SET_NAME 130 +#define ENGINE_F_ENGINE_SET_RAND 131 +#define ENGINE_F_ENGINE_SET_RSA 132 +#define ENGINE_F_ENGINE_UNLOAD_KEY 152 +#define ENGINE_F_HWCRHK_CTRL 143 +#define ENGINE_F_HWCRHK_FINISH 135 +#define ENGINE_F_HWCRHK_GET_PASS 155 +#define ENGINE_F_HWCRHK_INIT 136 +#define ENGINE_F_HWCRHK_LOAD_PRIVKEY 153 +#define ENGINE_F_HWCRHK_LOAD_PUBKEY 154 +#define ENGINE_F_HWCRHK_MOD_EXP 137 +#define ENGINE_F_HWCRHK_MOD_EXP_CRT 138 +#define ENGINE_F_HWCRHK_RAND_BYTES 139 +#define ENGINE_F_HWCRHK_RSA_MOD_EXP 140 +#define ENGINE_F_LOG_MESSAGE 141 + +/* Reason codes. */ +#define ENGINE_R_ALREADY_LOADED 100 +#define ENGINE_R_BIO_WAS_FREED 121 +#define ENGINE_R_BN_CTX_FULL 101 +#define ENGINE_R_BN_EXPAND_FAIL 102 +#define ENGINE_R_CHIL_ERROR 123 +#define ENGINE_R_CONFLICTING_ENGINE_ID 103 +#define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 119 +#define ENGINE_R_DSO_FAILURE 104 +#define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105 +#define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128 +#define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129 +#define ENGINE_R_FINISH_FAILED 106 +#define ENGINE_R_GET_HANDLE_FAILED 107 +#define ENGINE_R_ID_OR_NAME_MISSING 108 +#define ENGINE_R_INIT_FAILED 109 +#define ENGINE_R_INTERNAL_LIST_ERROR 110 +#define ENGINE_R_MISSING_KEY_COMPONENTS 111 +#define ENGINE_R_NOT_INITIALISED 117 +#define ENGINE_R_NOT_LOADED 112 +#define ENGINE_R_NO_CALLBACK 127 +#define ENGINE_R_NO_CONTROL_FUNCTION 120 +#define ENGINE_R_NO_KEY 124 +#define ENGINE_R_NO_LOAD_FUNCTION 125 +#define ENGINE_R_NO_REFERENCE 130 +#define ENGINE_R_NO_SUCH_ENGINE 116 +#define ENGINE_R_NO_UNLOAD_FUNCTION 126 +#define ENGINE_R_PROVIDE_PARAMETERS 113 +#define ENGINE_R_REQUEST_FAILED 114 +#define ENGINE_R_REQUEST_FALLBACK 118 +#define ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL 122 +#define ENGINE_R_UNIT_FAILURE 115 + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/lib/libssl/src/crypto/engine/enginetest.c b/lib/libssl/src/crypto/engine/enginetest.c new file mode 100644 index 00000000000..a5a3c47fcbf --- /dev/null +++ b/lib/libssl/src/crypto/engine/enginetest.c @@ -0,0 +1,251 @@ +/* crypto/engine/enginetest.c */ +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) 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). + * + */ + +#include +#include +#include +#include + +static void display_engine_list() + { + ENGINE *h; + int loop; + + h = ENGINE_get_first(); + loop = 0; + printf("listing available engine types\n"); + while(h) + { + printf("engine %i, id = \"%s\", name = \"%s\"\n", + loop++, ENGINE_get_id(h), ENGINE_get_name(h)); + h = ENGINE_get_next(h); + } + printf("end of list\n"); + } + +int main(int argc, char *argv[]) + { + ENGINE *block[512]; + char buf[256]; + const char *id, *name; + ENGINE *ptr; + int loop; + int to_return = 1; + ENGINE *new_h1 = NULL; + ENGINE *new_h2 = NULL; + ENGINE *new_h3 = NULL; + ENGINE *new_h4 = NULL; + + ERR_load_crypto_strings(); + + memset(block, 0, 512 * sizeof(ENGINE *)); + if(((new_h1 = ENGINE_new()) == NULL) || + !ENGINE_set_id(new_h1, "test_id0") || + !ENGINE_set_name(new_h1, "First test item") || + ((new_h2 = ENGINE_new()) == NULL) || + !ENGINE_set_id(new_h2, "test_id1") || + !ENGINE_set_name(new_h2, "Second test item") || + ((new_h3 = ENGINE_new()) == NULL) || + !ENGINE_set_id(new_h3, "test_id2") || + !ENGINE_set_name(new_h3, "Third test item") || + ((new_h4 = ENGINE_new()) == NULL) || + !ENGINE_set_id(new_h4, "test_id3") || + !ENGINE_set_name(new_h4, "Fourth test item")) + { + printf("Couldn't set up test ENGINE structures\n"); + goto end; + } + printf("\nenginetest beginning\n\n"); + display_engine_list(); + if(!ENGINE_add(new_h1)) + { + printf("Add failed!\n"); + goto end; + } + display_engine_list(); + ptr = ENGINE_get_first(); + if(!ENGINE_remove(ptr)) + { + printf("Remove failed!\n"); + goto end; + } + display_engine_list(); + if(!ENGINE_add(new_h3) || !ENGINE_add(new_h2)) + { + printf("Add failed!\n"); + goto end; + } + display_engine_list(); + if(!ENGINE_remove(new_h2)) + { + printf("Remove failed!\n"); + goto end; + } + display_engine_list(); + if(!ENGINE_add(new_h4)) + { + printf("Add failed!\n"); + goto end; + } + display_engine_list(); + if(ENGINE_add(new_h3)) + { + printf("Add *should* have failed but didn't!\n"); + goto end; + } + else + printf("Add that should fail did.\n"); + ERR_clear_error(); + if(ENGINE_remove(new_h2)) + { + printf("Remove *should* have failed but didn't!\n"); + goto end; + } + else + printf("Remove that should fail did.\n"); + if(!ENGINE_remove(new_h1)) + { + printf("Remove failed!\n"); + goto end; + } + display_engine_list(); + if(!ENGINE_remove(new_h3)) + { + printf("Remove failed!\n"); + goto end; + } + display_engine_list(); + if(!ENGINE_remove(new_h4)) + { + printf("Remove failed!\n"); + goto end; + } + display_engine_list(); + /* Depending on whether there's any hardware support compiled + * in, this remove may be destined to fail. */ + ptr = ENGINE_get_first(); + if(ptr) + if(!ENGINE_remove(ptr)) + printf("Remove failed!i - probably no hardware " + "support present.\n"); + display_engine_list(); + if(!ENGINE_add(new_h1) || !ENGINE_remove(new_h1)) + { + printf("Couldn't add and remove to an empty list!\n"); + goto end; + } + else + printf("Successfully added and removed to an empty list!\n"); + printf("About to beef up the engine-type list\n"); + for(loop = 0; loop < 512; loop++) + { + sprintf(buf, "id%i", loop); + id = strdup(buf); + sprintf(buf, "Fake engine type %i", loop); + name = strdup(buf); + if(((block[loop] = ENGINE_new()) == NULL) || + !ENGINE_set_id(block[loop], id) || + !ENGINE_set_name(block[loop], name)) + { + printf("Couldn't create block of ENGINE structures.\n" + "I'll probably also core-dump now, damn.\n"); + goto end; + } + } + for(loop = 0; loop < 512; loop++) + { + if(!ENGINE_add(block[loop])) + { + printf("\nAdding stopped at %i, (%s,%s)\n", + loop, ENGINE_get_id(block[loop]), + ENGINE_get_name(block[loop])); + goto cleanup_loop; + } + else + printf("."); fflush(stdout); + } +cleanup_loop: + printf("\nAbout to empty the engine-type list\n"); + while((ptr = ENGINE_get_first()) != NULL) + { + if(!ENGINE_remove(ptr)) + { + printf("\nRemove failed!\n"); + goto end; + } + printf("."); fflush(stdout); + } + for(loop = 0; loop < 512; loop++) + { + free((char *)(ENGINE_get_id(block[loop]))); + free((char *)(ENGINE_get_name(block[loop]))); + } + printf("\nTests completed happily\n"); + to_return = 0; +end: + if(to_return) + ERR_print_errors_fp(stderr); + if(new_h1) ENGINE_free(new_h1); + if(new_h2) ENGINE_free(new_h2); + if(new_h3) ENGINE_free(new_h3); + if(new_h4) ENGINE_free(new_h4); + for(loop = 0; loop < 512; loop++) + if(block[loop]) + ENGINE_free(block[loop]); + return to_return; + } diff --git a/lib/libssl/src/crypto/engine/hw_atalla.c b/lib/libssl/src/crypto/engine/hw_atalla.c new file mode 100644 index 00000000000..3bb992a193e --- /dev/null +++ b/lib/libssl/src/crypto/engine/hw_atalla.c @@ -0,0 +1,444 @@ +/* crypto/engine/hw_atalla.c */ +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) 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). + * + */ + +#include +#include +#include "cryptlib.h" +#include +#include "engine_int.h" +#include + +#ifndef NO_HW +#ifndef NO_HW_ATALLA + +#ifdef FLAT_INC +#include "atalla.h" +#else +#include "vendor_defns/atalla.h" +#endif + +static int atalla_init(void); +static int atalla_finish(void); + +/* BIGNUM stuff */ +static int atalla_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); + +/* RSA stuff */ +static int atalla_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa); +/* This function is aliased to mod_exp (with the mont stuff dropped). */ +static int atalla_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); + +/* DSA stuff */ +static int atalla_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, + BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *in_mont); +static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); + +/* DH stuff */ +/* This function is alised to mod_exp (with the DH and mont dropped). */ +static int atalla_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); + + +/* Our internal RSA_METHOD that we provide pointers to */ +static RSA_METHOD atalla_rsa = + { + "Atalla RSA method", + NULL, + NULL, + NULL, + NULL, + atalla_rsa_mod_exp, + atalla_mod_exp_mont, + NULL, + NULL, + 0, + NULL, + NULL, + NULL + }; + +/* Our internal DSA_METHOD that we provide pointers to */ +static DSA_METHOD atalla_dsa = + { + "Atalla DSA method", + NULL, /* dsa_do_sign */ + NULL, /* dsa_sign_setup */ + NULL, /* dsa_do_verify */ + atalla_dsa_mod_exp, /* dsa_mod_exp */ + atalla_mod_exp_dsa, /* bn_mod_exp */ + NULL, /* init */ + NULL, /* finish */ + 0, /* flags */ + NULL /* app_data */ + }; + +/* Our internal DH_METHOD that we provide pointers to */ +static DH_METHOD atalla_dh = + { + "Atalla DH method", + NULL, + NULL, + atalla_mod_exp_dh, + NULL, + NULL, + 0, + NULL + }; + +/* Our ENGINE structure. */ +static ENGINE engine_atalla = + { + "atalla", + "Atalla hardware engine support", + &atalla_rsa, + &atalla_dsa, + &atalla_dh, + NULL, + atalla_mod_exp, + NULL, + atalla_init, + atalla_finish, + NULL, /* no ctrl() */ + NULL, /* no load_privkey() */ + NULL, /* no load_pubkey() */ + 0, /* no flags */ + 0, 0, /* no references */ + NULL, NULL /* unlinked */ + }; + +/* As this is only ever called once, there's no need for locking + * (indeed - the lock will already be held by our caller!!!) */ +ENGINE *ENGINE_atalla() + { + RSA_METHOD *meth1; + DSA_METHOD *meth2; + DH_METHOD *meth3; + + /* We know that the "PKCS1_SSLeay()" functions hook properly + * to the atalla-specific mod_exp and mod_exp_crt so we use + * those functions. NB: We don't use ENGINE_openssl() or + * anything "more generic" because something like the RSAref + * code may not hook properly, and if you own one of these + * cards then you have the right to do RSA operations on it + * anyway! */ + meth1 = RSA_PKCS1_SSLeay(); + atalla_rsa.rsa_pub_enc = meth1->rsa_pub_enc; + atalla_rsa.rsa_pub_dec = meth1->rsa_pub_dec; + atalla_rsa.rsa_priv_enc = meth1->rsa_priv_enc; + atalla_rsa.rsa_priv_dec = meth1->rsa_priv_dec; + + /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish + * bits. */ + meth2 = DSA_OpenSSL(); + atalla_dsa.dsa_do_sign = meth2->dsa_do_sign; + atalla_dsa.dsa_sign_setup = meth2->dsa_sign_setup; + atalla_dsa.dsa_do_verify = meth2->dsa_do_verify; + + /* Much the same for Diffie-Hellman */ + meth3 = DH_OpenSSL(); + atalla_dh.generate_key = meth3->generate_key; + atalla_dh.compute_key = meth3->compute_key; + return &engine_atalla; + } + +/* This is a process-global DSO handle used for loading and unloading + * the Atalla library. NB: This is only set (or unset) during an + * init() or finish() call (reference counts permitting) and they're + * operating with global locks, so this should be thread-safe + * implicitly. */ +static DSO *atalla_dso = NULL; + +/* These are the function pointers that are (un)set when the library has + * successfully (un)loaded. */ +static tfnASI_GetHardwareConfig *p_Atalla_GetHardwareConfig = NULL; +static tfnASI_RSAPrivateKeyOpFn *p_Atalla_RSAPrivateKeyOpFn = NULL; +static tfnASI_GetPerformanceStatistics *p_Atalla_GetPerformanceStatistics = NULL; + +/* (de)initialisation functions. */ +static int atalla_init() + { + tfnASI_GetHardwareConfig *p1; + tfnASI_RSAPrivateKeyOpFn *p2; + tfnASI_GetPerformanceStatistics *p3; + /* Not sure of the origin of this magic value, but Ben's code had it + * and it seemed to have been working for a few people. :-) */ + unsigned int config_buf[1024]; + + if(atalla_dso != NULL) + { + ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_ALREADY_LOADED); + goto err; + } + /* Attempt to load libatasi.so/atasi.dll/whatever. Needs to be + * changed unfortunately because the Atalla drivers don't have + * standard library names that can be platform-translated well. */ + /* TODO: Work out how to actually map to the names the Atalla + * drivers really use - for now a symbollic link needs to be + * created on the host system from libatasi.so to atasi.so on + * unix variants. */ + atalla_dso = DSO_load(NULL, ATALLA_LIBNAME, NULL, + DSO_FLAG_NAME_TRANSLATION); + if(atalla_dso == NULL) + { + ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_DSO_FAILURE); + goto err; + } + if(!(p1 = (tfnASI_GetHardwareConfig *)DSO_bind_func( + atalla_dso, ATALLA_F1)) || + !(p2 = (tfnASI_RSAPrivateKeyOpFn *)DSO_bind_func( + atalla_dso, ATALLA_F2)) || + !(p3 = (tfnASI_GetPerformanceStatistics *)DSO_bind_func( + atalla_dso, ATALLA_F3))) + { + ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_DSO_FAILURE); + goto err; + } + /* Copy the pointers */ + p_Atalla_GetHardwareConfig = p1; + p_Atalla_RSAPrivateKeyOpFn = p2; + p_Atalla_GetPerformanceStatistics = p3; + /* Perform a basic test to see if there's actually any unit + * running. */ + if(p1(0L, config_buf) != 0) + { + ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_UNIT_FAILURE); + goto err; + } + /* Everything's fine. */ + return 1; +err: + if(atalla_dso) + DSO_free(atalla_dso); + p_Atalla_GetHardwareConfig = NULL; + p_Atalla_RSAPrivateKeyOpFn = NULL; + p_Atalla_GetPerformanceStatistics = NULL; + return 0; + } + +static int atalla_finish() + { + if(atalla_dso == NULL) + { + ENGINEerr(ENGINE_F_ATALLA_FINISH,ENGINE_R_NOT_LOADED); + return 0; + } + if(!DSO_free(atalla_dso)) + { + ENGINEerr(ENGINE_F_ATALLA_FINISH,ENGINE_R_DSO_FAILURE); + return 0; + } + atalla_dso = NULL; + p_Atalla_GetHardwareConfig = NULL; + p_Atalla_RSAPrivateKeyOpFn = NULL; + p_Atalla_GetPerformanceStatistics = NULL; + return 1; + } + +static int atalla_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx) + { + /* I need somewhere to store temporary serialised values for + * use with the Atalla API calls. A neat cheat - I'll use + * BIGNUMs from the BN_CTX but access their arrays directly as + * byte arrays . This way I don't have to clean anything + * up. */ + BIGNUM *modulus; + BIGNUM *exponent; + BIGNUM *argument; + BIGNUM *result; + RSAPrivateKey keydata; + int to_return, numbytes; + + modulus = exponent = argument = result = NULL; + to_return = 0; /* expect failure */ + + if(!atalla_dso) + { + ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_NOT_LOADED); + goto err; + } + /* Prepare the params */ + modulus = BN_CTX_get(ctx); + exponent = BN_CTX_get(ctx); + argument = BN_CTX_get(ctx); + result = BN_CTX_get(ctx); + if(!modulus || !exponent || !argument || !result) + { + ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_BN_CTX_FULL); + goto err; + } + if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, m->top) || + !bn_wexpand(argument, m->top) || !bn_wexpand(result, m->top)) + { + ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_BN_EXPAND_FAIL); + goto err; + } + /* Prepare the key-data */ + memset(&keydata, 0,sizeof keydata); + numbytes = BN_num_bytes(m); + memset(exponent->d, 0, numbytes); + memset(modulus->d, 0, numbytes); + BN_bn2bin(p, (unsigned char *)exponent->d + numbytes - BN_num_bytes(p)); + BN_bn2bin(m, (unsigned char *)modulus->d + numbytes - BN_num_bytes(m)); + keydata.privateExponent.data = (unsigned char *)exponent->d; + keydata.privateExponent.len = numbytes; + keydata.modulus.data = (unsigned char *)modulus->d; + keydata.modulus.len = numbytes; + /* Prepare the argument */ + memset(argument->d, 0, numbytes); + memset(result->d, 0, numbytes); + BN_bn2bin(a, (unsigned char *)argument->d + numbytes - BN_num_bytes(a)); + /* Perform the operation */ + if(p_Atalla_RSAPrivateKeyOpFn(&keydata, (unsigned char *)result->d, + (unsigned char *)argument->d, + keydata.modulus.len) != 0) + { + ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_REQUEST_FAILED); + goto err; + } + /* Convert the response */ + BN_bin2bn((unsigned char *)result->d, numbytes, r); + to_return = 1; +err: + if(modulus) ctx->tos--; + if(exponent) ctx->tos--; + if(argument) ctx->tos--; + if(result) ctx->tos--; + return to_return; + } + +static int atalla_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa) + { + BN_CTX *ctx = NULL; + int to_return = 0; + + if(!atalla_dso) + { + ENGINEerr(ENGINE_F_ATALLA_RSA_MOD_EXP,ENGINE_R_NOT_LOADED); + goto err; + } + if((ctx = BN_CTX_new()) == NULL) + goto err; + if(!rsa->d || !rsa->n) + { + ENGINEerr(ENGINE_F_ATALLA_RSA_MOD_EXP,ENGINE_R_MISSING_KEY_COMPONENTS); + goto err; + } + to_return = atalla_mod_exp(r0, I, rsa->d, rsa->n, ctx); +err: + if(ctx) + BN_CTX_free(ctx); + return to_return; + } + +/* This code was liberated and adapted from the commented-out code in + * dsa_ossl.c. Because of the unoptimised form of the Atalla acceleration + * (it doesn't have a CRT form for RSA), this function means that an + * Atalla system running with a DSA server certificate can handshake + * around 5 or 6 times faster/more than an equivalent system running with + * RSA. Just check out the "signs" statistics from the RSA and DSA parts + * of "openssl speed -engine atalla dsa1024 rsa1024". */ +static int atalla_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, + BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *in_mont) + { + BIGNUM t; + int to_return = 0; + + BN_init(&t); + /* let rr = a1 ^ p1 mod m */ + if (!atalla_mod_exp(rr,a1,p1,m,ctx)) goto end; + /* let t = a2 ^ p2 mod m */ + if (!atalla_mod_exp(&t,a2,p2,m,ctx)) goto end; + /* let rr = rr * t mod m */ + if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end; + to_return = 1; +end: + BN_free(&t); + return to_return; + } + + +static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx) + { + return atalla_mod_exp(r, a, p, m, ctx); + } + +/* This function is aliased to mod_exp (with the mont stuff dropped). */ +static int atalla_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) + { + return atalla_mod_exp(r, a, p, m, ctx); + } + +/* This function is aliased to mod_exp (with the dh and mont dropped). */ +static int atalla_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) + { + return atalla_mod_exp(r, a, p, m, ctx); + } + +#endif /* !NO_HW_ATALLA */ +#endif /* !NO_HW */ diff --git a/lib/libssl/src/crypto/engine/hw_cswift.c b/lib/libssl/src/crypto/engine/hw_cswift.c new file mode 100644 index 00000000000..77608b89839 --- /dev/null +++ b/lib/libssl/src/crypto/engine/hw_cswift.c @@ -0,0 +1,807 @@ +/* crypto/engine/hw_cswift.c */ +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) 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). + * + */ + +#include +#include +#include "cryptlib.h" +#include +#include "engine_int.h" +#include + +#ifndef NO_HW +#ifndef NO_HW_CSWIFT + +/* Attribution notice: Rainbow have generously allowed me to reproduce + * the necessary definitions here from their API. This means the support + * can build independently of whether application builders have the + * API or hardware. This will allow developers to easily produce software + * that has latent hardware support for any users that have accelerators + * installed, without the developers themselves needing anything extra. + * + * I have only clipped the parts from the CryptoSwift header files that + * are (or seem) relevant to the CryptoSwift support code. This is + * simply to keep the file sizes reasonable. + * [Geoff] + */ +#ifdef FLAT_INC +#include "cswift.h" +#else +#include "vendor_defns/cswift.h" +#endif + +static int cswift_init(void); +static int cswift_finish(void); + +/* BIGNUM stuff */ +static int cswift_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); +static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1, + const BIGNUM *iqmp, BN_CTX *ctx); + +/* RSA stuff */ +static int cswift_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa); +/* This function is aliased to mod_exp (with the mont stuff dropped). */ +static int cswift_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); + +/* DSA stuff */ +static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa); +static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa); + +/* DH stuff */ +/* This function is alised to mod_exp (with the DH and mont dropped). */ +static int cswift_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); + + +/* Our internal RSA_METHOD that we provide pointers to */ +static RSA_METHOD cswift_rsa = + { + "CryptoSwift RSA method", + NULL, + NULL, + NULL, + NULL, + cswift_rsa_mod_exp, + cswift_mod_exp_mont, + NULL, + NULL, + 0, + NULL, + NULL, + NULL + }; + +/* Our internal DSA_METHOD that we provide pointers to */ +static DSA_METHOD cswift_dsa = + { + "CryptoSwift DSA method", + cswift_dsa_sign, + NULL, /* dsa_sign_setup */ + cswift_dsa_verify, + NULL, /* dsa_mod_exp */ + NULL, /* bn_mod_exp */ + NULL, /* init */ + NULL, /* finish */ + 0, /* flags */ + NULL /* app_data */ + }; + +/* Our internal DH_METHOD that we provide pointers to */ +static DH_METHOD cswift_dh = + { + "CryptoSwift DH method", + NULL, + NULL, + cswift_mod_exp_dh, + NULL, + NULL, + 0, + NULL + }; + +/* Our ENGINE structure. */ +static ENGINE engine_cswift = + { + "cswift", + "CryptoSwift hardware engine support", + &cswift_rsa, + &cswift_dsa, + &cswift_dh, + NULL, + cswift_mod_exp, + cswift_mod_exp_crt, + cswift_init, + cswift_finish, + NULL, /* no ctrl() */ + NULL, /* no load_privkey() */ + NULL, /* no load_pubkey() */ + 0, /* no flags */ + 0, 0, /* no references */ + NULL, NULL /* unlinked */ + }; + +/* As this is only ever called once, there's no need for locking + * (indeed - the lock will already be held by our caller!!!) */ +ENGINE *ENGINE_cswift() + { + RSA_METHOD *meth1; + DH_METHOD *meth2; + + /* We know that the "PKCS1_SSLeay()" functions hook properly + * to the cswift-specific mod_exp and mod_exp_crt so we use + * those functions. NB: We don't use ENGINE_openssl() or + * anything "more generic" because something like the RSAref + * code may not hook properly, and if you own one of these + * cards then you have the right to do RSA operations on it + * anyway! */ + meth1 = RSA_PKCS1_SSLeay(); + cswift_rsa.rsa_pub_enc = meth1->rsa_pub_enc; + cswift_rsa.rsa_pub_dec = meth1->rsa_pub_dec; + cswift_rsa.rsa_priv_enc = meth1->rsa_priv_enc; + cswift_rsa.rsa_priv_dec = meth1->rsa_priv_dec; + + /* Much the same for Diffie-Hellman */ + meth2 = DH_OpenSSL(); + cswift_dh.generate_key = meth2->generate_key; + cswift_dh.compute_key = meth2->compute_key; + return &engine_cswift; + } + +/* This is a process-global DSO handle used for loading and unloading + * the CryptoSwift library. NB: This is only set (or unset) during an + * init() or finish() call (reference counts permitting) and they're + * operating with global locks, so this should be thread-safe + * implicitly. */ +static DSO *cswift_dso = NULL; + +/* These are the function pointers that are (un)set when the library has + * successfully (un)loaded. */ +t_swAcquireAccContext *p_CSwift_AcquireAccContext = NULL; +t_swAttachKeyParam *p_CSwift_AttachKeyParam = NULL; +t_swSimpleRequest *p_CSwift_SimpleRequest = NULL; +t_swReleaseAccContext *p_CSwift_ReleaseAccContext = NULL; + +/* Used in the DSO operations. */ +static const char *CSWIFT_LIBNAME = "swift"; +static const char *CSWIFT_F1 = "swAcquireAccContext"; +static const char *CSWIFT_F2 = "swAttachKeyParam"; +static const char *CSWIFT_F3 = "swSimpleRequest"; +static const char *CSWIFT_F4 = "swReleaseAccContext"; + + +/* CryptoSwift library functions and mechanics - these are used by the + * higher-level functions further down. NB: As and where there's no + * error checking, take a look lower down where these functions are + * called, the checking and error handling is probably down there. */ + +/* utility function to obtain a context */ +static int get_context(SW_CONTEXT_HANDLE *hac) + { + SW_STATUS status; + + status = p_CSwift_AcquireAccContext(hac); + if(status != SW_OK) + return 0; + return 1; + } + +/* similarly to release one. */ +static void release_context(SW_CONTEXT_HANDLE hac) + { + p_CSwift_ReleaseAccContext(hac); + } + +/* (de)initialisation functions. */ +static int cswift_init() + { + SW_CONTEXT_HANDLE hac; + t_swAcquireAccContext *p1; + t_swAttachKeyParam *p2; + t_swSimpleRequest *p3; + t_swReleaseAccContext *p4; + + if(cswift_dso != NULL) + { + ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_ALREADY_LOADED); + goto err; + } + /* Attempt to load libswift.so/swift.dll/whatever. */ + cswift_dso = DSO_load(NULL, CSWIFT_LIBNAME, NULL, + DSO_FLAG_NAME_TRANSLATION); + if(cswift_dso == NULL) + { + ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_DSO_FAILURE); + goto err; + } + if(!(p1 = (t_swAcquireAccContext *) + DSO_bind_func(cswift_dso, CSWIFT_F1)) || + !(p2 = (t_swAttachKeyParam *) + DSO_bind_func(cswift_dso, CSWIFT_F2)) || + !(p3 = (t_swSimpleRequest *) + DSO_bind_func(cswift_dso, CSWIFT_F3)) || + !(p4 = (t_swReleaseAccContext *) + DSO_bind_func(cswift_dso, CSWIFT_F4))) + { + ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_DSO_FAILURE); + goto err; + } + /* Copy the pointers */ + p_CSwift_AcquireAccContext = p1; + p_CSwift_AttachKeyParam = p2; + p_CSwift_SimpleRequest = p3; + p_CSwift_ReleaseAccContext = p4; + /* Try and get a context - if not, we may have a DSO but no + * accelerator! */ + if(!get_context(&hac)) + { + ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_UNIT_FAILURE); + goto err; + } + release_context(hac); + /* Everything's fine. */ + return 1; +err: + if(cswift_dso) + DSO_free(cswift_dso); + p_CSwift_AcquireAccContext = NULL; + p_CSwift_AttachKeyParam = NULL; + p_CSwift_SimpleRequest = NULL; + p_CSwift_ReleaseAccContext = NULL; + return 0; + } + +static int cswift_finish() + { + if(cswift_dso == NULL) + { + ENGINEerr(ENGINE_F_CSWIFT_FINISH,ENGINE_R_NOT_LOADED); + return 0; + } + if(!DSO_free(cswift_dso)) + { + ENGINEerr(ENGINE_F_CSWIFT_FINISH,ENGINE_R_DSO_FAILURE); + return 0; + } + cswift_dso = NULL; + p_CSwift_AcquireAccContext = NULL; + p_CSwift_AttachKeyParam = NULL; + p_CSwift_SimpleRequest = NULL; + p_CSwift_ReleaseAccContext = NULL; + return 1; + } + +/* Un petit mod_exp */ +static int cswift_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx) + { + /* I need somewhere to store temporary serialised values for + * use with the CryptoSwift API calls. A neat cheat - I'll use + * BIGNUMs from the BN_CTX but access their arrays directly as + * byte arrays . This way I don't have to clean anything + * up. */ + BIGNUM *modulus; + BIGNUM *exponent; + BIGNUM *argument; + BIGNUM *result; + SW_STATUS sw_status; + SW_LARGENUMBER arg, res; + SW_PARAM sw_param; + SW_CONTEXT_HANDLE hac; + int to_return, acquired; + + modulus = exponent = argument = result = NULL; + to_return = 0; /* expect failure */ + acquired = 0; + + if(!get_context(&hac)) + { + ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_GET_HANDLE_FAILED); + goto err; + } + acquired = 1; + /* Prepare the params */ + modulus = BN_CTX_get(ctx); + exponent = BN_CTX_get(ctx); + argument = BN_CTX_get(ctx); + result = BN_CTX_get(ctx); + if(!modulus || !exponent || !argument || !result) + { + ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_BN_CTX_FULL); + goto err; + } + if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, p->top) || + !bn_wexpand(argument, a->top) || !bn_wexpand(result, m->top)) + { + ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_BN_EXPAND_FAIL); + goto err; + } + sw_param.type = SW_ALG_EXP; + sw_param.up.exp.modulus.nbytes = BN_bn2bin(m, + (unsigned char *)modulus->d); + sw_param.up.exp.modulus.value = (unsigned char *)modulus->d; + sw_param.up.exp.exponent.nbytes = BN_bn2bin(p, + (unsigned char *)exponent->d); + sw_param.up.exp.exponent.value = (unsigned char *)exponent->d; + /* Attach the key params */ + sw_status = p_CSwift_AttachKeyParam(hac, &sw_param); + switch(sw_status) + { + case SW_OK: + break; + case SW_ERR_INPUT_SIZE: + ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP, + ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL); + goto err; + default: + { + char tmpbuf[20]; + ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_REQUEST_FAILED); + sprintf(tmpbuf, "%ld", sw_status); + ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); + } + goto err; + } + /* Prepare the argument and response */ + arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d); + arg.value = (unsigned char *)argument->d; + res.nbytes = BN_num_bytes(m); + memset(result->d, 0, res.nbytes); + res.value = (unsigned char *)result->d; + /* Perform the operation */ + if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP, &arg, 1, + &res, 1)) != SW_OK) + { + char tmpbuf[20]; + ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_REQUEST_FAILED); + sprintf(tmpbuf, "%ld", sw_status); + ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); + goto err; + } + /* Convert the response */ + BN_bin2bn((unsigned char *)result->d, res.nbytes, r); + to_return = 1; +err: + if(acquired) + release_context(hac); + if(modulus) ctx->tos--; + if(exponent) ctx->tos--; + if(argument) ctx->tos--; + if(result) ctx->tos--; + return to_return; + } + +/* Un petit mod_exp chinois */ +static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *q, const BIGNUM *dmp1, + const BIGNUM *dmq1, const BIGNUM *iqmp, BN_CTX *ctx) + { + SW_STATUS sw_status; + SW_LARGENUMBER arg, res; + SW_PARAM sw_param; + SW_CONTEXT_HANDLE hac; + BIGNUM *rsa_p = NULL; + BIGNUM *rsa_q = NULL; + BIGNUM *rsa_dmp1 = NULL; + BIGNUM *rsa_dmq1 = NULL; + BIGNUM *rsa_iqmp = NULL; + BIGNUM *argument = NULL; + BIGNUM *result = NULL; + int to_return = 0; /* expect failure */ + int acquired = 0; + + if(!get_context(&hac)) + { + ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_GET_HANDLE_FAILED); + goto err; + } + acquired = 1; + /* Prepare the params */ + rsa_p = BN_CTX_get(ctx); + rsa_q = BN_CTX_get(ctx); + rsa_dmp1 = BN_CTX_get(ctx); + rsa_dmq1 = BN_CTX_get(ctx); + rsa_iqmp = BN_CTX_get(ctx); + argument = BN_CTX_get(ctx); + result = BN_CTX_get(ctx); + if(!rsa_p || !rsa_q || !rsa_dmp1 || !rsa_dmq1 || !rsa_iqmp || + !argument || !result) + { + ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_BN_CTX_FULL); + goto err; + } + if(!bn_wexpand(rsa_p, p->top) || !bn_wexpand(rsa_q, q->top) || + !bn_wexpand(rsa_dmp1, dmp1->top) || + !bn_wexpand(rsa_dmq1, dmq1->top) || + !bn_wexpand(rsa_iqmp, iqmp->top) || + !bn_wexpand(argument, a->top) || + !bn_wexpand(result, p->top + q->top)) + { + ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_BN_EXPAND_FAIL); + goto err; + } + sw_param.type = SW_ALG_CRT; + sw_param.up.crt.p.nbytes = BN_bn2bin(p, (unsigned char *)rsa_p->d); + sw_param.up.crt.p.value = (unsigned char *)rsa_p->d; + sw_param.up.crt.q.nbytes = BN_bn2bin(q, (unsigned char *)rsa_q->d); + sw_param.up.crt.q.value = (unsigned char *)rsa_q->d; + sw_param.up.crt.dmp1.nbytes = BN_bn2bin(dmp1, + (unsigned char *)rsa_dmp1->d); + sw_param.up.crt.dmp1.value = (unsigned char *)rsa_dmp1->d; + sw_param.up.crt.dmq1.nbytes = BN_bn2bin(dmq1, + (unsigned char *)rsa_dmq1->d); + sw_param.up.crt.dmq1.value = (unsigned char *)rsa_dmq1->d; + sw_param.up.crt.iqmp.nbytes = BN_bn2bin(iqmp, + (unsigned char *)rsa_iqmp->d); + sw_param.up.crt.iqmp.value = (unsigned char *)rsa_iqmp->d; + /* Attach the key params */ + sw_status = p_CSwift_AttachKeyParam(hac, &sw_param); + switch(sw_status) + { + case SW_OK: + break; + case SW_ERR_INPUT_SIZE: + ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT, + ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL); + goto err; + default: + { + char tmpbuf[20]; + ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_REQUEST_FAILED); + sprintf(tmpbuf, "%ld", sw_status); + ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); + } + goto err; + } + /* Prepare the argument and response */ + arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d); + arg.value = (unsigned char *)argument->d; + res.nbytes = 2 * BN_num_bytes(p); + memset(result->d, 0, res.nbytes); + res.value = (unsigned char *)result->d; + /* Perform the operation */ + if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP_CRT, &arg, 1, + &res, 1)) != SW_OK) + { + char tmpbuf[20]; + ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_REQUEST_FAILED); + sprintf(tmpbuf, "%ld", sw_status); + ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); + goto err; + } + /* Convert the response */ + BN_bin2bn((unsigned char *)result->d, res.nbytes, r); + to_return = 1; +err: + if(acquired) + release_context(hac); + if(rsa_p) ctx->tos--; + if(rsa_q) ctx->tos--; + if(rsa_dmp1) ctx->tos--; + if(rsa_dmq1) ctx->tos--; + if(rsa_iqmp) ctx->tos--; + if(argument) ctx->tos--; + if(result) ctx->tos--; + return to_return; + } + +static int cswift_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa) + { + BN_CTX *ctx; + int to_return = 0; + + if((ctx = BN_CTX_new()) == NULL) + goto err; + if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) + { + ENGINEerr(ENGINE_F_CSWIFT_RSA_MOD_EXP,ENGINE_R_MISSING_KEY_COMPONENTS); + goto err; + } + to_return = cswift_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1, + rsa->dmq1, rsa->iqmp, ctx); +err: + if(ctx) + BN_CTX_free(ctx); + return to_return; + } + +/* This function is aliased to mod_exp (with the mont stuff dropped). */ +static int cswift_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) + { + return cswift_mod_exp(r, a, p, m, ctx); + } + +static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa) + { + SW_CONTEXT_HANDLE hac; + SW_PARAM sw_param; + SW_STATUS sw_status; + SW_LARGENUMBER arg, res; + unsigned char *ptr; + BN_CTX *ctx; + BIGNUM *dsa_p = NULL; + BIGNUM *dsa_q = NULL; + BIGNUM *dsa_g = NULL; + BIGNUM *dsa_key = NULL; + BIGNUM *result = NULL; + DSA_SIG *to_return = NULL; + int acquired = 0; + + if((ctx = BN_CTX_new()) == NULL) + goto err; + if(!get_context(&hac)) + { + ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_GET_HANDLE_FAILED); + goto err; + } + acquired = 1; + /* Prepare the params */ + dsa_p = BN_CTX_get(ctx); + dsa_q = BN_CTX_get(ctx); + dsa_g = BN_CTX_get(ctx); + dsa_key = BN_CTX_get(ctx); + result = BN_CTX_get(ctx); + if(!dsa_p || !dsa_q || !dsa_g || !dsa_key || !result) + { + ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_BN_CTX_FULL); + goto err; + } + if(!bn_wexpand(dsa_p, dsa->p->top) || + !bn_wexpand(dsa_q, dsa->q->top) || + !bn_wexpand(dsa_g, dsa->g->top) || + !bn_wexpand(dsa_key, dsa->priv_key->top) || + !bn_wexpand(result, dsa->p->top)) + { + ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_BN_EXPAND_FAIL); + goto err; + } + sw_param.type = SW_ALG_DSA; + sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p, + (unsigned char *)dsa_p->d); + sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d; + sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q, + (unsigned char *)dsa_q->d); + sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d; + sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g, + (unsigned char *)dsa_g->d); + sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d; + sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->priv_key, + (unsigned char *)dsa_key->d); + sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d; + /* Attach the key params */ + sw_status = p_CSwift_AttachKeyParam(hac, &sw_param); + switch(sw_status) + { + case SW_OK: + break; + case SW_ERR_INPUT_SIZE: + ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN, + ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL); + goto err; + default: + { + char tmpbuf[20]; + ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_REQUEST_FAILED); + sprintf(tmpbuf, "%ld", sw_status); + ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); + } + goto err; + } + /* Prepare the argument and response */ + arg.nbytes = dlen; + arg.value = (unsigned char *)dgst; + res.nbytes = BN_num_bytes(dsa->p); + memset(result->d, 0, res.nbytes); + res.value = (unsigned char *)result->d; + /* Perform the operation */ + sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_SIGN, &arg, 1, + &res, 1); + if(sw_status != SW_OK) + { + char tmpbuf[20]; + ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_REQUEST_FAILED); + sprintf(tmpbuf, "%ld", sw_status); + ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); + goto err; + } + /* Convert the response */ + ptr = (unsigned char *)result->d; + if((to_return = DSA_SIG_new()) == NULL) + goto err; + to_return->r = BN_bin2bn((unsigned char *)result->d, 20, NULL); + to_return->s = BN_bin2bn((unsigned char *)result->d + 20, 20, NULL); + +err: + if(acquired) + release_context(hac); + if(dsa_p) ctx->tos--; + if(dsa_q) ctx->tos--; + if(dsa_g) ctx->tos--; + if(dsa_key) ctx->tos--; + if(result) ctx->tos--; + if(ctx) + BN_CTX_free(ctx); + return to_return; + } + +static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa) + { + SW_CONTEXT_HANDLE hac; + SW_PARAM sw_param; + SW_STATUS sw_status; + SW_LARGENUMBER arg[2], res; + unsigned long sig_result; + BN_CTX *ctx; + BIGNUM *dsa_p = NULL; + BIGNUM *dsa_q = NULL; + BIGNUM *dsa_g = NULL; + BIGNUM *dsa_key = NULL; + BIGNUM *argument = NULL; + int to_return = -1; + int acquired = 0; + + if((ctx = BN_CTX_new()) == NULL) + goto err; + if(!get_context(&hac)) + { + ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_GET_HANDLE_FAILED); + goto err; + } + acquired = 1; + /* Prepare the params */ + dsa_p = BN_CTX_get(ctx); + dsa_q = BN_CTX_get(ctx); + dsa_g = BN_CTX_get(ctx); + dsa_key = BN_CTX_get(ctx); + argument = BN_CTX_get(ctx); + if(!dsa_p || !dsa_q || !dsa_g || !dsa_key || !argument) + { + ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_BN_CTX_FULL); + goto err; + } + if(!bn_wexpand(dsa_p, dsa->p->top) || + !bn_wexpand(dsa_q, dsa->q->top) || + !bn_wexpand(dsa_g, dsa->g->top) || + !bn_wexpand(dsa_key, dsa->pub_key->top) || + !bn_wexpand(argument, 40)) + { + ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_BN_EXPAND_FAIL); + goto err; + } + sw_param.type = SW_ALG_DSA; + sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p, + (unsigned char *)dsa_p->d); + sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d; + sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q, + (unsigned char *)dsa_q->d); + sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d; + sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g, + (unsigned char *)dsa_g->d); + sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d; + sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->pub_key, + (unsigned char *)dsa_key->d); + sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d; + /* Attach the key params */ + sw_status = p_CSwift_AttachKeyParam(hac, &sw_param); + switch(sw_status) + { + case SW_OK: + break; + case SW_ERR_INPUT_SIZE: + ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY, + ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL); + goto err; + default: + { + char tmpbuf[20]; + ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_REQUEST_FAILED); + sprintf(tmpbuf, "%ld", sw_status); + ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); + } + goto err; + } + /* Prepare the argument and response */ + arg[0].nbytes = dgst_len; + arg[0].value = (unsigned char *)dgst; + arg[1].nbytes = 40; + arg[1].value = (unsigned char *)argument->d; + memset(arg[1].value, 0, 40); + BN_bn2bin(sig->r, arg[1].value + 20 - BN_num_bytes(sig->r)); + BN_bn2bin(sig->s, arg[1].value + 40 - BN_num_bytes(sig->s)); + res.nbytes = 4; /* unsigned long */ + res.value = (unsigned char *)(&sig_result); + /* Perform the operation */ + sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_VERIFY, arg, 2, + &res, 1); + if(sw_status != SW_OK) + { + char tmpbuf[20]; + ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_REQUEST_FAILED); + sprintf(tmpbuf, "%ld", sw_status); + ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); + goto err; + } + /* Convert the response */ + to_return = ((sig_result == 0) ? 0 : 1); + +err: + if(acquired) + release_context(hac); + if(dsa_p) ctx->tos--; + if(dsa_q) ctx->tos--; + if(dsa_g) ctx->tos--; + if(dsa_key) ctx->tos--; + if(argument) ctx->tos--; + if(ctx) + BN_CTX_free(ctx); + return to_return; + } + +/* This function is aliased to mod_exp (with the dh and mont dropped). */ +static int cswift_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) + { + return cswift_mod_exp(r, a, p, m, ctx); + } + +#endif /* !NO_HW_CSWIFT */ +#endif /* !NO_HW */ diff --git a/lib/libssl/src/crypto/engine/hw_ncipher.c b/lib/libssl/src/crypto/engine/hw_ncipher.c new file mode 100644 index 00000000000..41f5900676a --- /dev/null +++ b/lib/libssl/src/crypto/engine/hw_ncipher.c @@ -0,0 +1,1019 @@ +/* crypto/engine/hw_ncipher.c -*- mode: C; c-file-style: "eay" -*- */ +/* Written by Richard Levitte (richard@levitte.org), Geoff Thorpe + * (geoff@geoffthorpe.net) and 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). + * + */ + +#include +#include +#include +#include "cryptlib.h" +#include +#include "engine_int.h" +#include + +#ifndef NO_HW +#ifndef NO_HW_NCIPHER + +/* Attribution notice: nCipher have said several times that it's OK for + * us to implement a general interface to their boxes, and recently declared + * their HWCryptoHook to be public, and therefore available for us to use. + * Thanks, nCipher. + * + * The hwcryptohook.h included here is from May 2000. + * [Richard Levitte] + */ +#ifdef FLAT_INC +#include "hwcryptohook.h" +#else +#include "vendor_defns/hwcryptohook.h" +#endif + +static int hwcrhk_init(void); +static int hwcrhk_finish(void); +static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)()); + +/* Functions to handle mutexes */ +static int hwcrhk_mutex_init(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext*); +static int hwcrhk_mutex_lock(HWCryptoHook_Mutex*); +static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex*); +static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex*); + +/* BIGNUM stuff */ +static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); + +/* RSA stuff */ +static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa); +/* This function is aliased to mod_exp (with the mont stuff dropped). */ +static int hwcrhk_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); + +/* DH stuff */ +/* This function is alised to mod_exp (with the DH and mont dropped). */ +static int hwcrhk_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); + +/* RAND stuff */ +static int hwcrhk_rand_bytes(unsigned char *buf, int num); +static int hwcrhk_rand_status(void); + +/* KM stuff */ +static EVP_PKEY *hwcrhk_load_privkey(const char *key_id, + const char *passphrase); +static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id, + const char *passphrase); +static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, + int index,long argl, void *argp); + +/* Interaction stuff */ +static int hwcrhk_get_pass(const char *prompt_info, + int *len_io, char *buf, + HWCryptoHook_PassphraseContext *ppctx, + HWCryptoHook_CallerContext *cactx); +static void hwcrhk_log_message(void *logstream, const char *message); + +/* Our internal RSA_METHOD that we provide pointers to */ +static RSA_METHOD hwcrhk_rsa = + { + "nCipher RSA method", + NULL, + NULL, + NULL, + NULL, + hwcrhk_rsa_mod_exp, + hwcrhk_mod_exp_mont, + NULL, + NULL, + 0, + NULL, + NULL, + NULL + }; + +/* Our internal DH_METHOD that we provide pointers to */ +static DH_METHOD hwcrhk_dh = + { + "nCipher DH method", + NULL, + NULL, + hwcrhk_mod_exp_dh, + NULL, + NULL, + 0, + NULL + }; + +static RAND_METHOD hwcrhk_rand = + { + /* "nCipher RAND method", */ + NULL, + hwcrhk_rand_bytes, + NULL, + NULL, + hwcrhk_rand_bytes, + hwcrhk_rand_status, + }; + +/* Our ENGINE structure. */ +static ENGINE engine_hwcrhk = + { + "chil", + "nCipher hardware engine support", + &hwcrhk_rsa, + NULL, + &hwcrhk_dh, + &hwcrhk_rand, + hwcrhk_mod_exp, + NULL, + hwcrhk_init, + hwcrhk_finish, + hwcrhk_ctrl, + hwcrhk_load_privkey, + hwcrhk_load_pubkey, + 0, /* no flags */ + 0, 0, /* no references */ + NULL, NULL /* unlinked */ + }; + +/* Internal stuff for HWCryptoHook */ + +/* Some structures needed for proper use of thread locks */ +/* hwcryptohook.h has some typedefs that turn struct HWCryptoHook_MutexValue + into HWCryptoHook_Mutex */ +struct HWCryptoHook_MutexValue + { + int lockid; + }; + +/* hwcryptohook.h has some typedefs that turn + struct HWCryptoHook_PassphraseContextValue + into HWCryptoHook_PassphraseContext */ +struct HWCryptoHook_PassphraseContextValue + { + void *any; + }; + +/* hwcryptohook.h has some typedefs that turn + struct HWCryptoHook_CallerContextValue + into HWCryptoHook_CallerContext */ +struct HWCryptoHook_CallerContextValue + { + void *any; + }; + +/* The MPI structure in HWCryptoHook is pretty compatible with OpenSSL + BIGNUM's, so lets define a couple of conversion macros */ +#define BN2MPI(mp, bn) \ + {mp.size = bn->top * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;} +#define MPI2BN(bn, mp) \ + {mp.size = bn->dmax * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;} + +#if 0 /* Card and password management is not yet supported */ +/* HWCryptoHook callbacks. insert_card() and get_pass() are not yet + defined, because we haven't quite decided on the proper form yet. + log_message() just adds an entry in the error stack. I don't know + if that's good or bad... */ +static int insert_card(const char *prompt_info, + const char *wrong_info, + HWCryptoHook_PassphraseContext *ppctx, + HWCryptoHook_CallerContext *cactx); +static int get_pass(const char *prompt_info, + int *len_io, char *buf, + HWCryptoHook_PassphraseContext *ppctx, + HWCryptoHook_CallerContext *cactx); +#endif + +static BIO *logstream = NULL; +static pem_password_cb *password_callback = NULL; +#if 0 +static void *password_callback_userdata = NULL; +#endif +static int disable_mutex_callbacks = 0; + +/* Stuff to pass to the HWCryptoHook library */ +static HWCryptoHook_InitInfo hwcrhk_globals = { + 0, /* Flags */ + &logstream, /* logstream */ + sizeof(BN_ULONG), /* limbsize */ + 0, /* mslimb first: false for BNs */ + -1, /* msbyte first: use native */ + 0, /* Max mutexes, 0 = no small limit */ + 0, /* Max simultaneous, 0 = default */ + + /* The next few are mutex stuff: we write wrapper functions + around the OS mutex functions. We initialise them to 0 + here, and change that to actual function pointers in hwcrhk_init() + if dynamic locks are supported (that is, if the application + programmer has made sure of setting up callbacks bafore starting + this engine) *and* if disable_mutex_callbacks hasn't been set by + a call to ENGINE_ctrl(ENGINE_CTRL_CHIL_NO_LOCKING). */ + sizeof(HWCryptoHook_Mutex), + 0, + 0, + 0, + 0, + + /* The next few are condvar stuff: we write wrapper functions + round the OS functions. Currently not implemented and not + and absolute necessity even in threaded programs, therefore + 0'ed. Will hopefully be implemented some day, since it + enhances the efficiency of HWCryptoHook. */ + 0, /* sizeof(HWCryptoHook_CondVar), */ + 0, /* hwcrhk_cv_init, */ + 0, /* hwcrhk_cv_wait, */ + 0, /* hwcrhk_cv_signal, */ + 0, /* hwcrhk_cv_broadcast, */ + 0, /* hwcrhk_cv_destroy, */ + + hwcrhk_get_pass, /* pass phrase */ + 0, /* insert_card, */ /* insert a card */ + hwcrhk_log_message /* Log message */ +}; + + +/* Now, to our own code */ + +/* As this is only ever called once, there's no need for locking + * (indeed - the lock will already be held by our caller!!!) */ +ENGINE *ENGINE_ncipher() + { + RSA_METHOD *meth1; + DH_METHOD *meth2; + + /* We know that the "PKCS1_SSLeay()" functions hook properly + * to the cswift-specific mod_exp and mod_exp_crt so we use + * those functions. NB: We don't use ENGINE_openssl() or + * anything "more generic" because something like the RSAref + * code may not hook properly, and if you own one of these + * cards then you have the right to do RSA operations on it + * anyway! */ + meth1 = RSA_PKCS1_SSLeay(); + hwcrhk_rsa.rsa_pub_enc = meth1->rsa_pub_enc; + hwcrhk_rsa.rsa_pub_dec = meth1->rsa_pub_dec; + hwcrhk_rsa.rsa_priv_enc = meth1->rsa_priv_enc; + hwcrhk_rsa.rsa_priv_dec = meth1->rsa_priv_dec; + + /* Much the same for Diffie-Hellman */ + meth2 = DH_OpenSSL(); + hwcrhk_dh.generate_key = meth2->generate_key; + hwcrhk_dh.compute_key = meth2->compute_key; + return &engine_hwcrhk; + } + +/* This is a process-global DSO handle used for loading and unloading + * the HWCryptoHook library. NB: This is only set (or unset) during an + * init() or finish() call (reference counts permitting) and they're + * operating with global locks, so this should be thread-safe + * implicitly. */ +static DSO *hwcrhk_dso = NULL; +static HWCryptoHook_ContextHandle hwcrhk_context = 0; +static int hndidx = -1; /* Index for KM handle. Not really used yet. */ + +/* These are the function pointers that are (un)set when the library has + * successfully (un)loaded. */ +static HWCryptoHook_Init_t *p_hwcrhk_Init = NULL; +static HWCryptoHook_Finish_t *p_hwcrhk_Finish = NULL; +static HWCryptoHook_ModExp_t *p_hwcrhk_ModExp = NULL; +static HWCryptoHook_RSA_t *p_hwcrhk_RSA = NULL; +static HWCryptoHook_RandomBytes_t *p_hwcrhk_RandomBytes = NULL; +static HWCryptoHook_RSALoadKey_t *p_hwcrhk_RSALoadKey = NULL; +static HWCryptoHook_RSAGetPublicKey_t *p_hwcrhk_RSAGetPublicKey = NULL; +static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL; +static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL; + +/* Used in the DSO operations. */ +static const char *HWCRHK_LIBNAME = "nfhwcrhk"; +static const char *n_hwcrhk_Init = "HWCryptoHook_Init"; +static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish"; +static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp"; +static const char *n_hwcrhk_RSA = "HWCryptoHook_RSA"; +static const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes"; +static const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey"; +static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey"; +static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey"; +static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT"; + +/* HWCryptoHook library functions and mechanics - these are used by the + * higher-level functions further down. NB: As and where there's no + * error checking, take a look lower down where these functions are + * called, the checking and error handling is probably down there. */ + +/* utility function to obtain a context */ +static int get_context(HWCryptoHook_ContextHandle *hac) + { + char tempbuf[1024]; + HWCryptoHook_ErrMsgBuf rmsg; + + rmsg.buf = tempbuf; + rmsg.size = 1024; + + *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg, + NULL); + if (!*hac) + return 0; + return 1; + } + +/* similarly to release one. */ +static void release_context(HWCryptoHook_ContextHandle hac) + { + p_hwcrhk_Finish(hac); + } + +/* (de)initialisation functions. */ +static int hwcrhk_init() + { + HWCryptoHook_Init_t *p1; + HWCryptoHook_Finish_t *p2; + HWCryptoHook_ModExp_t *p3; + HWCryptoHook_RSA_t *p4; + HWCryptoHook_RSALoadKey_t *p5; + HWCryptoHook_RSAGetPublicKey_t *p6; + HWCryptoHook_RSAUnloadKey_t *p7; + HWCryptoHook_RandomBytes_t *p8; + HWCryptoHook_ModExpCRT_t *p9; + + if(hwcrhk_dso != NULL) + { + ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_ALREADY_LOADED); + goto err; + } + /* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */ + hwcrhk_dso = DSO_load(NULL, HWCRHK_LIBNAME, NULL, + DSO_FLAG_NAME_TRANSLATION); + if(hwcrhk_dso == NULL) + { + ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_DSO_FAILURE); + goto err; + } + if(!(p1 = (HWCryptoHook_Init_t *) + DSO_bind_func(hwcrhk_dso, n_hwcrhk_Init)) || + !(p2 = (HWCryptoHook_Finish_t *) + DSO_bind_func(hwcrhk_dso, n_hwcrhk_Finish)) || + !(p3 = (HWCryptoHook_ModExp_t *) + DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExp)) || + !(p4 = (HWCryptoHook_RSA_t *) + DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSA)) || + !(p5 = (HWCryptoHook_RSALoadKey_t *) + DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSALoadKey)) || + !(p6 = (HWCryptoHook_RSAGetPublicKey_t *) + DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAGetPublicKey)) || + !(p7 = (HWCryptoHook_RSAUnloadKey_t *) + DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAUnloadKey)) || + !(p8 = (HWCryptoHook_RandomBytes_t *) + DSO_bind_func(hwcrhk_dso, n_hwcrhk_RandomBytes)) || + !(p9 = (HWCryptoHook_ModExpCRT_t *) + DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExpCRT))) + { + ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_DSO_FAILURE); + goto err; + } + /* Copy the pointers */ + p_hwcrhk_Init = p1; + p_hwcrhk_Finish = p2; + p_hwcrhk_ModExp = p3; + p_hwcrhk_RSA = p4; + p_hwcrhk_RSALoadKey = p5; + p_hwcrhk_RSAGetPublicKey = p6; + p_hwcrhk_RSAUnloadKey = p7; + p_hwcrhk_RandomBytes = p8; + p_hwcrhk_ModExpCRT = p9; + + /* Check if the application decided to support dynamic locks, + and if it does, use them. */ + if (disable_mutex_callbacks == 0 && + CRYPTO_get_dynlock_create_callback() != NULL && + CRYPTO_get_dynlock_lock_callback() != NULL && + CRYPTO_get_dynlock_destroy_callback() != NULL) + { + hwcrhk_globals.mutex_init = hwcrhk_mutex_init; + hwcrhk_globals.mutex_acquire = hwcrhk_mutex_lock; + hwcrhk_globals.mutex_release = hwcrhk_mutex_unlock; + hwcrhk_globals.mutex_destroy = hwcrhk_mutex_destroy; + } + + /* Try and get a context - if not, we may have a DSO but no + * accelerator! */ + if(!get_context(&hwcrhk_context)) + { + ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_UNIT_FAILURE); + goto err; + } + /* Everything's fine. */ + if (hndidx == -1) + hndidx = RSA_get_ex_new_index(0, + "nFast HWCryptoHook RSA key handle", + NULL, NULL, hwcrhk_ex_free); + return 1; +err: + if(hwcrhk_dso) + DSO_free(hwcrhk_dso); + hwcrhk_dso = NULL; + p_hwcrhk_Init = NULL; + p_hwcrhk_Finish = NULL; + p_hwcrhk_ModExp = NULL; + p_hwcrhk_RSA = NULL; + p_hwcrhk_RSALoadKey = NULL; + p_hwcrhk_RSAGetPublicKey = NULL; + p_hwcrhk_RSAUnloadKey = NULL; + p_hwcrhk_ModExpCRT = NULL; + p_hwcrhk_RandomBytes = NULL; + return 0; + } + +static int hwcrhk_finish() + { + int to_return = 1; + if(hwcrhk_dso == NULL) + { + ENGINEerr(ENGINE_F_HWCRHK_FINISH,ENGINE_R_NOT_LOADED); + to_return = 0; + goto err; + } + release_context(hwcrhk_context); + if(!DSO_free(hwcrhk_dso)) + { + ENGINEerr(ENGINE_F_HWCRHK_FINISH,ENGINE_R_DSO_FAILURE); + to_return = 0; + goto err; + } + err: + if (logstream) + BIO_free(logstream); + hwcrhk_dso = NULL; + p_hwcrhk_Init = NULL; + p_hwcrhk_Finish = NULL; + p_hwcrhk_ModExp = NULL; + p_hwcrhk_RSA = NULL; + p_hwcrhk_RSALoadKey = NULL; + p_hwcrhk_RSAGetPublicKey = NULL; + p_hwcrhk_RSAUnloadKey = NULL; + p_hwcrhk_ModExpCRT = NULL; + p_hwcrhk_RandomBytes = NULL; + return to_return; + } + +static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)()) + { + int to_return = 1; + + switch(cmd) + { + case ENGINE_CTRL_SET_LOGSTREAM: + { + BIO *bio = (BIO *)p; + + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if (logstream) + { + BIO_free(logstream); + logstream = NULL; + } + if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1) + logstream = bio; + else + ENGINEerr(ENGINE_F_HWCRHK_CTRL,ENGINE_R_BIO_WAS_FREED); + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + break; + case ENGINE_CTRL_SET_PASSWORD_CALLBACK: + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + password_callback = (pem_password_cb *)f; + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + break; + /* this enables or disables the "SimpleForkCheck" flag used in the + * initialisation structure. */ + case ENGINE_CTRL_CHIL_SET_FORKCHECK: + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if(i) + hwcrhk_globals.flags |= + HWCryptoHook_InitFlags_SimpleForkCheck; + else + hwcrhk_globals.flags &= + ~HWCryptoHook_InitFlags_SimpleForkCheck; + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + break; + /* This will prevent the initialisation function from "installing" + * the mutex-handling callbacks, even if they are available from + * within the library (or were provided to the library from the + * calling application). This is to remove any baggage for + * applications not using multithreading. */ + case ENGINE_CTRL_CHIL_NO_LOCKING: + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + disable_mutex_callbacks = 1; + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + break; + + /* The command isn't understood by this engine */ + default: + ENGINEerr(ENGINE_F_HWCRHK_CTRL, + ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); + to_return = 0; + break; + } + + return to_return; + } + +static EVP_PKEY *hwcrhk_load_privkey(const char *key_id, + const char *passphrase) + { + RSA *rtmp = NULL; + EVP_PKEY *res = NULL; + HWCryptoHook_MPI e, n; + HWCryptoHook_RSAKeyHandle *hptr; + HWCryptoHook_ErrMsgBuf rmsg; + + if(!hwcrhk_context) + { + ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, + ENGINE_R_NOT_INITIALISED); + goto err; + } + hptr = OPENSSL_malloc(sizeof(HWCryptoHook_RSAKeyHandle)); + if (!hptr) + { + ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, + ERR_R_MALLOC_FAILURE); + goto err; + } + if (p_hwcrhk_RSALoadKey(hwcrhk_context, key_id, hptr, + &rmsg, NULL)) + { + ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, + ENGINE_R_CHIL_ERROR); + ERR_add_error_data(1,rmsg.buf); + goto err; + } + if (!*hptr) + { + ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, + ENGINE_R_NO_KEY); + goto err; + } + rtmp = RSA_new_method(&engine_hwcrhk); + RSA_set_ex_data(rtmp, hndidx, (char *)hptr); + rtmp->e = BN_new(); + rtmp->n = BN_new(); + rtmp->flags |= RSA_FLAG_EXT_PKEY; + MPI2BN(rtmp->e, e); + MPI2BN(rtmp->n, n); + if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg) + != HWCRYPTOHOOK_ERROR_MPISIZE) + { + ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY,ENGINE_R_CHIL_ERROR); + ERR_add_error_data(1,rmsg.buf); + goto err; + } + + bn_expand2(rtmp->e, e.size/sizeof(BN_ULONG)); + bn_expand2(rtmp->n, n.size/sizeof(BN_ULONG)); + MPI2BN(rtmp->e, e); + MPI2BN(rtmp->n, n); + + if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg)) + { + ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY, + ENGINE_R_CHIL_ERROR); + ERR_add_error_data(1,rmsg.buf); + goto err; + } + rtmp->e->top = e.size / sizeof(BN_ULONG); + bn_fix_top(rtmp->e); + rtmp->n->top = n.size / sizeof(BN_ULONG); + bn_fix_top(rtmp->n); + + res = EVP_PKEY_new(); + EVP_PKEY_assign_RSA(res, rtmp); + + return res; + err: + if (res) + EVP_PKEY_free(res); + if (rtmp) + RSA_free(rtmp); + return NULL; + } + +static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id, const char *passphrase) + { + EVP_PKEY *res = hwcrhk_load_privkey(key_id, passphrase); + + if (res) + switch(res->type) + { + case EVP_PKEY_RSA: + { + RSA *rsa = NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY); + rsa = res->pkey.rsa; + res->pkey.rsa = RSA_new(); + res->pkey.rsa->n = rsa->n; + res->pkey.rsa->e = rsa->e; + CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY); + RSA_free(rsa); + } + default: + ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY, + ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); + goto err; + } + + return res; + err: + if (res) + EVP_PKEY_free(res); + return NULL; + } + +/* A little mod_exp */ +static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx) + { + char tempbuf[1024]; + HWCryptoHook_ErrMsgBuf rmsg; + /* Since HWCryptoHook_MPI is pretty compatible with BIGNUM's, + we use them directly, plus a little macro magic. We only + thing we need to make sure of is that enough space is allocated. */ + HWCryptoHook_MPI m_a, m_p, m_n, m_r; + int to_return, ret; + + to_return = 0; /* expect failure */ + rmsg.buf = tempbuf; + rmsg.size = 1024; + + if(!hwcrhk_context) + { + ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_NOT_INITIALISED); + goto err; + } + /* Prepare the params */ + bn_expand2(r, m->top); /* Check for error !! */ + BN2MPI(m_a, a); + BN2MPI(m_p, p); + BN2MPI(m_n, m); + MPI2BN(r, m_r); + + /* Perform the operation */ + ret = p_hwcrhk_ModExp(hwcrhk_context, m_a, m_p, m_n, &m_r, &rmsg); + + /* Convert the response */ + r->top = m_r.size / sizeof(BN_ULONG); + bn_fix_top(r); + + if (ret < 0) + { + /* FIXME: When this error is returned, HWCryptoHook is + telling us that falling back to software computation + might be a good thing. */ + if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) + { + ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_REQUEST_FALLBACK); + } + else + { + ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_REQUEST_FAILED); + } + ERR_add_error_data(1,rmsg.buf); + goto err; + } + + to_return = 1; +err: + return to_return; + } + +static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa) + { + char tempbuf[1024]; + HWCryptoHook_ErrMsgBuf rmsg; + HWCryptoHook_RSAKeyHandle *hptr; + int to_return = 0, ret; + + if(!hwcrhk_context) + { + ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_NOT_INITIALISED); + goto err; + } + + /* This provides support for nForce keys. Since that's opaque data + all we do is provide a handle to the proper key and let HWCryptoHook + take care of the rest. */ + if ((hptr = (HWCryptoHook_RSAKeyHandle *) RSA_get_ex_data(rsa, hndidx)) + != NULL) + { + HWCryptoHook_MPI m_a, m_r; + + if(!rsa->n) + { + ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP, + ENGINE_R_MISSING_KEY_COMPONENTS); + goto err; + } + + rmsg.buf = tempbuf; + rmsg.size = 1024; + + /* Prepare the params */ + bn_expand2(r, rsa->n->top); /* Check for error !! */ + BN2MPI(m_a, I); + MPI2BN(r, m_r); + + /* Perform the operation */ + ret = p_hwcrhk_RSA(m_a, *hptr, &m_r, &rmsg); + + /* Convert the response */ + r->top = m_r.size / sizeof(BN_ULONG); + bn_fix_top(r); + + if (ret < 0) + { + /* FIXME: When this error is returned, HWCryptoHook is + telling us that falling back to software computation + might be a good thing. */ + if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) + { + ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FALLBACK); + } + else + { + ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FAILED); + } + ERR_add_error_data(1,rmsg.buf); + goto err; + } + } + else + { + HWCryptoHook_MPI m_a, m_p, m_q, m_dmp1, m_dmq1, m_iqmp, m_r; + + if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) + { + ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP, + ENGINE_R_MISSING_KEY_COMPONENTS); + goto err; + } + + rmsg.buf = tempbuf; + rmsg.size = 1024; + + /* Prepare the params */ + bn_expand2(r, rsa->n->top); /* Check for error !! */ + BN2MPI(m_a, I); + BN2MPI(m_p, rsa->p); + BN2MPI(m_q, rsa->q); + BN2MPI(m_dmp1, rsa->dmp1); + BN2MPI(m_dmq1, rsa->dmq1); + BN2MPI(m_iqmp, rsa->iqmp); + MPI2BN(r, m_r); + + /* Perform the operation */ + ret = p_hwcrhk_ModExpCRT(hwcrhk_context, m_a, m_p, m_q, + m_dmp1, m_dmq1, m_iqmp, &m_r, NULL); + + /* Convert the response */ + r->top = m_r.size / sizeof(BN_ULONG); + bn_fix_top(r); + + if (ret < 0) + { + /* FIXME: When this error is returned, HWCryptoHook is + telling us that falling back to software computation + might be a good thing. */ + if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) + { + ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FALLBACK); + } + else + { + ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FAILED); + } + ERR_add_error_data(1,rmsg.buf); + goto err; + } + } + /* If we're here, we must be here with some semblance of success :-) */ + to_return = 1; +err: + return to_return; + } + +/* This function is aliased to mod_exp (with the mont stuff dropped). */ +static int hwcrhk_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) + { + return hwcrhk_mod_exp(r, a, p, m, ctx); + } + +/* This function is aliased to mod_exp (with the dh and mont dropped). */ +static int hwcrhk_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) + { + return hwcrhk_mod_exp(r, a, p, m, ctx); + } + +/* Random bytes are good */ +static int hwcrhk_rand_bytes(unsigned char *buf, int num) + { + char tempbuf[1024]; + HWCryptoHook_ErrMsgBuf rmsg; + int to_return = 0; /* assume failure */ + int ret; + + rmsg.buf = tempbuf; + rmsg.size = 1024; + + if(!hwcrhk_context) + { + ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_NOT_INITIALISED); + goto err; + } + + ret = p_hwcrhk_RandomBytes(hwcrhk_context, buf, num, &rmsg); + if (ret < 0) + { + /* FIXME: When this error is returned, HWCryptoHook is + telling us that falling back to software computation + might be a good thing. */ + if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) + { + ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_REQUEST_FALLBACK); + } + else + { + ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_REQUEST_FAILED); + } + ERR_add_error_data(1,rmsg.buf); + goto err; + } + to_return = 1; + err: + return to_return; + } + +static int hwcrhk_rand_status(void) + { + return 1; + } + +/* This cleans up an RSA KM key, called when ex_data is freed */ + +static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, + int index,long argl, void *argp) +{ + char tempbuf[1024]; + HWCryptoHook_ErrMsgBuf rmsg; + HWCryptoHook_RSAKeyHandle *hptr; + int ret; + + rmsg.buf = tempbuf; + rmsg.size = 1024; + + hptr = (HWCryptoHook_RSAKeyHandle *) item; + if(!hptr) return; + ret = p_hwcrhk_RSAUnloadKey(*hptr, NULL); + OPENSSL_free(hptr); +} + +/* Mutex calls: since the HWCryptoHook model closely follows the POSIX model + * these just wrap the POSIX functions and add some logging. + */ + +static int hwcrhk_mutex_init(HWCryptoHook_Mutex* mt, + HWCryptoHook_CallerContext *cactx) + { + mt->lockid = CRYPTO_get_new_dynlockid(); + if (mt->lockid == 0) + return 0; + return 1; + } + +static int hwcrhk_mutex_lock(HWCryptoHook_Mutex *mt) + { + CRYPTO_w_lock(mt->lockid); + return 1; + } + +void hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt) + { + CRYPTO_w_unlock(mt->lockid); + } + +static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex *mt) + { + CRYPTO_destroy_dynlockid(mt->lockid); + } + +static int hwcrhk_get_pass(const char *prompt_info, + int *len_io, char *buf, + HWCryptoHook_PassphraseContext *ppctx, + HWCryptoHook_CallerContext *cactx) + { + int l = 0; + char prompt[1024]; + + if (password_callback == NULL) + { + ENGINEerr(ENGINE_F_HWCRHK_GET_PASS,ENGINE_R_NO_CALLBACK); + return -1; + } + if (prompt_info) + { + strncpy(prompt, "Card: \"", sizeof(prompt)); + l += 5; + strncpy(prompt + l, prompt_info, sizeof(prompt) - l); + l += strlen(prompt_info); + if (l + 2 < sizeof(prompt)) + { + strncpy(prompt + l, "\"\n", sizeof(prompt) - l); + l += 2; + } + } + if (l < sizeof(prompt) - 1) + { + strncpy(prompt, "Enter Passphrase :", + sizeof(prompt) - l); + l += 35; + } + prompt[l] = '\0'; + + /* I know, passing on the prompt instead of the user data *is* + a bad thing. However, that's all we have right now. + -- Richard Levitte */ + *len_io = password_callback(buf, *len_io, 0, prompt); + if(!*len_io) + return -1; + return 0; + } + +static void hwcrhk_log_message(void *logstream, const char *message) + { + BIO *lstream = NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_BIO); + if (logstream) + lstream=*(BIO **)logstream; + if (lstream) + { + BIO_write(lstream, message, strlen(message)); + } + CRYPTO_w_unlock(CRYPTO_LOCK_BIO); + } + +#endif /* !NO_HW_NCIPHER */ +#endif /* !NO_HW */ diff --git a/lib/libssl/src/crypto/engine/vendor_defns/atalla.h b/lib/libssl/src/crypto/engine/vendor_defns/atalla.h new file mode 100644 index 00000000000..8111649c546 --- /dev/null +++ b/lib/libssl/src/crypto/engine/vendor_defns/atalla.h @@ -0,0 +1,61 @@ +/* This header declares the necessary definitions for using the exponentiation + * acceleration capabilities of Atalla cards. The only cryptographic operation + * is performed by "ASI_RSAPrivateKeyOpFn" and this takes a structure that + * defines an "RSA private key". However, it is really only performing a + * regular mod_exp using the supplied modulus and exponent - no CRT form is + * being used. Hence, it is a generic mod_exp function in disguise, and we use + * it as such. + * + * Thanks to the people at Atalla for letting me know these definitions are + * fine and that they can be reproduced here. + * + * Geoff. + */ + +typedef struct ItemStr + { + unsigned char *data; + int len; + } Item; + +typedef struct RSAPrivateKeyStr + { + void *reserved; + Item version; + Item modulus; + Item publicExponent; + Item privateExponent; + Item prime[2]; + Item exponent[2]; + Item coefficient; + } RSAPrivateKey; + +/* Predeclare the function pointer types that we dynamically load from the DSO. + * These use the same names and form that Ben's original support code had (in + * crypto/bn/bn_exp.c) unless of course I've inadvertently changed the style + * somewhere along the way! + */ + +typedef int tfnASI_GetPerformanceStatistics(int reset_flag, + unsigned int *ret_buf); + +typedef int tfnASI_GetHardwareConfig(long card_num, unsigned int *ret_buf); + +typedef int tfnASI_RSAPrivateKeyOpFn(RSAPrivateKey * rsaKey, + unsigned char *output, + unsigned char *input, + unsigned int modulus_len); + +/* These are the static string constants for the DSO file name and the function + * symbol names to bind to. Regrettably, the DSO name on *nix appears to be + * "atasi.so" rather than something more consistent like "libatasi.so". At the + * time of writing, I'm not sure what the file name on win32 is but clearly + * native name translation is not possible (eg libatasi.so on *nix, and + * atasi.dll on win32). For the purposes of testing, I have created a symbollic + * link called "libatasi.so" so that we can use native name-translation - a + * better solution will be needed. */ +static const char *ATALLA_LIBNAME = "atasi"; +static const char *ATALLA_F1 = "ASI_GetHardwareConfig"; +static const char *ATALLA_F2 = "ASI_RSAPrivateKeyOpFn"; +static const char *ATALLA_F3 = "ASI_GetPerformanceStatistics"; + diff --git a/lib/libssl/src/crypto/engine/vendor_defns/cswift.h b/lib/libssl/src/crypto/engine/vendor_defns/cswift.h new file mode 100644 index 00000000000..0af14a1a92e --- /dev/null +++ b/lib/libssl/src/crypto/engine/vendor_defns/cswift.h @@ -0,0 +1,213 @@ +/* Attribution notice: Rainbow have generously allowed me to reproduce + * the necessary definitions here from their API. This means the support + * can build independently of whether application builders have the + * API or hardware. This will allow developers to easily produce software + * that has latent hardware support for any users that have accelertors + * installed, without the developers themselves needing anything extra. + * + * I have only clipped the parts from the CryptoSwift header files that + * are (or seem) relevant to the CryptoSwift support code. This is + * simply to keep the file sizes reasonable. + * [Geoff] + */ + + +/* NB: These type widths do *not* seem right in general, in particular + * they're not terribly friendly to 64-bit architectures (unsigned long) + * will be 64-bit on IA-64 for a start. I'm leaving these alone as they + * agree with Rainbow's API and this will only be called into question + * on platforms with Rainbow support anyway! ;-) */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef long SW_STATUS; /* status */ +typedef unsigned char SW_BYTE; /* 8 bit byte */ +typedef unsigned short SW_U16; /* 16 bit number */ +#if defined(_IRIX) +#include +typedef __uint32_t SW_U32; +#else +typedef unsigned long SW_U32; /* 32 bit integer */ +#endif + +#if defined(WIN32) + typedef struct _SW_U64 { + SW_U32 low32; + SW_U32 high32; + } SW_U64; /* 64 bit integer */ +#elif defined(MAC) + typedef longlong SW_U64 +#else /* Unix variants */ + typedef struct _SW_U64 { + SW_U32 low32; + SW_U32 high32; + } SW_U64; /* 64 bit integer */ +#endif + +/* status codes */ +#define SW_OK (0L) +#define SW_ERR_BASE (-10000L) +#define SW_ERR_NO_CARD (SW_ERR_BASE-1) /* The Card is not present */ +#define SW_ERR_CARD_NOT_READY (SW_ERR_BASE-2) /* The card has not powered */ + /* up yet */ +#define SW_ERR_TIME_OUT (SW_ERR_BASE-3) /* Execution of a command */ + /* time out */ +#define SW_ERR_NO_EXECUTE (SW_ERR_BASE-4) /* The Card failed to */ + /* execute the command */ +#define SW_ERR_INPUT_NULL_PTR (SW_ERR_BASE-5) /* a required pointer is */ + /* NULL */ +#define SW_ERR_INPUT_SIZE (SW_ERR_BASE-6) /* size is invalid, too */ + /* small, too large. */ +#define SW_ERR_INVALID_HANDLE (SW_ERR_BASE-7) /* Invalid SW_ACC_CONTEXT */ + /* handle */ +#define SW_ERR_PENDING (SW_ERR_BASE-8) /* A request is already out- */ + /* standing at this */ + /* context handle */ +#define SW_ERR_AVAILABLE (SW_ERR_BASE-9) /* A result is available. */ +#define SW_ERR_NO_PENDING (SW_ERR_BASE-10)/* No request is pending. */ +#define SW_ERR_NO_MEMORY (SW_ERR_BASE-11)/* Not enough memory */ +#define SW_ERR_BAD_ALGORITHM (SW_ERR_BASE-12)/* Invalid algorithm type */ + /* in SW_PARAM structure */ +#define SW_ERR_MISSING_KEY (SW_ERR_BASE-13)/* No key is associated with */ + /* context. */ + /* swAttachKeyParam() is */ + /* not called. */ +#define SW_ERR_KEY_CMD_MISMATCH \ + (SW_ERR_BASE-14)/* Cannot perform requested */ + /* SW_COMMAND_CODE since */ + /* key attached via */ + /* swAttachKeyParam() */ + /* cannot be used for this*/ + /* SW_COMMAND_CODE. */ +#define SW_ERR_NOT_IMPLEMENTED \ + (SW_ERR_BASE-15)/* Not implemented */ +#define SW_ERR_BAD_COMMAND (SW_ERR_BASE-16)/* Bad command code */ +#define SW_ERR_BAD_ITEM_SIZE (SW_ERR_BASE-17)/* too small or too large in */ + /* the "initems" or */ + /* "outitems". */ +#define SW_ERR_BAD_ACCNUM (SW_ERR_BASE-18)/* Bad accelerator number */ +#define SW_ERR_SELFTEST_FAIL (SW_ERR_BASE-19)/* At least one of the self */ + /* test fail, look at the */ + /* selfTestBitmap in */ + /* SW_ACCELERATOR_INFO for*/ + /* details. */ +#define SW_ERR_MISALIGN (SW_ERR_BASE-20)/* Certain alogrithms require*/ + /* key materials aligned */ + /* in certain order, e.g. */ + /* 128 bit for CRT */ +#define SW_ERR_OUTPUT_NULL_PTR \ + (SW_ERR_BASE-21)/* a required pointer is */ + /* NULL */ +#define SW_ERR_OUTPUT_SIZE \ + (SW_ERR_BASE-22)/* size is invalid, too */ + /* small, too large. */ +#define SW_ERR_FIRMWARE_CHECKSUM \ + (SW_ERR_BASE-23)/* firmware checksum mismatch*/ + /* download failed. */ +#define SW_ERR_UNKNOWN_FIRMWARE \ + (SW_ERR_BASE-24)/* unknown firmware error */ +#define SW_ERR_INTERRUPT (SW_ERR_BASE-25)/* request is abort when */ + /* it's waiting to be */ + /* completed. */ +#define SW_ERR_NVWRITE_FAIL (SW_ERR_BASE-26)/* error in writing to Non- */ + /* volatile memory */ +#define SW_ERR_NVWRITE_RANGE (SW_ERR_BASE-27)/* out of range error in */ + /* writing to NV memory */ +#define SW_ERR_RNG_ERROR (SW_ERR_BASE-28)/* Random Number Generation */ + /* failure */ +#define SW_ERR_DSS_FAILURE (SW_ERR_BASE-29)/* DSS Sign or Verify failure*/ +#define SW_ERR_MODEXP_FAILURE (SW_ERR_BASE-30)/* Failure in various math */ + /* calculations */ +#define SW_ERR_ONBOARD_MEMORY (SW_ERR_BASE-31)/* Error in accessing on - */ + /* board memory */ +#define SW_ERR_FIRMWARE_VERSION \ + (SW_ERR_BASE-32)/* Wrong version in firmware */ + /* update */ +#define SW_ERR_ZERO_WORKING_ACCELERATOR \ + (SW_ERR_BASE-44)/* All accelerators are bad */ + + + /* algorithm type */ +#define SW_ALG_CRT 1 +#define SW_ALG_EXP 2 +#define SW_ALG_DSA 3 +#define SW_ALG_NVDATA 4 + + /* command code */ +#define SW_CMD_MODEXP_CRT 1 /* perform Modular Exponentiation using */ + /* Chinese Remainder Theorem (CRT) */ +#define SW_CMD_MODEXP 2 /* perform Modular Exponentiation */ +#define SW_CMD_DSS_SIGN 3 /* perform DSS sign */ +#define SW_CMD_DSS_VERIFY 4 /* perform DSS verify */ +#define SW_CMD_RAND 5 /* perform random number generation */ +#define SW_CMD_NVREAD 6 /* perform read to nonvolatile RAM */ +#define SW_CMD_NVWRITE 7 /* perform write to nonvolatile RAM */ + +typedef SW_U32 SW_ALGTYPE; /* alogrithm type */ +typedef SW_U32 SW_STATE; /* state */ +typedef SW_U32 SW_COMMAND_CODE; /* command code */ +typedef SW_U32 SW_COMMAND_BITMAP[4]; /* bitmap */ + +typedef struct _SW_LARGENUMBER { + SW_U32 nbytes; /* number of bytes in the buffer "value" */ + SW_BYTE* value; /* the large integer as a string of */ + /* bytes in network (big endian) order */ +} SW_LARGENUMBER; + +typedef struct _SW_CRT { + SW_LARGENUMBER p; /* prime number p */ + SW_LARGENUMBER q; /* prime number q */ + SW_LARGENUMBER dmp1; /* exponent1 */ + SW_LARGENUMBER dmq1; /* exponent2 */ + SW_LARGENUMBER iqmp; /* CRT coefficient */ +} SW_CRT; + +typedef struct _SW_EXP { + SW_LARGENUMBER modulus; /* modulus */ + SW_LARGENUMBER exponent;/* exponent */ +} SW_EXP; + +typedef struct _SW_DSA { + SW_LARGENUMBER p; /* */ + SW_LARGENUMBER q; /* */ + SW_LARGENUMBER g; /* */ + SW_LARGENUMBER key; /* private/public key */ +} SW_DSA; + +typedef struct _SW_NVDATA { + SW_U32 accnum; /* accelerator board number */ + SW_U32 offset; /* offset in byte */ +} SW_NVDATA; + +typedef struct _SW_PARAM { + SW_ALGTYPE type; /* type of the alogrithm */ + union { + SW_CRT crt; + SW_EXP exp; + SW_DSA dsa; + SW_NVDATA nvdata; + } up; +} SW_PARAM; + +typedef SW_U32 SW_CONTEXT_HANDLE; /* opaque context handle */ + + +/* Now the OpenSSL bits, these function types are the for the function + * pointers that will bound into the Rainbow shared libraries. */ +typedef SW_STATUS t_swAcquireAccContext(SW_CONTEXT_HANDLE *hac); +typedef SW_STATUS t_swAttachKeyParam(SW_CONTEXT_HANDLE hac, + SW_PARAM *key_params); +typedef SW_STATUS t_swSimpleRequest(SW_CONTEXT_HANDLE hac, + SW_COMMAND_CODE cmd, + SW_LARGENUMBER pin[], + SW_U32 pin_count, + SW_LARGENUMBER pout[], + SW_U32 pout_count); +typedef SW_STATUS t_swReleaseAccContext(SW_CONTEXT_HANDLE hac); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + diff --git a/lib/libssl/src/crypto/evp/e_bf.c b/lib/libssl/src/crypto/evp/e_bf.c new file mode 100644 index 00000000000..72047f64dab --- /dev/null +++ b/lib/libssl/src/crypto/evp/e_bf.c @@ -0,0 +1,80 @@ +/* crypto/evp/e_bf.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef NO_BF +#include +#include "cryptlib.h" +#include +#include "evp_locl.h" +#include + +static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); + +IMPLEMENT_BLOCK_CIPHER(bf, bf_ks, BF, bf_ks, NID_bf, 8, 16, 8, + 0, bf_init_key, NULL, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL) + +static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) + { + BF_set_key(&(ctx->c.bf_ks),EVP_CIPHER_CTX_key_length(ctx),key); + return 1; + } + +#endif diff --git a/lib/libssl/src/crypto/evp/e_cast.c b/lib/libssl/src/crypto/evp/e_cast.c new file mode 100644 index 00000000000..e5af7fb4edd --- /dev/null +++ b/lib/libssl/src/crypto/evp/e_cast.c @@ -0,0 +1,82 @@ +/* crypto/evp/e_cast.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef NO_CAST + +#include +#include "cryptlib.h" +#include +#include +#include "evp_locl.h" + +static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv,int enc); + +IMPLEMENT_BLOCK_CIPHER(cast5, cast_ks, CAST, cast_ks, + NID_cast5, 8, EVP_CAST5_KEY_SIZE, 8, + EVP_CIPH_VARIABLE_LENGTH, cast_init_key, NULL, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL) + +static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) + { + CAST_set_key(&(ctx->c.cast_ks),EVP_CIPHER_CTX_key_length(ctx),key); + return 1; + } + +#endif diff --git a/lib/libssl/src/crypto/evp/e_des.c b/lib/libssl/src/crypto/evp/e_des.c new file mode 100644 index 00000000000..f4e998b81c8 --- /dev/null +++ b/lib/libssl/src/crypto/evp/e_des.c @@ -0,0 +1,118 @@ +/* crypto/evp/e_des.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef NO_DES +#include +#include "cryptlib.h" +#include +#include +#include "evp_locl.h" + +static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); + +/* Because of various casts and different names can't use IMPLEMENT_BLOCK_CIPHER */ + +static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int inl) +{ + BLOCK_CIPHER_ecb_loop() + des_ecb_encrypt((des_cblock *)(in + i), (des_cblock *)(out + i), ctx->c.des_ks, ctx->encrypt); + return 1; +} + +static int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int inl) +{ + des_ofb64_encrypt(in, out, (long)inl, ctx->c.des_ks, (des_cblock *)ctx->iv, &ctx->num); + return 1; +} + +static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int inl) +{ + des_ncbc_encrypt(in, out, (long)inl, ctx->c.des_ks, + (des_cblock *)ctx->iv, ctx->encrypt); + return 1; +} + +static int des_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int inl) +{ + des_cfb64_encrypt(in, out, (long)inl, ctx->c.des_ks, + (des_cblock *)ctx->iv, &ctx->num, ctx->encrypt); + return 1; +} + +BLOCK_CIPHER_defs(des, des_ks, NID_des, 8, 8, 8, + 0, des_init_key, NULL, + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL) + + +static int des_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,ctx->c.des_ks); + return 1; + } + +#endif diff --git a/lib/libssl/src/crypto/evp/e_des3.c b/lib/libssl/src/crypto/evp/e_des3.c new file mode 100644 index 00000000000..a9aba4ae700 --- /dev/null +++ b/lib/libssl/src/crypto/evp/e_des3.c @@ -0,0 +1,165 @@ +/* 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.] + */ + +#ifndef NO_DES +#include +#include "cryptlib.h" +#include +#include +#include "evp_locl.h" + +static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv,int enc); + +static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv,int enc); + +/* 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) +{ + BLOCK_CIPHER_ecb_loop() + des_ecb3_encrypt((des_cblock *)(in + i), (des_cblock *)(out + i), + ctx->c.des_ede.ks1, ctx->c.des_ede.ks2, ctx->c.des_ede.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) +{ + des_ede3_ofb64_encrypt(in, out, (long)inl, + ctx->c.des_ede.ks1, ctx->c.des_ede.ks2, ctx->c.des_ede.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) +{ + des_ede3_cbc_encrypt(in, out, (long)inl, + ctx->c.des_ede.ks1, ctx->c.des_ede.ks2, ctx->c.des_ede.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) +{ + des_ede3_cfb64_encrypt(in, out, (long)inl, + ctx->c.des_ede.ks1, ctx->c.des_ede.ks2, ctx->c.des_ede.ks3, + (des_cblock *)ctx->iv, &ctx->num, ctx->encrypt); + return 1; +} + +#define NID_des_ede_ecb NID_des_ede + +BLOCK_CIPHER_defs(des_ede, des_ede, NID_des_ede, 8, 16, 8, + 0, des_ede_init_key, NULL, + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL) + +#define NID_des_ede3_ecb NID_des_ede3 +#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, NID_des_ede3, 8, 24, 8, + 0, des_ede3_init_key, NULL, + EVP_CIPHER_set_asn1_iv, + 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) + { + des_cblock *deskey = (des_cblock *)key; + + des_set_key_unchecked(&deskey[0],ctx->c.des_ede.ks1); + des_set_key_unchecked(&deskey[1],ctx->c.des_ede.ks2); + memcpy( (char *)ctx->c.des_ede.ks3, + (char *)ctx->c.des_ede.ks1, + sizeof(ctx->c.des_ede.ks1)); + return 1; + } + +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; + + des_set_key_unchecked(&deskey[0],ctx->c.des_ede.ks1); + des_set_key_unchecked(&deskey[1],ctx->c.des_ede.ks2); + des_set_key_unchecked(&deskey[2],ctx->c.des_ede.ks3); + + return 1; + } + +EVP_CIPHER *EVP_des_ede(void) +{ + return &des_ede_ecb; +} + +EVP_CIPHER *EVP_des_ede3(void) +{ + return &des_ede3_ecb; +} +#endif diff --git a/lib/libssl/src/crypto/evp/e_idea.c b/lib/libssl/src/crypto/evp/e_idea.c new file mode 100644 index 00000000000..8d3c88deb71 --- /dev/null +++ b/lib/libssl/src/crypto/evp/e_idea.c @@ -0,0 +1,112 @@ +/* crypto/evp/e_idea.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef NO_IDEA + +#include +#include "cryptlib.h" +#include +#include +#include "evp_locl.h" + +static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv,int enc); + +/* NB idea_ecb_encrypt doesn't take an 'encrypt' argument so we treat it as a special + * case + */ + +static int idea_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int inl) +{ + BLOCK_CIPHER_ecb_loop() + idea_ecb_encrypt(in + i, out + i, &ctx->c.idea_ks); + return 1; +} + +/* Can't use IMPLEMENT_BLOCK_CIPHER because idea_ecb_encrypt is different */ + +BLOCK_CIPHER_func_cbc(idea, idea, idea_ks) +BLOCK_CIPHER_func_ofb(idea, idea, idea_ks) +BLOCK_CIPHER_func_cfb(idea, idea, idea_ks) + +BLOCK_CIPHER_defs(idea, idea_ks, NID_idea, 8, 16, 8, + 0, idea_init_key, NULL, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL) + +static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) + { + if(!enc) { + if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE) enc = 1; + else if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE) enc = 1; + } + if (enc) idea_set_encrypt_key(key,&(ctx->c.idea_ks)); + else + { + IDEA_KEY_SCHEDULE tmp; + + idea_set_encrypt_key(key,&tmp); + idea_set_decrypt_key(&tmp,&(ctx->c.idea_ks)); + memset((unsigned char *)&tmp,0, + sizeof(IDEA_KEY_SCHEDULE)); + } + return 1; + } + +#endif diff --git a/lib/libssl/src/crypto/evp/e_rc2.c b/lib/libssl/src/crypto/evp/e_rc2.c new file mode 100644 index 00000000000..3955c3ef848 --- /dev/null +++ b/lib/libssl/src/crypto/evp/e_rc2.c @@ -0,0 +1,222 @@ +/* crypto/evp/e_rc2.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef NO_RC2 + +#include +#include "cryptlib.h" +#include +#include +#include "evp_locl.h" + +static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv,int enc); +static int rc2_meth_to_magic(EVP_CIPHER_CTX *ctx); +static int rc2_magic_to_meth(int i); +static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); + +IMPLEMENT_BLOCK_CIPHER(rc2, rc2.ks, RC2, rc2, NID_rc2, + 8, + EVP_RC2_KEY_SIZE, 8, + EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + rc2_init_key, NULL, + rc2_set_asn1_type_and_iv, rc2_get_asn1_type_and_iv, + rc2_ctrl) + +#define RC2_40_MAGIC 0xa0 +#define RC2_64_MAGIC 0x78 +#define RC2_128_MAGIC 0x3a + +static EVP_CIPHER r2_64_cbc_cipher= + { + NID_rc2_64_cbc, + 8,8 /* 64 bit */,8, + EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + rc2_init_key, + rc2_cbc_cipher, + NULL, + sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+ + sizeof((((EVP_CIPHER_CTX *)NULL)->c.rc2)), + rc2_set_asn1_type_and_iv, + rc2_get_asn1_type_and_iv, + rc2_ctrl, + NULL + }; + +static EVP_CIPHER r2_40_cbc_cipher= + { + NID_rc2_40_cbc, + 8,5 /* 40 bit */,8, + EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + rc2_init_key, + rc2_cbc_cipher, + NULL, + sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+ + sizeof((((EVP_CIPHER_CTX *)NULL)->c.rc2)), + rc2_set_asn1_type_and_iv, + rc2_get_asn1_type_and_iv, + rc2_ctrl, + NULL + }; + +EVP_CIPHER *EVP_rc2_64_cbc(void) + { + return(&r2_64_cbc_cipher); + } + +EVP_CIPHER *EVP_rc2_40_cbc(void) + { + return(&r2_40_cbc_cipher); + } + +static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) + { + RC2_set_key(&(ctx->c.rc2.ks),EVP_CIPHER_CTX_key_length(ctx), + key,ctx->c.rc2.key_bits); + return 1; + } + +static int rc2_meth_to_magic(EVP_CIPHER_CTX *e) + { + int i; + + EVP_CIPHER_CTX_ctrl(e, EVP_CTRL_GET_RC2_KEY_BITS, 0, &i); + if (i == 128) return(RC2_128_MAGIC); + else if (i == 64) return(RC2_64_MAGIC); + else if (i == 40) return(RC2_40_MAGIC); + else return(0); + } + +static int rc2_magic_to_meth(int i) + { + if (i == RC2_128_MAGIC) return 128; + else if (i == RC2_64_MAGIC) return 64; + else if (i == RC2_40_MAGIC) return 40; + else + { + EVPerr(EVP_F_RC2_MAGIC_TO_METH,EVP_R_UNSUPPORTED_KEY_SIZE); + return(0); + } + } + +static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) + { + long num=0; + int i=0,l; + int key_bits; + unsigned char iv[EVP_MAX_IV_LENGTH]; + + if (type != NULL) + { + l=EVP_CIPHER_CTX_iv_length(c); + i=ASN1_TYPE_get_int_octetstring(type,&num,iv,l); + if (i != l) + return(-1); + key_bits =rc2_magic_to_meth((int)num); + if (!key_bits) + return(-1); + if(i > 0) EVP_CipherInit(c, NULL, NULL, iv, -1); + EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL); + EVP_CIPHER_CTX_set_key_length(c, key_bits / 8); + } + return(i); + } + +static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) + { + long num; + int i=0,j; + + if (type != NULL) + { + num=rc2_meth_to_magic(c); + j=EVP_CIPHER_CTX_iv_length(c); + i=ASN1_TYPE_set_int_octetstring(type,num,c->oiv,j); + } + return(i); + } + +static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) + { + switch(type) { + + case EVP_CTRL_INIT: + c->c.rc2.key_bits = EVP_CIPHER_CTX_key_length(c) * 8; + return 1; + + case EVP_CTRL_GET_RC2_KEY_BITS: + *(int *)ptr = c->c.rc2.key_bits; + return 1; + + + case EVP_CTRL_SET_RC2_KEY_BITS: + if(arg > 0) { + c->c.rc2.key_bits = arg; + return 1; + } + return 0; + + default: + return -1; + } + } + +#endif diff --git a/lib/libssl/src/crypto/evp/e_rc5.c b/lib/libssl/src/crypto/evp/e_rc5.c new file mode 100644 index 00000000000..5885f1826b2 --- /dev/null +++ b/lib/libssl/src/crypto/evp/e_rc5.c @@ -0,0 +1,118 @@ +/* crypto/evp/e_rc5.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef NO_RC5 + +#include +#include "cryptlib.h" +#include +#include +#include "evp_locl.h" + +static int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv,int enc); +static int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); + +IMPLEMENT_BLOCK_CIPHER(rc5_32_12_16, rc5.ks, RC5_32, rc5, NID_rc5, + 8, EVP_RC5_32_12_16_KEY_SIZE, 8, + EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + r_32_12_16_init_key, NULL, + NULL, NULL, rc5_ctrl) + + + +static int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) + { + switch(type) { + + case EVP_CTRL_INIT: + c->c.rc5.rounds = RC5_12_ROUNDS; + return 1; + + case EVP_CTRL_GET_RC5_ROUNDS: + *(int *)ptr = c->c.rc5.rounds; + return 1; + + + case EVP_CTRL_SET_RC5_ROUNDS: + switch(arg) { + case RC5_8_ROUNDS: + case RC5_12_ROUNDS: + case RC5_16_ROUNDS: + c->c.rc5.rounds = arg; + return 1; + + default: + EVPerr(EVP_F_RC5_CTRL, EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS); + return 0; + } + + default: + return -1; + } + } + +static int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) + { + RC5_32_set_key(&(ctx->c.rc5.ks),EVP_CIPHER_CTX_key_length(ctx), + key,ctx->c.rc5.rounds); + return 1; + } + +#endif diff --git a/lib/libssl/src/crypto/evp/evp_locl.h b/lib/libssl/src/crypto/evp/evp_locl.h new file mode 100644 index 00000000000..ce49d5b7d81 --- /dev/null +++ b/lib/libssl/src/crypto/evp/evp_locl.h @@ -0,0 +1,168 @@ +/* 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). + * + */ + +/* Macros to code block cipher wrappers */ + +/* Wrapper functions for each cipher mode */ + +#define BLOCK_CIPHER_ecb_loop() \ + unsigned int i; \ + if(inl < 8) return 1;\ + inl -= 8; \ + for(i=0; i <= inl; i+=8) \ + +#define BLOCK_CIPHER_func_ecb(cname, cprefix, kname) \ +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, &ctx->c.kname, ctx->encrypt);\ + return 1;\ +} + +#define BLOCK_CIPHER_func_ofb(cname, cprefix, kname) \ +static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ +{\ + cprefix##_ofb64_encrypt(in, out, (long)inl, &ctx->c.kname, ctx->iv, &ctx->num);\ + return 1;\ +} + +#define BLOCK_CIPHER_func_cbc(cname, cprefix, kname) \ +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, &ctx->c.kname, ctx->iv, ctx->encrypt);\ + return 1;\ +} + +#define BLOCK_CIPHER_func_cfb(cname, cprefix, kname) \ +static int cname##_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ +{\ + cprefix##_cfb64_encrypt(in, out, (long)inl, &ctx->c.kname, ctx->iv, &ctx->num, ctx->encrypt);\ + return 1;\ +} + +#define BLOCK_CIPHER_all_funcs(cname, cprefix, kname) \ + BLOCK_CIPHER_func_cbc(cname, cprefix, kname) \ + BLOCK_CIPHER_func_cfb(cname, cprefix, kname) \ + BLOCK_CIPHER_func_ecb(cname, cprefix, kname) \ + BLOCK_CIPHER_func_ofb(cname, cprefix, kname) + +#define BLOCK_CIPHER_defs(cname, kstruct, \ + nid, block_size, key_len, iv_len, flags,\ + init_key, cleanup, set_asn1, get_asn1, ctrl)\ +static 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 \ +};\ +EVP_CIPHER *EVP_##cname##_cbc(void) { return &cname##_cbc; }\ +static 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 \ +};\ +EVP_CIPHER *EVP_##cname##_cfb(void) { return &cname##_cfb; }\ +static 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 \ +};\ +EVP_CIPHER *EVP_##cname##_ofb(void) { return &cname##_ofb; }\ +static 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 \ +};\ +EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; } + + + +#define IMPLEMENT_BLOCK_CIPHER(cname, kname, cprefix, kstruct, \ + nid, block_size, key_len, iv_len, flags, \ + init_key, cleanup, set_asn1, get_asn1, ctrl) \ + BLOCK_CIPHER_all_funcs(cname, cprefix, kname) \ + BLOCK_CIPHER_defs(cname, kstruct, nid, block_size, key_len, iv_len, flags,\ + init_key, cleanup, set_asn1, get_asn1, ctrl) + diff --git a/lib/libssl/src/crypto/evp/m_md4.c b/lib/libssl/src/crypto/evp/m_md4.c new file mode 100644 index 00000000000..6a24ceb86d6 --- /dev/null +++ b/lib/libssl/src/crypto/evp/m_md4.c @@ -0,0 +1,83 @@ +/* crypto/evp/m_md4.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef NO_MD4 +#include +#include "cryptlib.h" +#include +#include +#include + +static EVP_MD md4_md= + { + NID_md4, + 0, + MD4_DIGEST_LENGTH, + MD4_Init, + MD4_Update, + MD4_Final, + EVP_PKEY_RSA_method, + MD4_CBLOCK, + sizeof(EVP_MD *)+sizeof(MD4_CTX), + }; + +EVP_MD *EVP_md4(void) + { + return(&md4_md); + } +#endif diff --git a/lib/libssl/src/crypto/md4/Makefile.ssl b/lib/libssl/src/crypto/md4/Makefile.ssl new file mode 100644 index 00000000000..5341bf5b463 --- /dev/null +++ b/lib/libssl/src/crypto/md4/Makefile.ssl @@ -0,0 +1,84 @@ +# +# SSLeay/crypto/md4/Makefile +# + +DIR= md4 +TOP= ../.. +CC= cc +CPP= $(CC) -E +INCLUDES= +CFLAG=-g +INSTALL_PREFIX= +OPENSSLDIR= /usr/local/ssl +INSTALLTOP=/usr/local/ssl +MAKE= make -f Makefile.ssl +MAKEDEPEND= $(TOP)/util/domd $(TOP) +MAKEFILE= Makefile.ssl +AR= ar r + +CFLAGS= $(INCLUDES) $(CFLAG) + +GENERAL=Makefile +TEST=md4test.c +APPS=md4.c + +LIB=$(TOP)/libcrypto.a +LIBSRC=md4_dgst.c md4_one.c +LIBOBJ=md4_dgst.o md4_one.o + +SRC= $(LIBSRC) + +EXHEADER= md4.h +HEADER= md4_locl.h $(EXHEADER) + +ALL= $(GENERAL) $(SRC) $(HEADER) + +top: + (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all) + +all: lib + +lib: $(LIBOBJ) + $(AR) $(LIB) $(LIBOBJ) + $(RANLIB) $(LIB) + @touch lib + +files: + $(PERL) $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO + +links: + @$(TOP)/util/point.sh Makefile.ssl Makefile + @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST) + @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS) + +install: + @for i in $(EXHEADER) ; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done; + +tags: + ctags $(SRC) + +tests: + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + $(MAKEDEPEND) $(INCLUDES) $(DEPFLAG) $(PROGS) $(LIBSRC) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f asm/mx86unix.cpp *.o asm/*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +md4_dgst.o: ../../include/openssl/md4.h ../../include/openssl/opensslconf.h +md4_dgst.o: ../../include/openssl/opensslv.h ../md32_common.h md4_locl.h +md4_one.o: ../../include/openssl/md4.h diff --git a/lib/libssl/src/crypto/md4/md4.c b/lib/libssl/src/crypto/md4/md4.c new file mode 100644 index 00000000000..e4b0aac0117 --- /dev/null +++ b/lib/libssl/src/crypto/md4/md4.c @@ -0,0 +1,127 @@ +/* crypto/md4/md4.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 +#include +#include + +#define BUFSIZE 1024*16 + +void do_fp(FILE *f); +void pt(unsigned char *md); +#ifndef _OSD_POSIX +int read(int, void *, unsigned int); +#endif + +int main(int argc, char **argv) + { + int i,err=0; + FILE *IN; + + if (argc == 1) + { + do_fp(stdin); + } + else + { + for (i=1; i + */ +#else +#define MD4_LONG unsigned int +#endif + +#define MD4_CBLOCK 64 +#define MD4_LBLOCK (MD4_CBLOCK/4) +#define MD4_DIGEST_LENGTH 16 + +typedef struct MD4state_st + { + MD4_LONG A,B,C,D; + MD4_LONG Nl,Nh; + MD4_LONG data[MD4_LBLOCK]; + int num; + } MD4_CTX; + +void MD4_Init(MD4_CTX *c); +void MD4_Update(MD4_CTX *c, const void *data, unsigned long len); +void MD4_Final(unsigned char *md, MD4_CTX *c); +unsigned char *MD4(const unsigned char *d, unsigned long n, unsigned char *md); +void MD4_Transform(MD4_CTX *c, const unsigned char *b); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/libssl/src/crypto/md4/md4_dgst.c b/lib/libssl/src/crypto/md4/md4_dgst.c new file mode 100644 index 00000000000..81488ae2e27 --- /dev/null +++ b/lib/libssl/src/crypto/md4/md4_dgst.c @@ -0,0 +1,285 @@ +/* crypto/md4/md4_dgst.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "md4_locl.h" +#include + +const char *MD4_version="MD4" OPENSSL_VERSION_PTEXT; + +/* Implemented from RFC1186 The MD4 Message-Digest Algorithm + */ + +#define INIT_DATA_A (unsigned long)0x67452301L +#define INIT_DATA_B (unsigned long)0xefcdab89L +#define INIT_DATA_C (unsigned long)0x98badcfeL +#define INIT_DATA_D (unsigned long)0x10325476L + +void MD4_Init(MD4_CTX *c) + { + c->A=INIT_DATA_A; + c->B=INIT_DATA_B; + c->C=INIT_DATA_C; + c->D=INIT_DATA_D; + c->Nl=0; + c->Nh=0; + c->num=0; + } + +#ifndef md4_block_host_order +void md4_block_host_order (MD4_CTX *c, const void *data, int num) + { + const MD4_LONG *X=data; + register unsigned long A,B,C,D; + /* + * In case you wonder why A-D are declared as long and not + * as MD4_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. + * + * + */ + + 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], 3,0); + R0(D,A,B,C,X[ 1], 7,0); + R0(C,D,A,B,X[ 2],11,0); + R0(B,C,D,A,X[ 3],19,0); + R0(A,B,C,D,X[ 4], 3,0); + R0(D,A,B,C,X[ 5], 7,0); + R0(C,D,A,B,X[ 6],11,0); + R0(B,C,D,A,X[ 7],19,0); + R0(A,B,C,D,X[ 8], 3,0); + R0(D,A,B,C,X[ 9], 7,0); + R0(C,D,A,B,X[10],11,0); + R0(B,C,D,A,X[11],19,0); + R0(A,B,C,D,X[12], 3,0); + R0(D,A,B,C,X[13], 7,0); + R0(C,D,A,B,X[14],11,0); + R0(B,C,D,A,X[15],19,0); + /* Round 1 */ + R1(A,B,C,D,X[ 0], 3,0x5A827999L); + R1(D,A,B,C,X[ 4], 5,0x5A827999L); + R1(C,D,A,B,X[ 8], 9,0x5A827999L); + R1(B,C,D,A,X[12],13,0x5A827999L); + R1(A,B,C,D,X[ 1], 3,0x5A827999L); + R1(D,A,B,C,X[ 5], 5,0x5A827999L); + R1(C,D,A,B,X[ 9], 9,0x5A827999L); + R1(B,C,D,A,X[13],13,0x5A827999L); + R1(A,B,C,D,X[ 2], 3,0x5A827999L); + R1(D,A,B,C,X[ 6], 5,0x5A827999L); + R1(C,D,A,B,X[10], 9,0x5A827999L); + R1(B,C,D,A,X[14],13,0x5A827999L); + R1(A,B,C,D,X[ 3], 3,0x5A827999L); + R1(D,A,B,C,X[ 7], 5,0x5A827999L); + R1(C,D,A,B,X[11], 9,0x5A827999L); + R1(B,C,D,A,X[15],13,0x5A827999L); + /* Round 2 */ + R2(A,B,C,D,X[ 0], 3,0x6ED9EBA1); + R2(D,A,B,C,X[ 8], 9,0x6ED9EBA1); + R2(C,D,A,B,X[ 4],11,0x6ED9EBA1); + R2(B,C,D,A,X[12],15,0x6ED9EBA1); + R2(A,B,C,D,X[ 2], 3,0x6ED9EBA1); + R2(D,A,B,C,X[10], 9,0x6ED9EBA1); + R2(C,D,A,B,X[ 6],11,0x6ED9EBA1); + R2(B,C,D,A,X[14],15,0x6ED9EBA1); + R2(A,B,C,D,X[ 1], 3,0x6ED9EBA1); + R2(D,A,B,C,X[ 9], 9,0x6ED9EBA1); + R2(C,D,A,B,X[ 5],11,0x6ED9EBA1); + R2(B,C,D,A,X[13],15,0x6ED9EBA1); + R2(A,B,C,D,X[ 3], 3,0x6ED9EBA1); + R2(D,A,B,C,X[11], 9,0x6ED9EBA1); + R2(C,D,A,B,X[ 7],11,0x6ED9EBA1); + R2(B,C,D,A,X[15],15,0x6ED9EBA1); + + A = c->A += A; + B = c->B += B; + C = c->C += C; + D = c->D += D; + } + } +#endif + +#ifndef md4_block_data_order +#ifdef X +#undef X +#endif +void md4_block_data_order (MD4_CTX *c, const void *data_, int num) + { + const unsigned char *data=data_; + register unsigned long A,B,C,D,l; + /* + * In case you wonder why A-D are declared as long and not + * as MD4_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. + * + * + */ +#ifndef MD32_XARRAY + /* See comment in crypto/sha/sha_locl.h for details. */ + unsigned long XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, + XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15; +# define X(i) XX##i +#else + MD4_LONG XX[MD4_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), 3,0); HOST_c2l(data,l); X( 2)=l; + R0(D,A,B,C,X( 1), 7,0); HOST_c2l(data,l); X( 3)=l; + R0(C,D,A,B,X( 2),11,0); HOST_c2l(data,l); X( 4)=l; + R0(B,C,D,A,X( 3),19,0); HOST_c2l(data,l); X( 5)=l; + R0(A,B,C,D,X( 4), 3,0); HOST_c2l(data,l); X( 6)=l; + R0(D,A,B,C,X( 5), 7,0); HOST_c2l(data,l); X( 7)=l; + R0(C,D,A,B,X( 6),11,0); HOST_c2l(data,l); X( 8)=l; + R0(B,C,D,A,X( 7),19,0); HOST_c2l(data,l); X( 9)=l; + R0(A,B,C,D,X( 8), 3,0); HOST_c2l(data,l); X(10)=l; + R0(D,A,B,C,X( 9), 7,0); HOST_c2l(data,l); X(11)=l; + R0(C,D,A,B,X(10),11,0); HOST_c2l(data,l); X(12)=l; + R0(B,C,D,A,X(11),19,0); HOST_c2l(data,l); X(13)=l; + R0(A,B,C,D,X(12), 3,0); HOST_c2l(data,l); X(14)=l; + R0(D,A,B,C,X(13), 7,0); HOST_c2l(data,l); X(15)=l; + R0(C,D,A,B,X(14),11,0); + R0(B,C,D,A,X(15),19,0); + /* Round 1 */ + R1(A,B,C,D,X( 0), 3,0x5A827999L); + R1(D,A,B,C,X( 4), 5,0x5A827999L); + R1(C,D,A,B,X( 8), 9,0x5A827999L); + R1(B,C,D,A,X(12),13,0x5A827999L); + R1(A,B,C,D,X( 1), 3,0x5A827999L); + R1(D,A,B,C,X( 5), 5,0x5A827999L); + R1(C,D,A,B,X( 9), 9,0x5A827999L); + R1(B,C,D,A,X(13),13,0x5A827999L); + R1(A,B,C,D,X( 2), 3,0x5A827999L); + R1(D,A,B,C,X( 6), 5,0x5A827999L); + R1(C,D,A,B,X(10), 9,0x5A827999L); + R1(B,C,D,A,X(14),13,0x5A827999L); + R1(A,B,C,D,X( 3), 3,0x5A827999L); + R1(D,A,B,C,X( 7), 5,0x5A827999L); + R1(C,D,A,B,X(11), 9,0x5A827999L); + R1(B,C,D,A,X(15),13,0x5A827999L); + /* Round 2 */ + R2(A,B,C,D,X( 0), 3,0x6ED9EBA1L); + R2(D,A,B,C,X( 8), 9,0x6ED9EBA1L); + R2(C,D,A,B,X( 4),11,0x6ED9EBA1L); + R2(B,C,D,A,X(12),15,0x6ED9EBA1L); + R2(A,B,C,D,X( 2), 3,0x6ED9EBA1L); + R2(D,A,B,C,X(10), 9,0x6ED9EBA1L); + R2(C,D,A,B,X( 6),11,0x6ED9EBA1L); + R2(B,C,D,A,X(14),15,0x6ED9EBA1L); + R2(A,B,C,D,X( 1), 3,0x6ED9EBA1L); + R2(D,A,B,C,X( 9), 9,0x6ED9EBA1L); + R2(C,D,A,B,X( 5),11,0x6ED9EBA1L); + R2(B,C,D,A,X(13),15,0x6ED9EBA1L); + R2(A,B,C,D,X( 3), 3,0x6ED9EBA1L); + R2(D,A,B,C,X(11), 9,0x6ED9EBA1L); + R2(C,D,A,B,X( 7),11,0x6ED9EBA1L); + R2(B,C,D,A,X(15),15,0x6ED9EBA1L); + + A = c->A += A; + B = c->B += B; + C = c->C += C; + D = c->D += D; + } + } +#endif + +#ifdef undef +int printit(unsigned long *l) + { + int i,ii; + + for (i=0; i<2; i++) + { + for (ii=0; ii<8; ii++) + { + fprintf(stderr,"%08lx ",l[i*8+ii]); + } + fprintf(stderr,"\n"); + } + } +#endif diff --git a/lib/libssl/src/crypto/md4/md4_locl.h b/lib/libssl/src/crypto/md4/md4_locl.h new file mode 100644 index 00000000000..0a2b39018da --- /dev/null +++ b/lib/libssl/src/crypto/md4/md4_locl.h @@ -0,0 +1,154 @@ +/* crypto/md4/md4_locl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#ifndef MD4_LONG_LOG2 +#define MD4_LONG_LOG2 2 /* default to 32 bits */ +#endif + +void md4_block_host_order (MD4_CTX *c, const void *p,int num); +void md4_block_data_order (MD4_CTX *c, const void *p,int num); + +#if defined(__i386) || defined(_M_IX86) || defined(__INTEL__) +/* + * *_block_host_order is expected to handle aligned data while + * *_block_data_order - unaligned. As algorithm and host (x86) + * are in this case of the same "endianness" these two are + * otherwise indistinguishable. But normally you don't want to + * call the same function because unaligned access in places + * where alignment is expected is usually a "Bad Thing". Indeed, + * on RISCs you get punished with BUS ERROR signal or *severe* + * performance degradation. Intel CPUs are in turn perfectly + * capable of loading unaligned data without such drastic side + * effect. Yes, they say it's slower than aligned load, but no + * exception is generated and therefore performance degradation + * is *incomparable* with RISCs. What we should weight here is + * costs of unaligned access against costs of aligning data. + * According to my measurements allowing unaligned access results + * in ~9% performance improvement on Pentium II operating at + * 266MHz. I won't be surprised if the difference will be higher + * on faster systems:-) + * + * + */ +#define md4_block_data_order md4_block_host_order +#endif + +#define DATA_ORDER_IS_LITTLE_ENDIAN + +#define HASH_LONG MD4_LONG +#define HASH_LONG_LOG2 MD4_LONG_LOG2 +#define HASH_CTX MD4_CTX +#define HASH_CBLOCK MD4_CBLOCK +#define HASH_LBLOCK MD4_LBLOCK +#define HASH_UPDATE MD4_Update +#define HASH_TRANSFORM MD4_Transform +#define HASH_FINAL MD4_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 md4_block_host_order +#if !defined(L_ENDIAN) || defined(md4_block_data_order) +#define HASH_BLOCK_DATA_ORDER md4_block_data_order +/* + * Little-endians (Intel and Alpha) feel better without this. + * It looks like memcpy does better job than generic + * md4_block_data_order on copying-n-aligning input data. + * But frankly speaking I didn't expect such result on Alpha. + * On the other hand I've got this with egcs-1.0.2 and if + * program is compiled with another (better?) compiler it + * might turn out other way around. + * + * + */ +#endif + +#include "md32_common.h" + +/* +#define F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) +#define G(x,y,z) (((x) & (y)) | ((x) & ((z))) | ((y) & ((z)))) +*/ + +/* As pointed out by Wei Dai , 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)) | ((b) & (d)) | ((c) & (d))) +#define H(b,c,d) ((b) ^ (c) ^ (d)) + +#define R0(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+F((b),(c),(d))); \ + a=ROTATE(a,s); }; + +#define R1(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+G((b),(c),(d))); \ + a=ROTATE(a,s); };\ + +#define R2(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+H((b),(c),(d))); \ + a=ROTATE(a,s); }; diff --git a/lib/libssl/src/crypto/md4/md4_one.c b/lib/libssl/src/crypto/md4/md4_one.c new file mode 100644 index 00000000000..87a995d38d4 --- /dev/null +++ b/lib/libssl/src/crypto/md4/md4_one.c @@ -0,0 +1,95 @@ +/* crypto/md4/md4_one.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#ifdef CHARSET_EBCDIC +#include +#endif + +unsigned char *MD4(const unsigned char *d, unsigned long n, unsigned char *md) + { + MD4_CTX c; + static unsigned char m[MD4_DIGEST_LENGTH]; + + if (md == NULL) md=m; + MD4_Init(&c); +#ifndef CHARSET_EBCDIC + MD4_Update(&c,d,n); +#else + { + char temp[1024]; + unsigned long chunk; + + while (n > 0) + { + chunk = (n > sizeof(temp)) ? sizeof(temp) : n; + ebcdic2ascii(temp, d, chunk); + MD4_Update(&c,temp,chunk); + n -= chunk; + d += chunk; + } + } +#endif + MD4_Final(md,&c); + memset(&c,0,sizeof(c)); /* security consideration */ + return(md); + } + diff --git a/lib/libssl/src/crypto/md4/md4s.cpp b/lib/libssl/src/crypto/md4/md4s.cpp new file mode 100644 index 00000000000..c0ec97fc9f9 --- /dev/null +++ b/lib/libssl/src/crypto/md4/md4s.cpp @@ -0,0 +1,78 @@ +// +// gettsc.inl +// +// gives access to the Pentium's (secret) cycle counter +// +// This software was written by Leonard Janke (janke@unixg.ubc.ca) +// in 1996-7 and is entered, by him, into the public domain. + +#if defined(__WATCOMC__) +void GetTSC(unsigned long&); +#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax]; +#elif defined(__GNUC__) +inline +void GetTSC(unsigned long& tsc) +{ + asm volatile(".byte 15, 49\n\t" + : "=eax" (tsc) + : + : "%edx", "%eax"); +} +#elif defined(_MSC_VER) +inline +void GetTSC(unsigned long& tsc) +{ + unsigned long a; + __asm _emit 0fh + __asm _emit 31h + __asm mov a, eax; + tsc=a; +} +#endif + +#include +#include +#include + +extern "C" { +void md4_block_x86(MD4_CTX *ctx, unsigned char *buffer,int num); +} + +void main(int argc,char *argv[]) + { + unsigned char buffer[64*256]; + MD4_CTX ctx; + unsigned long s1,s2,e1,e2; + unsigned char k[16]; + unsigned long data[2]; + unsigned char iv[8]; + int i,num=0,numm; + int j=0; + + if (argc >= 2) + num=atoi(argv[1]); + + if (num == 0) num=16; + if (num > 250) num=16; + numm=num+2; + num*=64; + numm*=64; + + for (j=0; j<6; j++) + { + for (i=0; i<10; i++) /**/ + { + md4_block_x86(&ctx,buffer,numm); + GetTSC(s1); + md4_block_x86(&ctx,buffer,numm); + GetTSC(e1); + GetTSC(s2); + md4_block_x86(&ctx,buffer,num); + GetTSC(e2); + md4_block_x86(&ctx,buffer,num); + } + printf("md4 (%d bytes) %d %d (%.2f)\n",num, + e1-s1,e2-s2,(double)((e1-s1)-(e2-s2))/2); + } + } + diff --git a/lib/libssl/src/crypto/md4/md4test.c b/lib/libssl/src/crypto/md4/md4test.c new file mode 100644 index 00000000000..97e6e21efd1 --- /dev/null +++ b/lib/libssl/src/crypto/md4/md4test.c @@ -0,0 +1,131 @@ +/* crypto/md4/md4test.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 +#include +#include + +#ifdef NO_MD4 +int main(int argc, char *argv[]) +{ + printf("No MD4 support\n"); + return(0); +} +#else +#include + +static char *test[]={ + "", + "a", + "abc", + "message digest", + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "12345678901234567890123456789012345678901234567890123456789012345678901234567890", + NULL, + }; + +static char *ret[]={ +"31d6cfe0d16ae931b73c59d7e0c089c0", +"bde52cb31de33e46245e05fbdbd6fb24", +"a448017aaf21d8525fc10ae87aa6729d", +"d9130a8164549fe818874806e1c7014b", +"d79e1c308aa5bbcdeea8ed63df412da9", +"043f8582f241db351ce627e153e7f0e4", +"e33b4ddc9c38f2199c3e7b164fcc0536", +}; + +static char *pt(unsigned char *md); +int main(int argc, char *argv[]) + { + int i,err=0; + unsigned char **P,**R; + char *p; + + P=(unsigned char **)test; + R=(unsigned char **)ret; + i=1; + while (*P != NULL) + { + p=pt(MD4(&(P[0][0]),(unsigned long)strlen((char *)*P),NULL)); + if (strcmp(p,(char *)*R) != 0) + { + printf("error calculating MD4 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) + { + chop; + $o++; + s/#.*$//; + next if /^\s*$/; + ($Cname,$mynum) = split; + if (defined($nidn{$mynum})) + { die "$ARGV[1]:$o:There's already an object with NID ",$mynum," on line ",$order{$mynum},"\n"; } + $nid{$Cname} = $mynum; + $nidn{$mynum} = $Cname; + $order{$mynum} = $o; + $max_nid = $mynum if $mynum > $max_nid; + } +close NUMIN; + +open (IN,"$ARGV[0]") || die "Can't open input file $ARGV[0]"; +$Cname=""; +$o=0; +while () + { + chop; + $o++; + if (/^!module\s+(.*)$/) + { + $module = $1."-"; + $module =~ s/\./_/g; + $module =~ s/-/_/g; + } + if (/^!global$/) + { $module = ""; } + if (/^!Cname\s+(.*)$/) + { $Cname = $1; } + if (/^!Alias\s+(.+?)\s+(.*)$/) + { + $Cname = $module.$1; + $myoid = $2; + $myoid = &process_oid($myoid); + $Cname =~ s/-/_/g; + $ordern{$o} = $Cname; + $order{$Cname} = $o; + $obj{$Cname} = $myoid; + $_ = ""; + $Cname = ""; + } + s/!.*$//; + s/#.*$//; + next if /^\s*$/; + ($myoid,$mysn,$myln) = split ':'; + $mysn =~ s/^\s*//; + $mysn =~ s/\s*$//; + $myln =~ s/^\s*//; + $myln =~ s/\s*$//; + $myoid =~ s/^\s*//; + $myoid =~ s/\s*$//; + if ($myoid ne "") + { + $myoid = &process_oid($myoid); + } + + if ($Cname eq "" && !($myln =~ / /)) + { + $Cname = $myln; + $Cname =~ s/\./_/g; + $Cname =~ s/-/_/g; + if ($Cname ne "" && defined($ln{$module.$Cname})) + { die "objects.txt:$o:There's already an object with long name ",$ln{$module.$Cname}," on line ",$order{$module.$Cname},"\n"; } + } + if ($Cname eq "") + { + $Cname = $mysn; + $Cname =~ s/-/_/g; + if ($Cname ne "" && defined($sn{$module.$Cname})) + { die "objects.txt:$o:There's already an object with short name ",$sn{$module.$Cname}," on line ",$order{$module.$Cname},"\n"; } + } + if ($Cname eq "") + { + $Cname = $myln; + $Cname =~ s/-/_/g; + $Cname =~ s/\./_/g; + $Cname =~ s/ /_/g; + if ($Cname ne "" && defined($ln{$module.$Cname})) + { die "objects.txt:$o:There's already an object with long name ",$ln{$module.$Cname}," on line ",$order{$module.$Cname},"\n"; } + } + $Cname =~ s/\./_/g; + $Cname =~ s/-/_/g; + $Cname = $module.$Cname; + $ordern{$o} = $Cname; + $order{$Cname} = $o; + $sn{$Cname} = $mysn; + $ln{$Cname} = $myln; + $obj{$Cname} = $myoid; + if (!defined($nid{$Cname})) + { + $max_nid++; + $nid{$Cname} = $max_nid; + $nidn{$max_nid} = $Cname; + } + $Cname=""; + } +close IN; + +open (NUMOUT,">$ARGV[1]") || die "Can't open output file $ARGV[1]"; +foreach (sort { $a <=> $b } keys %nidn) + { + print NUMOUT $nidn{$_},"\t\t",$_,"\n"; + } +close NUMOUT; + +open (OUT,">$ARGV[2]") || die "Can't open output file $ARGV[2]"; +print OUT <<'EOF'; +/* lib/obj/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.] + */ + +/* 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 + */ + +#define SN_undef "UNDEF" +#define LN_undef "undefined" +#define NID_undef 0 +#define OBJ_undef 0L + +EOF + +foreach (sort { $a <=> $b } keys %ordern) + { + $Cname=$ordern{$_}; + print OUT "#define SN_",$Cname,"\t\t\"",$sn{$Cname},"\"\n" if $sn{$Cname} ne ""; + print OUT "#define LN_",$Cname,"\t\t\"",$ln{$Cname},"\"\n" if $ln{$Cname} ne ""; + print OUT "#define NID_",$Cname,"\t\t",$nid{$Cname},"\n" if $nid{$Cname} ne ""; + print OUT "#define OBJ_",$Cname,"\t\t",$obj{$Cname},"\n" if $obj{$Cname} ne ""; + print OUT "\n"; + } + +close OUT; + +sub process_oid + { + local($oid)=@_; + local(@a,$oid_pref); + + @a = split(/\s+/,$myoid); + $pref_oid = ""; + $pref_sep = ""; + if (!($a[0] =~ /^[0-9]+$/)) + { + $a[0] =~ s/-/_/g; + $pref_oid = "OBJ_" . $a[0]; + $pref_sep = ","; + shift @a; + } + $oids = join('L,',@a) . "L"; + if ($oids ne "L") + { + $oids = $pref_oid . $pref_sep . $oids; + } + else + { + $oids = $pref_oid; + } + return($oids); + } diff --git a/lib/libssl/src/crypto/rand/rand_lcl.h b/lib/libssl/src/crypto/rand/rand_lcl.h new file mode 100644 index 00000000000..120e9366d2e --- /dev/null +++ b/lib/libssl/src/crypto/rand/rand_lcl.h @@ -0,0 +1,184 @@ +/* crypto/rand/md_rand.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * 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). + * + */ + +#ifndef HEADER_RAND_LCL_H +#define HEADER_RAND_LCL_H + +#define ENTROPY_NEEDED 20 /* require 160 bits = 20 bytes of randomness */ + + +#if !defined(USE_MD5_RAND) && !defined(USE_SHA1_RAND) && !defined(USE_MDC2_RAND) && !defined(USE_MD2_RAND) +#if !defined(NO_SHA) && !defined(NO_SHA1) +#define USE_SHA1_RAND +#elif !defined(NO_MD5) +#define USE_MD5_RAND +#elif !defined(NO_MDC2) && !defined(NO_DES) +#define USE_MDC2_RAND +#elif !defined(NO_MD2) +#define USE_MD2_RAND +#else +#error No message digest algorithm available +#endif +#endif + +#if defined(USE_MD5_RAND) +#include +#define MD_DIGEST_LENGTH MD5_DIGEST_LENGTH +#define MD(a,b,c) MD5(a,b,c) +#elif defined(USE_SHA1_RAND) +#include +#define MD_DIGEST_LENGTH SHA_DIGEST_LENGTH +#define MD(a,b,c) SHA1(a,b,c) +#elif defined(USE_MDC2_RAND) +#include +#define MD_DIGEST_LENGTH MDC2_DIGEST_LENGTH +#define MD(a,b,c) MDC2(a,b,c) +#elif defined(USE_MD2_RAND) +#include +#define MD_DIGEST_LENGTH MD2_DIGEST_LENGTH +#define MD(a,b,c) MD2(a,b,c) +#endif +#if defined(USE_MD5_RAND) +#include +#define MD_DIGEST_LENGTH MD5_DIGEST_LENGTH +#define MD_CTX MD5_CTX +#define MD_Init(a) MD5_Init(a) +#define MD_Update(a,b,c) MD5_Update(a,b,c) +#define MD_Final(a,b) MD5_Final(a,b) +#define MD(a,b,c) MD5(a,b,c) +#elif defined(USE_SHA1_RAND) +#include +#define MD_DIGEST_LENGTH SHA_DIGEST_LENGTH +#define MD_CTX SHA_CTX +#define MD_Init(a) SHA1_Init(a) +#define MD_Update(a,b,c) SHA1_Update(a,b,c) +#define MD_Final(a,b) SHA1_Final(a,b) +#define MD(a,b,c) SHA1(a,b,c) +#elif defined(USE_MDC2_RAND) +#include +#define MD_DIGEST_LENGTH MDC2_DIGEST_LENGTH +#define MD_CTX MDC2_CTX +#define MD_Init(a) MDC2_Init(a) +#define MD_Update(a,b,c) MDC2_Update(a,b,c) +#define MD_Final(a,b) MDC2_Final(a,b) +#define MD(a,b,c) MDC2(a,b,c) +#elif defined(USE_MD2_RAND) +#include +#define MD_DIGEST_LENGTH MD2_DIGEST_LENGTH +#define MD_CTX MD2_CTX +#define MD_Init(a) MD2_Init(a) +#define MD_Update(a,b,c) MD2_Update(a,b,c) +#define MD_Final(a,b) MD2_Final(a,b) +#define MD(a,b,c) MD2(a,b,c) +#endif + + +#endif diff --git a/lib/libssl/src/crypto/rand/rand_win.c b/lib/libssl/src/crypto/rand/rand_win.c new file mode 100644 index 00000000000..9f2dcff9a92 --- /dev/null +++ b/lib/libssl/src/crypto/rand/rand_win.c @@ -0,0 +1,732 @@ +/* crypto/rand/rand_win.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). + * + */ + +#include "cryptlib.h" +#include +#include "rand_lcl.h" + +#if defined(WINDOWS) || defined(WIN32) +#include +#ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0400 +#endif +#include +#include + +/* Intel hardware RNG CSP -- available from + * http://developer.intel.com/design/security/rng/redist_license.htm + */ +#define PROV_INTEL_SEC 22 +#define INTEL_DEF_PROV "Intel Hardware Cryptographic Service Provider" + +static void readtimer(void); +static void readscreen(void); + +/* It appears like CURSORINFO, PCURSORINFO and LPCURSORINFO are only defined + when WINVER is 0x0500 and up, which currently only happens on Win2000. + Unfortunately, those are typedefs, so they're a little bit difficult to + detect properly. On the other hand, the macro CURSOR_SHOWING is defined + within the same conditional, so it can be use to detect the absence of said + typedefs. */ + +#ifndef CURSOR_SHOWING +/* + * Information about the global cursor. + */ +typedef struct tagCURSORINFO +{ + DWORD cbSize; + DWORD flags; + HCURSOR hCursor; + POINT ptScreenPos; +} CURSORINFO, *PCURSORINFO, *LPCURSORINFO; + +#define CURSOR_SHOWING 0x00000001 +#endif /* CURSOR_SHOWING */ + +typedef BOOL (WINAPI *CRYPTACQUIRECONTEXT)(HCRYPTPROV *, LPCTSTR, LPCTSTR, + DWORD, DWORD); +typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV, DWORD, BYTE *); +typedef BOOL (WINAPI *CRYPTRELEASECONTEXT)(HCRYPTPROV, DWORD); + +typedef HWND (WINAPI *GETFOREGROUNDWINDOW)(VOID); +typedef BOOL (WINAPI *GETCURSORINFO)(PCURSORINFO); +typedef DWORD (WINAPI *GETQUEUESTATUS)(UINT); + +typedef HANDLE (WINAPI *CREATETOOLHELP32SNAPSHOT)(DWORD, DWORD); +typedef BOOL (WINAPI *HEAP32FIRST)(LPHEAPENTRY32, DWORD, DWORD); +typedef BOOL (WINAPI *HEAP32NEXT)(LPHEAPENTRY32); +typedef BOOL (WINAPI *HEAP32LIST)(HANDLE, LPHEAPLIST32); +typedef BOOL (WINAPI *PROCESS32)(HANDLE, LPPROCESSENTRY32); +typedef BOOL (WINAPI *THREAD32)(HANDLE, LPTHREADENTRY32); +typedef BOOL (WINAPI *MODULE32)(HANDLE, LPMODULEENTRY32); + +#include +#include +#if 1 /* The NET API is Unicode only. It requires the use of the UNICODE + * macro. When UNICODE is defined LPTSTR becomes LPWSTR. LMSTR was + * was added to the Platform SDK to allow the NET API to be used in + * non-Unicode applications provided that Unicode strings were still + * used for input. LMSTR is defined as LPWSTR. + */ +typedef NET_API_STATUS (NET_API_FUNCTION * NETSTATGET) + (LPWSTR, LPWSTR, DWORD, DWORD, LPBYTE*); +typedef NET_API_STATUS (NET_API_FUNCTION * NETFREE)(LPBYTE); +#endif /* 1 */ + +int RAND_poll(void) +{ + MEMORYSTATUS m; + HCRYPTPROV hProvider = 0; + BYTE buf[64]; + DWORD w; + HWND h; + + HMODULE advapi, kernel, user, netapi; + CRYPTACQUIRECONTEXT acquire = 0; + CRYPTGENRANDOM gen = 0; + CRYPTRELEASECONTEXT release = 0; +#if 1 /* There was previously a problem with NETSTATGET. Currently, this + * section is still experimental, but if all goes well, this conditional + * will be removed + */ + NETSTATGET netstatget = 0; + NETFREE netfree = 0; +#endif /* 1 */ + + /* Determine the OS version we are on so we can turn off things + * that do not work properly. + */ + OSVERSIONINFO osverinfo ; + osverinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO) ; + GetVersionEx( &osverinfo ) ; + + /* load functions dynamically - not available on all systems */ + advapi = LoadLibrary("ADVAPI32.DLL"); + kernel = LoadLibrary("KERNEL32.DLL"); + user = LoadLibrary("USER32.DLL"); + netapi = LoadLibrary("NETAPI32.DLL"); + +#if 1 /* There was previously a problem with NETSTATGET. Currently, this + * section is still experimental, but if all goes well, this conditional + * will be removed + */ + if (netapi) + { + netstatget = (NETSTATGET) GetProcAddress(netapi,"NetStatisticsGet"); + netfree = (NETFREE) GetProcAddress(netapi,"NetApiBufferFree"); + } + + if (netstatget && netfree) + { + LPBYTE outbuf; + /* NetStatisticsGet() is a Unicode only function + * STAT_WORKSTATION_0 contains 45 fields and STAT_SERVER_0 + * contains 17 fields. We treat each field as a source of + * one byte of entropy. + */ + + if (netstatget(NULL, L"LanmanWorkstation", 0, 0, &outbuf) == 0) + { + RAND_add(outbuf, sizeof(STAT_WORKSTATION_0), 45); + netfree(outbuf); + } + if (netstatget(NULL, L"LanmanServer", 0, 0, &outbuf) == 0) + { + RAND_add(outbuf, sizeof(STAT_SERVER_0), 17); + netfree(outbuf); + } + } + + if (netapi) + FreeLibrary(netapi); +#endif /* 1 */ + + /* It appears like this can cause an exception deep within ADVAPI32.DLL + * at random times on Windows 2000. Reported by Jeffrey Altman. + * Only use it on NT. + */ + if ( osverinfo.dwPlatformId == VER_PLATFORM_WIN32_NT && + osverinfo.dwMajorVersion < 5) + { + /* Read Performance Statistics from NT/2000 registry + * The size of the performance data can vary from call + * to call so we must guess the size of the buffer to use + * and increase its size if we get an ERROR_MORE_DATA + * return instead of ERROR_SUCCESS. + */ + LONG rc=ERROR_MORE_DATA; + char * buf=NULL; + DWORD bufsz=0; + DWORD length; + + while (rc == ERROR_MORE_DATA) + { + buf = realloc(buf,bufsz+8192); + if (!buf) + break; + bufsz += 8192; + + length = bufsz; + rc = RegQueryValueEx(HKEY_PERFORMANCE_DATA, "Global", + NULL, NULL, buf, &length); + } + if (rc == ERROR_SUCCESS) + { + /* For entropy count assume only least significant + * byte of each DWORD is random. + */ + RAND_add(&length, sizeof(length), 0); + RAND_add(buf, length, length / 4.0); + } + if (buf) + free(buf); + } + + if (advapi) + { + acquire = (CRYPTACQUIRECONTEXT) GetProcAddress(advapi, + "CryptAcquireContextA"); + gen = (CRYPTGENRANDOM) GetProcAddress(advapi, + "CryptGenRandom"); + release = (CRYPTRELEASECONTEXT) GetProcAddress(advapi, + "CryptReleaseContext"); + } + + if (acquire && gen && release) + { + /* poll the CryptoAPI PRNG */ + /* The CryptoAPI returns sizeof(buf) bytes of randomness */ + if (acquire(&hProvider, 0, 0, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT)) + { + if (gen(hProvider, sizeof(buf), buf) != 0) + { + RAND_add(buf, sizeof(buf), sizeof(buf)); +#ifdef DEBUG + printf("randomness from PROV_RSA_FULL\n"); +#endif + } + release(hProvider, 0); + } + + /* poll the Pentium PRG with CryptoAPI */ + if (acquire(&hProvider, 0, INTEL_DEF_PROV, PROV_INTEL_SEC, 0)) + { + if (gen(hProvider, sizeof(buf), buf) != 0) + { + RAND_add(buf, sizeof(buf), sizeof(buf)); +#ifdef DEBUG + printf("randomness from PROV_INTEL_SEC\n"); +#endif + } + release(hProvider, 0); + } + } + + if (advapi) + FreeLibrary(advapi); + + /* timer data */ + readtimer(); + + /* memory usage statistics */ + GlobalMemoryStatus(&m); + RAND_add(&m, sizeof(m), 1); + + /* process ID */ + w = GetCurrentProcessId(); + RAND_add(&w, sizeof(w), 1); + + if (user) + { + GETCURSORINFO cursor; + GETFOREGROUNDWINDOW win; + GETQUEUESTATUS queue; + + win = (GETFOREGROUNDWINDOW) GetProcAddress(user, "GetForegroundWindow"); + cursor = (GETCURSORINFO) GetProcAddress(user, "GetCursorInfo"); + queue = (GETQUEUESTATUS) GetProcAddress(user, "GetQueueStatus"); + + if (win) + { + /* window handle */ + h = win(); + RAND_add(&h, sizeof(h), 0); + } + if (cursor) + { + /* unfortunately, its not safe to call GetCursorInfo() + * on NT4 even though it exists in SP3 (or SP6) and + * higher. + */ + if ( osverinfo.dwPlatformId == VER_PLATFORM_WIN32_NT && + osverinfo.dwMajorVersion < 5) + cursor = 0; + } + if (cursor) + { + /* cursor position */ + /* assume 2 bytes of entropy */ + CURSORINFO ci; + ci.cbSize = sizeof(CURSORINFO); + if (cursor(&ci)) + RAND_add(&ci, ci.cbSize, 2); + } + + if (queue) + { + /* message queue status */ + /* assume 1 byte of entropy */ + w = queue(QS_ALLEVENTS); + RAND_add(&w, sizeof(w), 1); + } + + FreeLibrary(user); + } + + /* Toolhelp32 snapshot: enumerate processes, threads, modules and heap + * http://msdn.microsoft.com/library/psdk/winbase/toolhelp_5pfd.htm + * (Win 9x and 2000 only, not available on NT) + * + * This seeding method was proposed in Peter Gutmann, Software + * Generation of Practically Strong Random Numbers, + * http://www.usenix.org/publications/library/proceedings/sec98/gutmann.html + * revised version at http://www.cryptoengines.com/~peter/06_random.pdf + * (The assignment of entropy estimates below is arbitrary, but based + * on Peter's analysis the full poll appears to be safe. Additional + * interactive seeding is encouraged.) + */ + + if (kernel) + { + CREATETOOLHELP32SNAPSHOT snap; + HANDLE handle; + + HEAP32FIRST heap_first; + HEAP32NEXT heap_next; + HEAP32LIST heaplist_first, heaplist_next; + PROCESS32 process_first, process_next; + THREAD32 thread_first, thread_next; + MODULE32 module_first, module_next; + + HEAPLIST32 hlist; + HEAPENTRY32 hentry; + PROCESSENTRY32 p; + THREADENTRY32 t; + MODULEENTRY32 m; + + snap = (CREATETOOLHELP32SNAPSHOT) + GetProcAddress(kernel, "CreateToolhelp32Snapshot"); + heap_first = (HEAP32FIRST) GetProcAddress(kernel, "Heap32First"); + heap_next = (HEAP32NEXT) GetProcAddress(kernel, "Heap32Next"); + heaplist_first = (HEAP32LIST) GetProcAddress(kernel, "Heap32ListFirst"); + heaplist_next = (HEAP32LIST) GetProcAddress(kernel, "Heap32ListNext"); + process_first = (PROCESS32) GetProcAddress(kernel, "Process32First"); + process_next = (PROCESS32) GetProcAddress(kernel, "Process32Next"); + thread_first = (THREAD32) GetProcAddress(kernel, "Thread32First"); + thread_next = (THREAD32) GetProcAddress(kernel, "Thread32Next"); + module_first = (MODULE32) GetProcAddress(kernel, "Module32First"); + module_next = (MODULE32) GetProcAddress(kernel, "Module32Next"); + + if (snap && heap_first && heap_next && heaplist_first && + heaplist_next && process_first && process_next && + thread_first && thread_next && module_first && + module_next && (handle = snap(TH32CS_SNAPALL,0)) + != NULL) + { + /* heap list and heap walking */ + /* HEAPLIST32 contains 3 fields that will change with + * each entry. Consider each field a source of 1 byte + * of entropy. + * HEAPENTRY32 contains 5 fields that will change with + * each entry. Consider each field a source of 1 byte + * of entropy. + */ + hlist.dwSize = sizeof(HEAPLIST32); + if (heaplist_first(handle, &hlist)) + do + { + RAND_add(&hlist, hlist.dwSize, 3); + hentry.dwSize = sizeof(HEAPENTRY32); + if (heap_first(&hentry, + hlist.th32ProcessID, + hlist.th32HeapID)) + { + int entrycnt = 50; + do + RAND_add(&hentry, + hentry.dwSize, 5); + while (heap_next(&hentry) + && --entrycnt > 0); + } + } while (heaplist_next(handle, + &hlist)); + + /* process walking */ + /* PROCESSENTRY32 contains 9 fields that will change + * with each entry. Consider each field a source of + * 1 byte of entropy. + */ + p.dwSize = sizeof(PROCESSENTRY32); + if (process_first(handle, &p)) + do + RAND_add(&p, p.dwSize, 9); + while (process_next(handle, &p)); + + /* thread walking */ + /* THREADENTRY32 contains 6 fields that will change + * with each entry. Consider each field a source of + * 1 byte of entropy. + */ + t.dwSize = sizeof(THREADENTRY32); + if (thread_first(handle, &t)) + do + RAND_add(&t, t.dwSize, 6); + while (thread_next(handle, &t)); + + /* module walking */ + /* MODULEENTRY32 contains 9 fields that will change + * with each entry. Consider each field a source of + * 1 byte of entropy. + */ + m.dwSize = sizeof(MODULEENTRY32); + if (module_first(handle, &m)) + do + RAND_add(&m, m.dwSize, 9); + while (module_next(handle, &m)); + + CloseHandle(handle); + } + + FreeLibrary(kernel); + } + +#ifdef DEBUG + printf("Exiting RAND_poll\n"); +#endif + + return(1); +} + +int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam) + { + double add_entropy=0; + + switch (iMsg) + { + case WM_KEYDOWN: + { + static WPARAM key; + if (key != wParam) + add_entropy = 0.05; + key = wParam; + } + break; + case WM_MOUSEMOVE: + { + static int lastx,lasty,lastdx,lastdy; + int x,y,dx,dy; + + x=LOWORD(lParam); + y=HIWORD(lParam); + dx=lastx-x; + dy=lasty-y; + if (dx != 0 && dy != 0 && dx-lastdx != 0 && dy-lastdy != 0) + add_entropy=.2; + lastx=x, lasty=y; + lastdx=dx, lastdy=dy; + } + break; + } + + readtimer(); + RAND_add(&iMsg, sizeof(iMsg), add_entropy); + RAND_add(&wParam, sizeof(wParam), 0); + RAND_add(&lParam, sizeof(lParam), 0); + + return (RAND_status()); + } + + +void RAND_screen(void) /* function available for backward compatibility */ +{ + RAND_poll(); + readscreen(); +} + + +/* feed timing information to the PRNG */ +static void readtimer(void) +{ + DWORD w; + LARGE_INTEGER l; + static int have_perfc = 1; +#ifndef __GNUC__ + static int have_tsc = 1; + DWORD cyclecount; + + if (have_tsc) { + __try { + __asm { + rdtsc + mov cyclecount, eax + } + RAND_add(&cyclecount, sizeof(cyclecount), 1); + } __except(EXCEPTION_EXECUTE_HANDLER) { + have_tsc = 0; + } + } +#else +# define have_tsc 0 +#endif + + if (have_perfc) { + if (QueryPerformanceCounter(&l) == 0) + have_perfc = 0; + else + RAND_add(&l, sizeof(l), 0); + } + + if (!have_tsc && !have_perfc) { + w = GetTickCount(); + RAND_add(&w, sizeof(w), 0); + } +} + +/* feed screen contents to PRNG */ +/***************************************************************************** + * + * Created 960901 by Gertjan van Oosten, gertjan@West.NL, West Consulting B.V. + * + * Code adapted from + * ; + * the original copyright message is: + * + * (C) Copyright Microsoft Corp. 1993. All rights reserved. + * + * You have a royalty-free right to use, modify, reproduce and + * distribute the Sample Files (and/or any modified version) in + * any way you find useful, provided that you agree that + * Microsoft has no warranty obligations or liability for any + * Sample Application Files which are modified. + */ + +static void readscreen(void) +{ + HDC hScrDC; /* screen DC */ + HDC hMemDC; /* memory DC */ + HBITMAP hBitmap; /* handle for our bitmap */ + HBITMAP hOldBitmap; /* handle for previous bitmap */ + BITMAP bm; /* bitmap properties */ + unsigned int size; /* size of bitmap */ + char *bmbits; /* contents of bitmap */ + int w; /* screen width */ + int h; /* screen height */ + int y; /* y-coordinate of screen lines to grab */ + int n = 16; /* number of screen lines to grab at a time */ + + /* Create a screen DC and a memory DC compatible to screen DC */ + hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL); + hMemDC = CreateCompatibleDC(hScrDC); + + /* Get screen resolution */ + w = GetDeviceCaps(hScrDC, HORZRES); + h = GetDeviceCaps(hScrDC, VERTRES); + + /* Create a bitmap compatible with the screen DC */ + hBitmap = CreateCompatibleBitmap(hScrDC, w, n); + + /* Select new bitmap into memory DC */ + hOldBitmap = SelectObject(hMemDC, hBitmap); + + /* Get bitmap properties */ + GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm); + size = (unsigned int)bm.bmWidthBytes * bm.bmHeight * bm.bmPlanes; + + bmbits = OPENSSL_malloc(size); + if (bmbits) { + /* Now go through the whole screen, repeatedly grabbing n lines */ + for (y = 0; y < h-n; y += n) + { + unsigned char md[MD_DIGEST_LENGTH]; + + /* Bitblt screen DC to memory DC */ + BitBlt(hMemDC, 0, 0, w, n, hScrDC, 0, y, SRCCOPY); + + /* Copy bitmap bits from memory DC to bmbits */ + GetBitmapBits(hBitmap, size, bmbits); + + /* Get the hash of the bitmap */ + MD(bmbits,size,md); + + /* Seed the random generator with the hash value */ + RAND_add(md, MD_DIGEST_LENGTH, 0); + } + + OPENSSL_free(bmbits); + } + + /* Select old bitmap back into memory DC */ + hBitmap = SelectObject(hMemDC, hOldBitmap); + + /* Clean up */ + DeleteObject(hBitmap); + DeleteDC(hMemDC); + DeleteDC(hScrDC); +} + +#else /* Unix version */ + +#include + +int RAND_poll(void) +{ + unsigned long l; + pid_t curr_pid = getpid(); +#ifdef DEVRANDOM + FILE *fh; +#endif + +#ifdef DEVRANDOM + /* Use a random entropy pool device. Linux, FreeBSD and OpenBSD + * have this. Use /dev/urandom if you can as /dev/random may block + * if it runs out of random entries. */ + + if ((fh = fopen(DEVRANDOM, "r")) != NULL) + { + unsigned char tmpbuf[ENTROPY_NEEDED]; + int n; + + setvbuf(fh, NULL, _IONBF, 0); + n=fread((unsigned char *)tmpbuf,1,ENTROPY_NEEDED,fh); + fclose(fh); + RAND_add(tmpbuf,sizeof tmpbuf,n); + memset(tmpbuf,0,n); + } +#endif + + /* put in some default random data, we need more than just this */ + l=curr_pid; + RAND_add(&l,sizeof(l),0); + l=getuid(); + RAND_add(&l,sizeof(l),0); + + l=time(NULL); + RAND_add(&l,sizeof(l),0); + +#ifdef DEVRANDOM + return 1; +#endif + return 0; +} + +#endif diff --git a/lib/libssl/src/crypto/symhacks.h b/lib/libssl/src/crypto/symhacks.h new file mode 100644 index 00000000000..358ad355bb4 --- /dev/null +++ b/lib/libssl/src/crypto/symhacks.h @@ -0,0 +1,154 @@ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_SYMHACKS_H +#define HEADER_SYMHACKS_H + +/* Hacks to solve the problem with linkers incapable of handling very long + symbol names. In the case of VMS, the limit is 31 characters on VMS for + VAX. */ +#ifdef VMS + +/* Hack a long name in crypto/asn1/a_mbstr.c */ +#undef ASN1_STRING_set_default_mask_asc +#define ASN1_STRING_set_default_mask_asc ASN1_STRING_set_def_mask_asc + +#if 0 /* No longer needed, since safestack macro magic does the job */ +/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO) */ +#undef i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO +#define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO i2d_ASN1_SET_OF_PKCS7_SIGINF +#undef d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO +#define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO d2i_ASN1_SET_OF_PKCS7_SIGINF +#endif + +#if 0 /* No longer needed, since safestack macro magic does the job */ +/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO) */ +#undef i2d_ASN1_SET_OF_PKCS7_RECIP_INFO +#define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO i2d_ASN1_SET_OF_PKCS7_RECINF +#undef d2i_ASN1_SET_OF_PKCS7_RECIP_INFO +#define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO d2i_ASN1_SET_OF_PKCS7_RECINF +#endif + +#if 0 /* No longer needed, since safestack macro magic does the job */ +/* Hack the names created with DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION) */ +#undef i2d_ASN1_SET_OF_ACCESS_DESCRIPTION +#define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION i2d_ASN1_SET_OF_ACC_DESC +#undef d2i_ASN1_SET_OF_ACCESS_DESCRIPTION +#define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION d2i_ASN1_SET_OF_ACC_DESC +#endif + +/* Hack the names created with DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE) */ +#undef PEM_read_NETSCAPE_CERT_SEQUENCE +#define PEM_read_NETSCAPE_CERT_SEQUENCE PEM_read_NS_CERT_SEQ +#undef PEM_write_NETSCAPE_CERT_SEQUENCE +#define PEM_write_NETSCAPE_CERT_SEQUENCE PEM_write_NS_CERT_SEQ +#undef PEM_read_bio_NETSCAPE_CERT_SEQUENCE +#define PEM_read_bio_NETSCAPE_CERT_SEQUENCE PEM_read_bio_NS_CERT_SEQ +#undef PEM_write_bio_NETSCAPE_CERT_SEQUENCE +#define PEM_write_bio_NETSCAPE_CERT_SEQUENCE PEM_write_bio_NS_CERT_SEQ +#undef PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE +#define PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE PEM_write_cb_bio_NS_CERT_SEQ + +/* Hack the names created with DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO) */ +#undef PEM_read_PKCS8_PRIV_KEY_INFO +#define PEM_read_PKCS8_PRIV_KEY_INFO PEM_read_P8_PRIV_KEY_INFO +#undef PEM_write_PKCS8_PRIV_KEY_INFO +#define PEM_write_PKCS8_PRIV_KEY_INFO PEM_write_P8_PRIV_KEY_INFO +#undef PEM_read_bio_PKCS8_PRIV_KEY_INFO +#define PEM_read_bio_PKCS8_PRIV_KEY_INFO PEM_read_bio_P8_PRIV_KEY_INFO +#undef PEM_write_bio_PKCS8_PRIV_KEY_INFO +#define PEM_write_bio_PKCS8_PRIV_KEY_INFO PEM_write_bio_P8_PRIV_KEY_INFO +#undef PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO +#define PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO PEM_wrt_cb_bio_P8_PRIV_KEY_INFO + +/* Hack other PEM names */ +#undef PEM_write_bio_PKCS8PrivateKey_nid +#define PEM_write_bio_PKCS8PrivateKey_nid PEM_write_bio_PKCS8PrivKey_nid + +/* Hack some long X509 names */ +#undef X509_REVOKED_get_ext_by_critical +#define X509_REVOKED_get_ext_by_critical X509_REVOKED_get_ext_by_critic + +/* Hack some long CRYPTO names */ +#define CRYPTO_set_dynlock_destroy_callback CRYPTO_set_dynlock_destroy_cb +#define CRYPTO_set_dynlock_create_callback CRYPTO_set_dynlock_create_cb +#define CRYPTO_set_dynlock_lock_callback CRYPTO_set_dynlock_lock_cb +#define CRYPTO_get_dynlock_lock_callback CRYPTO_get_dynlock_lock_cb +#define CRYPTO_get_dynlock_destroy_callback CRYPTO_get_dynlock_destroy_cb +#define CRYPTO_get_dynlock_create_callback CRYPTO_get_dynlock_create_cb + +/* Hack some long SSL names */ +#define SSL_CTX_set_default_verify_paths SSL_CTX_set_def_verify_paths +#define SSL_get_ex_data_X509_STORE_CTX_idx SSL_get_ex_d_X509_STORE_CTX_idx +#define SSL_add_file_cert_subjects_to_stack SSL_add_file_cert_subjs_to_stk +#define SSL_add_dir_cert_subjects_to_stack SSL_add_dir_cert_subjs_to_stk +#define SSL_CTX_use_certificate_chain_file SSL_CTX_use_cert_chain_file +#define SSL_CTX_set_cert_verify_callback SSL_CTX_set_cert_verify_cb +#define SSL_CTX_set_default_passwd_cb_userdata SSL_CTX_set_def_passwd_cb_ud + +/* Hack some long ENGINE names */ +#define ENGINE_get_default_BN_mod_exp_crt ENGINE_get_def_BN_mod_exp_crt +#define ENGINE_set_default_BN_mod_exp_crt ENGINE_set_def_BN_mod_exp_crt + +#endif /* defined VMS */ + + +/* Case insensiteve linking causes problems.... */ +#if defined(WIN16) || defined(VMS) +#undef ERR_load_CRYPTO_strings +#define ERR_load_CRYPTO_strings ERR_load_CRYPTOlib_strings +#endif + + +#endif /* ! defined HEADER_VMS_IDHACKS_H */ diff --git a/lib/libssl/src/doc/apps/rsautl.pod b/lib/libssl/src/doc/apps/rsautl.pod new file mode 100644 index 00000000000..7a334bc8d6a --- /dev/null +++ b/lib/libssl/src/doc/apps/rsautl.pod @@ -0,0 +1,183 @@ +=pod + +=head1 NAME + +rsautl - RSA utility + +=head1 SYNOPSIS + +B B +[B<-in file>] +[B<-out file>] +[B<-inkey file>] +[B<-pubin>] +[B<-certin>] +[B<-sign>] +[B<-verify>] +[B<-encrypt>] +[B<-decrypt>] +[B<-pkcs>] +[B<-ssl>] +[B<-raw>] +[B<-hexdump>] +[B<-asn1parse>] + +=head1 DESCRIPTION + +The B command can be used to sign, verify, encrypt and decrypt +data using the RSA algorithm. + +=head1 COMMAND OPTIONS + +=over 4 + +=item B<-in filename> + +This specifies the input filename to read data from or standard input +if this option is not specified. + +=item B<-out filename> + +specifies the output filename to write to or standard output by +default. + +=item B<-inkey file> + +the input key file, by default it should be an RSA private key. + +=item B<-pubin> + +the input file is an RSA public key. + +=item B<-certin> + +the input is a certificate containing an RSA public key. + +=item B<-sign> + +sign the input data and output the signed result. This requires +and RSA private key. + +=item B<-verify> + +verify the input data and output the recovered data. + +=item B<-encrypt> + +encrypt the input data using an RSA public key. + +=item B<-decrypt> + +decrypt the input data using an RSA private key. + +=item B<-pkcs, -oaep, -ssl, -raw> + +the padding to use: PKCS#1 v1.5 (the default), PKCS#1 OAEP, +special padding used in SSL v2 backwards compatible handshakes, +or no padding, respectively. +For signatures, only B<-pkcs> and B<-raw> can be used. + +=item B<-hexdump> + +hex dump the output data. + +=item B<-asn1parse> + +asn1parse the output data, this is useful when combined with the +B<-verify> option. + +=back + +=head1 NOTES + +B because it uses the RSA algorithm directly can only be +used to sign or verify small pieces of data. + +=head1 EXAMPLES + +Sign some data using a private key: + + openssl rsautl -sign -in file -inkey key.pem -out sig + +Recover the signed data + + openssl rsautl -sign -in sig -inkey key.pem + +Examine the raw signed data: + + openssl rsautl -sign -in file -inkey key.pem -raw -hexdump + + 0000 - 00 01 ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ + 0010 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ + 0020 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ + 0030 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ + 0040 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ + 0050 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ + 0060 - ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................ + 0070 - ff ff ff ff 00 68 65 6c-6c 6f 20 77 6f 72 6c 64 .....hello world + +The PKCS#1 block formatting is evident from this. If this was done using +encrypt and decrypt the block would have been of type 2 (the second byte) +and random padding data visible instead of the 0xff bytes. + +It is possible to analyse the signature of certificates using this +utility in conjunction with B. Consider the self signed +example in certs/pca-cert.pem . Running B as follows yields: + + openssl asn1parse -in pca-cert.pem + + 0:d=0 hl=4 l= 742 cons: SEQUENCE + 4:d=1 hl=4 l= 591 cons: SEQUENCE + 8:d=2 hl=2 l= 3 cons: cont [ 0 ] + 10:d=3 hl=2 l= 1 prim: INTEGER :02 + 13:d=2 hl=2 l= 1 prim: INTEGER :00 + 16:d=2 hl=2 l= 13 cons: SEQUENCE + 18:d=3 hl=2 l= 9 prim: OBJECT :md5WithRSAEncryption + 29:d=3 hl=2 l= 0 prim: NULL + 31:d=2 hl=2 l= 92 cons: SEQUENCE + 33:d=3 hl=2 l= 11 cons: SET + 35:d=4 hl=2 l= 9 cons: SEQUENCE + 37:d=5 hl=2 l= 3 prim: OBJECT :countryName + 42:d=5 hl=2 l= 2 prim: PRINTABLESTRING :AU + .... + 599:d=1 hl=2 l= 13 cons: SEQUENCE + 601:d=2 hl=2 l= 9 prim: OBJECT :md5WithRSAEncryption + 612:d=2 hl=2 l= 0 prim: NULL + 614:d=1 hl=3 l= 129 prim: BIT STRING + + +The final BIT STRING contains the actual signature. It can be extracted with: + + openssl asn1parse -in pca-cert.pem -out sig -noout -strparse 614 + +The certificate public key can be extracted with: + + openssl x509 -in test/testx509.pem -pubout -noout >pubkey.pem + +The signature can be analysed with: + + openssl rsautl -in sig -verify -asn1parse -inkey pubkey.pem -pubin + + 0:d=0 hl=2 l= 32 cons: SEQUENCE + 2:d=1 hl=2 l= 12 cons: SEQUENCE + 4:d=2 hl=2 l= 8 prim: OBJECT :md5 + 14:d=2 hl=2 l= 0 prim: NULL + 16:d=1 hl=2 l= 16 prim: OCTET STRING + 0000 - f3 46 9e aa 1a 4a 73 c9-37 ea 93 00 48 25 08 b5 .F...Js.7...H%.. + +This is the parsed version of an ASN1 DigestInfo structure. It can be seen that +the digest used was md5. The actual part of the certificate that was signed can +be extracted with: + + openssl asn1parse -in pca-cert.pem -out tbs -noout -strparse 4 + +and its digest computed with: + + openssl md5 -c tbs + MD5(tbs)= f3:46:9e:aa:1a:4a:73:c9:37:ea:93:00:48:25:08:b5 + +which it can be seen agrees with the recovered value above. + +=head1 SEE ALSO + +L, L, L diff --git a/lib/libssl/src/doc/crypto/BIO_ctrl.pod b/lib/libssl/src/doc/crypto/BIO_ctrl.pod new file mode 100644 index 00000000000..722e8b8f46c --- /dev/null +++ b/lib/libssl/src/doc/crypto/BIO_ctrl.pod @@ -0,0 +1,128 @@ +=pod + +=head1 NAME + +BIO_ctrl, BIO_callback_ctrl, BIO_ptr_ctrl, BIO_int_ctrl, BIO_reset, +BIO_seek, BIO_tell, BIO_flush, BIO_eof, BIO_set_close, BIO_get_close, +BIO_pending, BIO_wpending, BIO_ctrl_pending, BIO_ctrl_wpending, +BIO_get_info_callback, BIO_set_info_callback - BIO control operations + +=head1 SYNOPSIS + + #include + + long BIO_ctrl(BIO *bp,int cmd,long larg,void *parg); + long BIO_callback_ctrl(BIO *b, int cmd, void (*fp)(struct bio_st *, int, const char *, int, long, long)); + char * BIO_ptr_ctrl(BIO *bp,int cmd,long larg); + long BIO_int_ctrl(BIO *bp,int cmd,long larg,int iarg); + + int BIO_reset(BIO *b); + int BIO_seek(BIO *b, int ofs); + int BIO_tell(BIO *b); + int BIO_flush(BIO *b); + int BIO_eof(BIO *b); + int BIO_set_close(BIO *b,long flag); + int BIO_get_close(BIO *b); + int BIO_pending(BIO *b); + int BIO_wpending(BIO *b); + size_t BIO_ctrl_pending(BIO *b); + size_t BIO_ctrl_wpending(BIO *b); + + int BIO_get_info_callback(BIO *b,bio_info_cb **cbp); + int BIO_set_info_callback(BIO *b,bio_info_cb *cb); + + typedef void bio_info_cb(BIO *b, int oper, const char *ptr, int arg1, long arg2, long arg3); + +=head1 DESCRIPTION + +BIO_ctrl(), BIO_callback_ctrl(), BIO_ptr_ctrl() and BIO_int_ctrl() +are BIO "control" operations taking arguments of various types. +These functions are not normally called directly, various macros +are used instead. The standard macros are described below, macros +specific to a particular type of BIO are described in the specific +BIOs manual page as well as any special features of the standard +calls. + +BIO_reset() typically resets a BIO to some initial state, in the case +of file related BIOs for example it rewinds the file pointer to the +start of the file. + +BIO_seek() resets a file related BIO's (that is file descriptor and +FILE BIOs) file position pointer to B bytes from start of file. + +BIO_tell() returns the current file position of a file related BIO. + +BIO_flush() normally writes out any internally buffered data, in some +cases it is used to signal EOF and that no more data will be written. + +BIO_eof() returns 1 if the BIO has read EOF, the precise meaning of +"EOF" varies according to the BIO type. + +BIO_set_close() sets the BIO B close flag to B. B can +take the value BIO_CLOSE or BIO_NOCLOSE. Typically BIO_CLOSE is used +in a source/sink BIO to indicate that the underlying I/O stream should +be closed when the BIO is freed. + +BIO_get_close() returns the BIOs close flag. + +BIO_pending(), BIO_ctrl_pending(), BIO_wpending() and BIO_ctrl_wpending() +return the number of pending characters in the BIOs read and write buffers. +Not all BIOs support these calls. BIO_ctrl_pending() and BIO_ctrl_wpending() +return a size_t type and are functions, BIO_pending() and BIO_wpending() are +macros which call BIO_ctrl(). + +=head1 RETURN VALUES + +BIO_reset() normally returns 1 for success and 0 or -1 for failure. File +BIOs are an exception, they return 0 for success and -1 for failure. + +BIO_seek() and BIO_tell() both return the current file position on success +and -1 for failure, except file BIOs which for BIO_seek() always return 0 +for success and -1 for failure. + +BIO_flush() returns 1 for success and 0 or -1 for failure. + +BIO_eof() returns 1 if EOF has been reached 0 otherwise. + +BIO_set_close() always returns 1. + +BIO_get_close() returns the close flag value: BIO_CLOSE or BIO_NOCLOSE. + +BIO_pending(), BIO_ctrl_pending(), BIO_wpending() and BIO_ctrl_wpending() +return the amount of pending data. + +=head1 NOTES + +BIO_flush(), because it can write data may return 0 or -1 indicating +that the call should be retried later in a similar manner to BIO_write(). +The BIO_should_retry() call should be used and appropriate action taken +is the call fails. + +The return values of BIO_pending() and BIO_wpending() may not reliably +determine the amount of pending data in all cases. For example in the +case of a file BIO some data may be available in the FILE structures +internal buffers but it is not possible to determine this in a +portably way. For other types of BIO they may not be supported. + +Filter BIOs if they do not internally handle a particular BIO_ctrl() +operation usually pass the operation to the next BIO in the chain. +This often means there is no need to locate the required BIO for +a particular operation, it can be called on a chain and it will +be automatically passed to the relevant BIO. However this can cause +unexpected results: for example no current filter BIOs implement +BIO_seek(), but this may still succeed if the chain ends in a FILE +or file descriptor BIO. + +Source/sink BIOs return an 0 if they do not recognize the BIO_ctrl() +operation. + +=head1 BUGS + +Some of the return values are ambiguous and care should be taken. In +particular a return value of 0 can be returned if an operation is not +supported, if an error occurred, if EOF has not been reached and in +the case of BIO_seek() on a file BIO for a successful operation. + +=head1 SEE ALSO + +TBA diff --git a/lib/libssl/src/doc/crypto/BIO_f_base64.pod b/lib/libssl/src/doc/crypto/BIO_f_base64.pod new file mode 100644 index 00000000000..fdb603b38e3 --- /dev/null +++ b/lib/libssl/src/doc/crypto/BIO_f_base64.pod @@ -0,0 +1,82 @@ +=pod + +=head1 NAME + +BIO_f_base64 - base64 BIO filter + +=head1 SYNOPSIS + + #include + #include + + BIO_METHOD * BIO_f_base64(void); + +=head1 DESCRIPTION + +BIO_f_base64() returns the base64 BIO method. This is a filter +BIO that base64 encodes any data written through it and decodes +any data read through it. + +Base64 BIOs do not support BIO_gets() or BIO_puts(). + +BIO_flush() on a base64 BIO that is being written through is +used to signal that no more data is to be encoded: this is used +to flush the final block through the BIO. + +The flag BIO_FLAGS_BASE64_NO_NL can be set with BIO_set_flags() +to encode the data all on one line or expect the data to be all +on one line. + +=head1 NOTES + +Because of the format of base64 encoding the end of the encoded +block cannot always be reliably determined. + +=head1 RETURN VALUES + +BIO_f_base64() returns the base64 BIO method. + +=head1 EXAMPLES + +Base64 encode the string "Hello World\n" and write the result +to standard output: + + BIO *bio, *b64; + char message[] = "Hello World \n"; + + b64 = BIO_new(BIO_f_base64()); + bio = BIO_new_fp(stdout, BIO_NOCLOSE); + bio = BIO_push(b64, bio); + BIO_write(bio, message, strlen(message)); + BIO_flush(bio); + + BIO_free_all(bio); + +Read Base64 encoded data from standard input and write the decoded +data to standard output: + + BIO *bio, *b64, bio_out; + char inbuf[512]; + int inlen; + char message[] = "Hello World \n"; + + b64 = BIO_new(BIO_f_base64()); + bio = BIO_new_fp(stdin, BIO_NOCLOSE); + bio_out = BIO_new_fp(stdout, BIO_NOCLOSE); + bio = BIO_push(b64, bio); + while((inlen = BIO_read(bio, inbuf, strlen(message))) > 0) + BIO_write(bio_out, inbuf, inlen); + + BIO_free_all(bio); + +=head1 BUGS + +The ambiguity of EOF in base64 encoded data can cause additional +data following the base64 encoded block to be misinterpreted. + +There should be some way of specifying a test that the BIO can perform +to reliably determine EOF (for example a MIME boundary). + +=head1 SEE ALSO + +TBA diff --git a/lib/libssl/src/doc/crypto/BIO_f_buffer.pod b/lib/libssl/src/doc/crypto/BIO_f_buffer.pod new file mode 100644 index 00000000000..c9093c6a576 --- /dev/null +++ b/lib/libssl/src/doc/crypto/BIO_f_buffer.pod @@ -0,0 +1,69 @@ +=pod + +=head1 NAME + +BIO_f_buffer - buffering BIO + +=head1 SYNOPSIS + + #include + + BIO_METHOD * BIO_f_buffer(void); + + #define BIO_get_buffer_num_lines(b) BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL) + #define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0) + #define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1) + #define BIO_set_buffer_size(b,size) BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL) + #define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf) + +=head1 DESCRIPTION + +BIO_f_buffer() returns the buffering BIO method. + +Data written to a buffering BIO is buffered and periodically written +to the next BIO in the chain. Data read from a buffering BIO comes from +an internal buffer which is filled from the next BIO in the chain. +Both BIO_gets() and BIO_puts() are supported. + +Calling BIO_reset() on a buffering BIO clears any buffered data. + +BIO_get_buffer_num_lines() returns the number of lines currently buffered. + +BIO_set_read_buffer_size(), BIO_set_write_buffer_size() and BIO_set_buffer_size() +set the read, write or both read and write buffer sizes to B. The initial +buffer size is DEFAULT_BUFFER_SIZE, currently 1024. Any attempt to reduce the +buffer size below DEFAULT_BUFFER_SIZE is ignored. Any buffered data is cleared +when the buffer is resized. + +BIO_set_buffer_read_data() clears the read buffer and fills it with B +bytes of B. If B is larger than the current buffer size the buffer +is expanded. + +=head1 NOTES + +Buffering BIOs implement BIO_gets() by using BIO_read() operations on the +next BIO in the chain. By prepending a buffering BIO to a chain it is therefore +possible to provide BIO_gets() functionality if the following BIOs do not +support it (for example SSL BIOs). + +Data is only written to the next BIO in the chain when the write buffer fills +or when BIO_flush() is called. It is therefore important to call BIO_flush() +whenever any pending data should be written such as when removing a buffering +BIO using BIO_pop(). BIO_flush() may need to be retried if the ultimate +source/sink BIO is non blocking. + +=head1 RETURN VALUES + +BIO_f_buffer() returns the buffering BIO method. + +BIO_get_buffer_num_lines() returns the number of lines buffered (may be 0). + +BIO_set_read_buffer_size(), BIO_set_write_buffer_size() and BIO_set_buffer_size() +return 1 if the buffer was successfully resized or 0 for failure. + +BIO_set_buffer_read_data() returns 1 if the data was set correctly or 0 if +there was an error. + +=head1 SEE ALSO + +TBA diff --git a/lib/libssl/src/doc/crypto/BIO_f_cipher.pod b/lib/libssl/src/doc/crypto/BIO_f_cipher.pod new file mode 100644 index 00000000000..4182f2c3090 --- /dev/null +++ b/lib/libssl/src/doc/crypto/BIO_f_cipher.pod @@ -0,0 +1,76 @@ +=pod + +=head1 NAME + +BIO_f_cipher, BIO_set_cipher, BIO_get_cipher_status, BIO_get_cipher_ctx - cipher BIO filter + +=head1 SYNOPSIS + + #include + #include + + BIO_METHOD * BIO_f_cipher(void); + void BIO_set_cipher(BIO *b,const EVP_CIPHER *cipher, + unsigned char *key, unsigned char *iv, int enc); + int BIO_get_cipher_status(BIO *b) + int BIO_get_cipher_ctx(BIO *b, EVP_CIPHER_CTX **pctx) + +=head1 DESCRIPTION + +BIO_f_cipher() returns the cipher BIO method. This is a filter +BIO that encrypts any data written through it, and decrypts any data +read from it. It is a BIO wrapper for the cipher routines +EVP_CipherInit(), EVP_CipherUpdate() and EVP_CipherFinal(). + +Cipher BIOs do not support BIO_gets() or BIO_puts(). + +BIO_flush() on an encryption BIO that is being written through is +used to signal that no more data is to be encrypted: this is used +to flush and possibly pad the final block through the BIO. + +BIO_set_cipher() sets the cipher of BIO to B using key B +and IV B. B should be set to 1 for encryption and zero for +decryption. + +When reading from an encryption BIO the final block is automatically +decrypted and checked when EOF is detected. BIO_get_cipher_status() +is a BIO_ctrl() macro which can be called to determine whether the +decryption operation was successful. + +BIO_get_cipher_ctx() is a BIO_ctrl() macro which retrieves the internal +BIO cipher context. The retrieved context can be used in conjunction +with the standard cipher routines to set it up. This is useful when +BIO_set_cipher() is not flexible enough for the applications needs. + +=head1 NOTES + +When encrypting BIO_flush() B be called to flush the final block +through the BIO. If it is not then the final block will fail a subsequent +decrypt. + +When decrypting an error on the final block is signalled by a zero +return value from the read operation. A successful decrypt followed +by EOF will also return zero for the final read. BIO_get_cipher_status() +should be called to determine if the decrypt was successful. + +As always, if BIO_gets() or BIO_puts() support is needed then it can +be achieved by preceding the cipher BIO with a buffering BIO. + +=head1 RETURN VALUES + +BIO_f_cipher() returns the cipher BIO method. + +BIO_set_cipher() does not return a value. + +BIO_get_cipher_status() returns 1 for a successful decrypt and 0 +for failure. + +BIO_get_cipher_ctx() currently always returns 1. + +=head1 EXAMPLES + +TBA + +=head1 SEE ALSO + +TBA diff --git a/lib/libssl/src/doc/crypto/BIO_f_md.pod b/lib/libssl/src/doc/crypto/BIO_f_md.pod new file mode 100644 index 00000000000..c32504dfb18 --- /dev/null +++ b/lib/libssl/src/doc/crypto/BIO_f_md.pod @@ -0,0 +1,138 @@ +=pod + +=head1 NAME + +BIO_f_md, BIO_set_md, BIO_get_md, BIO_get_md_ctx - message digest BIO filter + +=head1 SYNOPSIS + + #include + #include + + BIO_METHOD * BIO_f_md(void); + int BIO_set_md(BIO *b,EVP_MD *md); + int BIO_get_md(BIO *b,EVP_MD **mdp); + int BIO_get_md_ctx(BIO *b,EVP_MD_CTX **mdcp); + +=head1 DESCRIPTION + +BIO_f_md() returns the message digest BIO method. This is a filter +BIO that digests any data passed through it, it is a BIO wrapper +for the digest routines EVP_DigestInit(), EVP_DigestUpdate() +and EVP_DigestFinal(). + +Any data written or read through a digest BIO using BIO_read() and +BIO_write() is digested. + +BIO_gets(), if its B parameter is large enough finishes the +digest calculation and returns the digest value. BIO_puts() is +not supported. + +BIO_reset() reinitializes a digest BIO. + +BIO_set_md() sets the message digest of BIO B to B: this +must be called to initialize a digest BIO before any data is +passed through it. It is a BIO_ctrl() macro. + +BIO_get_md() places the a pointer to the digest BIOs digest method +in B, it is a BIO_ctrl() macro. + +BIO_get_md_ctx() returns the digest BIOs context into B. + +=head1 NOTES + +The context returned by BIO_get_md_ctx() can be used in calls +to EVP_DigestFinal() and also the signature routines EVP_SignFinal() +and EVP_VerifyFinal(). + +The context returned by BIO_get_md_ctx() is an internal context +structure. Changes made to this context will affect the digest +BIO itself and the context pointer will become invalid when the digest +BIO is freed. + +After the digest has been retrieved from a digest BIO it must be +reinitialized by calling BIO_reset(), or BIO_set_md() before any more +data is passed through it. + +If an application needs to call BIO_gets() or BIO_puts() through +a chain containing digest BIOs then this can be done by prepending +a buffering BIO. + +=head1 RETURN VALUES + +BIO_f_md() returns the digest BIO method. + +BIO_set_md(), BIO_get_md() and BIO_md_ctx() return 1 for success and +0 for failure. + +=head1 EXAMPLES + +The following example creates a BIO chain containing an SHA1 and MD5 +digest BIO and passes the string "Hello World" through it. Error +checking has been omitted for clarity. + + BIO *bio, *mdtmp; + char message[] = "Hello World"; + bio = BIO_new(BIO_s_null()); + mdtmp = BIO_new(BIO_f_md()); + BIO_set_md(mdtmp, EVP_sha1()); + /* For BIO_push() we want to append the sink BIO and keep a note of + * the start of the chain. + */ + bio = BIO_push(mdtmp, bio); + mdtmp = BIO_new(BIO_f_md()); + BIO_set_md(mdtmp, EVP_md5()); + bio = BIO_push(mdtmp, bio); + /* Note: mdtmp can now be discarded */ + BIO_write(bio, message, strlen(message)); + +The next example digests data by reading through a chain instead: + + BIO *bio, *mdtmp; + char buf[1024]; + int rdlen; + bio = BIO_new_file(file, "rb"); + mdtmp = BIO_new(BIO_f_md()); + BIO_set_md(mdtmp, EVP_sha1()); + bio = BIO_push(mdtmp, bio); + mdtmp = BIO_new(BIO_f_md()); + BIO_set_md(mdtmp, EVP_md5()); + bio = BIO_push(mdtmp, bio); + do { + rdlen = BIO_read(bio, buf, sizeof(buf)); + /* Might want to do something with the data here */ + } while(rdlen > 0); + +This next example retrieves the message digests from a BIO chain and +outputs them. This could be used with the examples above. + + BIO *mdtmp; + unsigned char mdbuf[EVP_MAX_MD_SIZE]; + int mdlen; + int i; + mdtmp = bio; /* Assume bio has previously been set up */ + do { + EVP_MD *md; + mdtmp = BIO_find_type(mdtmp, BIO_TYPE_MD); + if(!mdtmp) break; + BIO_get_md(mdtmp, &md); + printf("%s digest", OBJ_nid2sn(EVP_MD_type(md))); + mdlen = BIO_gets(mdtmp, mdbuf, EVP_MAX_MD_SIZE); + for(i = 0; i < mdlen; i++) printf(":%02X", mdbuf[i]); + printf("\n"); + mdtmp = BIO_next(mdtmp); + } while(mdtmp); + + BIO_free_all(bio); + +=head1 BUGS + +The lack of support for BIO_puts() and the non standard behaviour of +BIO_gets() could be regarded as anomalous. It could be argued that BIO_gets() +and BIO_puts() should be passed to the next BIO in the chain and digest +the data passed through and that digests should be retrieved using a +separate BIO_ctrl() call. + +=head1 SEE ALSO + +TBA diff --git a/lib/libssl/src/doc/crypto/BIO_f_null.pod b/lib/libssl/src/doc/crypto/BIO_f_null.pod new file mode 100644 index 00000000000..b057c184083 --- /dev/null +++ b/lib/libssl/src/doc/crypto/BIO_f_null.pod @@ -0,0 +1,32 @@ +=pod + +=head1 NAME + +BIO_f_null - null filter + +=head1 SYNOPSIS + + #include + + BIO_METHOD * BIO_f_null(void); + +=head1 DESCRIPTION + +BIO_f_null() returns the null filter BIO method. This is a filter BIO +that does nothing. + +All requests to a null filter BIO are passed through to the next BIO in +the chain: this means that a BIO chain containing a null filter BIO +behaves just as though the BIO was not there. + +=head1 NOTES + +As may be apparent a null filter BIO is not particularly useful. + +=head1 RETURN VALUES + +BIO_f_null() returns the null filter BIO method. + +=head1 SEE ALSO + +TBA diff --git a/lib/libssl/src/doc/crypto/BIO_f_ssl.pod b/lib/libssl/src/doc/crypto/BIO_f_ssl.pod new file mode 100644 index 00000000000..a56ee2b92f2 --- /dev/null +++ b/lib/libssl/src/doc/crypto/BIO_f_ssl.pod @@ -0,0 +1,313 @@ +=pod + +=head1 NAME + +BIO_f_ssl, BIO_set_ssl, BIO_get_ssl, BIO_set_ssl_mode, BIO_set_ssl_renegotiate_bytes, +BIO_get_num_renegotiates, BIO_set_ssl_renegotiate_timeout, BIO_new_ssl, +BIO_new_ssl_connect, BIO_new_buffer_ssl_connect, BIO_ssl_copy_session_id, +BIO_ssl_shutdown - SSL BIO + +=head1 SYNOPSIS + + #include + #include + + BIO_METHOD *BIO_f_ssl(void); + + #define BIO_set_ssl(b,ssl,c) BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)ssl) + #define BIO_get_ssl(b,sslp) BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)sslp) + #define BIO_set_ssl_mode(b,client) BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL) + #define BIO_set_ssl_renegotiate_bytes(b,num) \ + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL); + #define BIO_set_ssl_renegotiate_timeout(b,seconds) \ + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL); + #define BIO_get_num_renegotiates(b) \ + BIO_ctrl(b,BIO_C_SET_SSL_NUM_RENEGOTIATES,0,NULL); + + BIO *BIO_new_ssl(SSL_CTX *ctx,int client); + BIO *BIO_new_ssl_connect(SSL_CTX *ctx); + BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx); + int BIO_ssl_copy_session_id(BIO *to,BIO *from); + void BIO_ssl_shutdown(BIO *bio); + + #define BIO_do_handshake(b) BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL) + +=head1 DESCRIPTION + +BIO_f_ssl() returns the SSL BIO method. This is a filter BIO which +is a wrapper round the OpenSSL SSL routines adding a BIO "flavour" to +SSL I/O. + +I/O performed on an SSL BIO communicates using the SSL protocol with +the SSLs read and write BIOs. If an SSL connection is not established +then an attempt is made to establish one on the first I/O call. + +If a BIO is appended to an SSL BIO using BIO_push() it is automatically +used as the SSL BIOs read and write BIOs. + +Calling BIO_reset() on an SSL BIO closes down any current SSL connection +by calling SSL_shutdown(). BIO_reset() is then sent to the next BIO in +the chain: this will typically disconnect the underlying transport. +The SSL BIO is then reset to the initial accept or connect state. + +If the close flag is set when an SSL BIO is freed then the internal +SSL structure is also freed using SSL_free(). + +BIO_set_ssl() sets the internal SSL pointer of BIO B to B using +the close flag B. + +BIO_get_ssl() retrieves the SSL pointer of BIO B, it can then be +manipulated using the standard SSL library functions. + +BIO_set_ssl_mode() sets the SSL BIO mode to B. If B +is 1 client mode is set. If B is 0 server mode is set. + +BIO_set_ssl_renegotiate_bytes() sets the renegotiate byte count +to B. When set after every B bytes of I/O (read and write) +the SSL session is automatically renegotiated. B must be at +least 512 bytes. + +BIO_set_ssl_renegotiate_timeout() sets the renegotiate timeout to +B. When the renegotiate timeout elapses the session is +automatically renegotiated. + +BIO_get_num_renegotiates() returns the total number of session +renegotiations due to I/O or timeout. + +BIO_new_ssl() allocates an SSL BIO using SSL_CTX B and using +client mode if B is non zero. + +BIO_new_ssl_connect() creates a new BIO chain consisting of an +SSL BIO (using B) followed by a connect BIO. + +BIO_new_buffer_ssl_connect() creates a new BIO chain consisting +of a buffering BIO, an SSL BIO (using B) and a connect +BIO. + +BIO_ssl_copy_session_id() copies an SSL session id between +BIO chains B and B. It does this by locating the +SSL BIOs in each chain and calling SSL_copy_session_id() on +the internal SSL pointer. + +BIO_ssl_shutdown() closes down an SSL connection on BIO +chain B. It does this by locating the SSL BIO in the +chain and calling SSL_shutdown() on its internal SSL +pointer. + +BIO_do_handshake() attempts to complete an SSL handshake on the +supplied BIO and establish the SSL connection. It returns 1 +if the connection was established successfully. A zero or negative +value is returned if the connection could not be established, the +call BIO_should_retry() should be used for non blocking connect BIOs +to determine if the call should be retried. If an SSL connection has +already been established this call has no effect. + +=head1 NOTES + +SSL BIOs are exceptional in that if the underlying transport +is non blocking they can still request a retry in exceptional +circumstances. Specifically this will happen if a session +renegotiation takes place during a BIO_read() operation, one +case where this happens is when SGC or step up occurs. + +In OpenSSL 0.9.6 and later the SSL flag SSL_AUTO_RETRY can be +set to disable this behaviour. That is when this flag is set +an SSL BIO using a blocking transport will never request a +retry. + +Since unknown BIO_ctrl() operations are sent through filter +BIOs the servers name and port can be set using BIO_set_host() +on the BIO returned by BIO_new_ssl_connect() without having +to locate the connect BIO first. + +Applications do not have to call BIO_do_handshake() but may wish +to do so to separate the handshake process from other I/O +processing. + +=head1 RETURN VALUES + +TBA + +=head1 EXAMPLE + +This SSL/TLS client example, attempts to retrieve a page from an +SSL/TLS web server. The I/O routines are identical to those of the +unencrypted example in L. + + BIO *sbio, *out; + int len; + char tmpbuf[1024]; + SSL_CTX *ctx; + SSL *ssl; + + ERR_load_crypto_strings(); + ERR_load_SSL_strings(); + OpenSSL_add_all_algorithms(); + + /* We would seed the PRNG here if the platform didn't + * do it automatically + */ + + ctx = SSL_CTX_new(SSLv23_client_method()); + + /* We'd normally set some stuff like the verify paths and + * mode here because as things stand this will connect to + * any server whose certificate is signed by any CA. + */ + + sbio = BIO_new_ssl_connect(ctx); + + BIO_get_ssl(sbio, &ssl); + + if(!ssl) { + fprintf(stderr, "Can't locate SSL pointer\n"); + /* whatever ... */ + } + + /* Don't want any retries */ + SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); + + /* We might want to do other things with ssl here */ + + BIO_set_conn_hostname(sbio, "localhost:https"); + + out = BIO_new_fp(stdout, BIO_NOCLOSE); + if(BIO_do_connect(sbio) <= 0) { + fprintf(stderr, "Error connecting to server\n"); + ERR_print_errors_fp(stderr); + /* whatever ... */ + } + + if(BIO_do_handshake(sbio) <= 0) { + fprintf(stderr, "Error establishing SSL connection\n"); + ERR_print_errors_fp(stderr); + /* whatever ... */ + } + + /* Could examine ssl here to get connection info */ + + BIO_puts(sbio, "GET / HTTP/1.0\n\n"); + for(;;) { + len = BIO_read(sbio, tmpbuf, 1024); + if(len <= 0) break; + BIO_write(out, tmpbuf, len); + } + BIO_free_all(sbio); + BIO_free(out); + +Here is a simple server example. It makes use of a buffering +BIO to allow lines to be read from the SSL BIO using BIO_gets. +It creates a pseudo web page containing the actual request from +a client and also echoes the request to standard output. + + BIO *sbio, *bbio, *acpt, *out; + int len; + char tmpbuf[1024]; + SSL_CTX *ctx; + SSL *ssl; + + ERR_load_crypto_strings(); + ERR_load_SSL_strings(); + OpenSSL_add_all_algorithms(); + + /* Might seed PRNG here */ + + ctx = SSL_CTX_new(SSLv23_server_method()); + + if (!SSL_CTX_use_certificate_file(ctx,"server.pem",SSL_FILETYPE_PEM) + || !SSL_CTX_use_PrivateKey_file(ctx,"server.pem",SSL_FILETYPE_PEM) + || !SSL_CTX_check_private_key(ctx)) { + + fprintf(stderr, "Error setting up SSL_CTX\n"); + ERR_print_errors_fp(stderr); + return 0; + } + + /* Might do other things here like setting verify locations and + * DH and/or RSA temporary key callbacks + */ + + /* New SSL BIO setup as server */ + sbio=BIO_new_ssl(ctx,0); + + BIO_get_ssl(sbio, &ssl); + + if(!ssl) { + fprintf(stderr, "Can't locate SSL pointer\n"); + /* whatever ... */ + } + + /* Don't want any retries */ + SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); + + /* Create the buffering BIO */ + + bbio = BIO_new(BIO_f_buffer()); + + /* Add to chain */ + sbio = BIO_push(bbio, sbio); + + acpt=BIO_new_accept("4433"); + + /* By doing this when a new connection is established + * we automatically have sbio inserted into it. The + * BIO chain is now 'swallowed' by the accept BIO and + * will be freed when the accept BIO is freed. + */ + + BIO_set_accept_bios(acpt,sbio); + + out = BIO_new_fp(stdout, BIO_NOCLOSE); + + /* Setup accept BIO */ + if(BIO_do_accept(acpt) <= 0) { + fprintf(stderr, "Error setting up accept BIO\n"); + ERR_print_errors_fp(stderr); + return 0; + } + + /* Now wait for incoming connection */ + if(BIO_do_accept(acpt) <= 0) { + fprintf(stderr, "Error in connection\n"); + ERR_print_errors_fp(stderr); + return 0; + } + + /* We only want one connection so remove and free + * accept BIO + */ + + sbio = BIO_pop(acpt); + + BIO_free_all(acpt); + + if(BIO_do_handshake(sbio) <= 0) { + fprintf(stderr, "Error in SSL handshake\n"); + ERR_print_errors_fp(stderr); + return 0; + } + + BIO_puts(sbio, "HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n"); + BIO_puts(sbio, "
\r\nConnection Established\r\nRequest headers:\r\n");
+ BIO_puts(sbio, "--------------------------------------------------\r\n");
+
+ for(;;) {
+ 	len = BIO_gets(sbio, tmpbuf, 1024);
+        if(len <= 0) break;
+	BIO_write(sbio, tmpbuf, len);
+	BIO_write(out, tmpbuf, len);
+	/* Look for blank line signifying end of headers*/
+	if((tmpbuf[0] == '\r') || (tmpbuf[0] == '\n')) break;
+ }
+
+ BIO_puts(sbio, "--------------------------------------------------\r\n");
+ BIO_puts(sbio, "
\r\n"); + + /* Since there is a buffering BIO present we had better flush it */ + BIO_flush(sbio); + + BIO_free_all(sbio); + +=head1 SEE ALSO + +TBA diff --git a/lib/libssl/src/doc/crypto/BIO_find_type.pod b/lib/libssl/src/doc/crypto/BIO_find_type.pod new file mode 100644 index 00000000000..bd3b2561961 --- /dev/null +++ b/lib/libssl/src/doc/crypto/BIO_find_type.pod @@ -0,0 +1,98 @@ +=pod + +=head1 NAME + +BIO_find_type, BIO_next - BIO chain traversal + +=head1 SYNOPSIS + + #include + + BIO * BIO_find_type(BIO *b,int bio_type); + BIO * BIO_next(BIO *b); + + #define BIO_method_type(b) ((b)->method->type) + + #define BIO_TYPE_NONE 0 + #define BIO_TYPE_MEM (1|0x0400) + #define BIO_TYPE_FILE (2|0x0400) + + #define BIO_TYPE_FD (4|0x0400|0x0100) + #define BIO_TYPE_SOCKET (5|0x0400|0x0100) + #define BIO_TYPE_NULL (6|0x0400) + #define BIO_TYPE_SSL (7|0x0200) + #define BIO_TYPE_MD (8|0x0200) + #define BIO_TYPE_BUFFER (9|0x0200) + #define BIO_TYPE_CIPHER (10|0x0200) + #define BIO_TYPE_BASE64 (11|0x0200) + #define BIO_TYPE_CONNECT (12|0x0400|0x0100) + #define BIO_TYPE_ACCEPT (13|0x0400|0x0100) + #define BIO_TYPE_PROXY_CLIENT (14|0x0200) + #define BIO_TYPE_PROXY_SERVER (15|0x0200) + #define BIO_TYPE_NBIO_TEST (16|0x0200) + #define BIO_TYPE_NULL_FILTER (17|0x0200) + #define BIO_TYPE_BER (18|0x0200) + #define BIO_TYPE_BIO (19|0x0400) + + #define BIO_TYPE_DESCRIPTOR 0x0100 + #define BIO_TYPE_FILTER 0x0200 + #define BIO_TYPE_SOURCE_SINK 0x0400 + +=head1 DESCRIPTION + +The BIO_find_type() searches for a BIO of a given type in a chain, starting +at BIO B. If B is a specific type (such as BIO_TYPE_MEM) then a search +is made for a BIO of that type. If B is a general type (such as +B) then the next matching BIO of the given general type is +searched for. BIO_find_type() returns the next matching BIO or NULL if none is +found. + +Note: not all the B types above have corresponding BIO implementations. + +BIO_next() returns the next BIO in a chain. It can be used to traverse all BIOs +in a chain or used in conjunction with BIO_find_type() to find all BIOs of a +certain type. + +BIO_method_type() returns the type of a BIO. + +=head1 RETURN VALUES + +BIO_find_type() returns a matching BIO or NULL for no match. + +BIO_next() returns the next BIO in a chain. + +BIO_method_type() returns the type of the BIO B. + +=head1 NOTES + +BIO_next() was added to OpenSSL 0.9.6 to provide a 'clean' way to traverse a BIO +chain or find multiple matches using BIO_find_type(). Previous versions had to +use: + + next = bio->next_bio; + +=head1 BUGS + +BIO_find_type() in OpenSSL 0.9.5a and earlier could not be safely passed a +NULL pointer for the B argument. + +=head1 EXAMPLE + +Traverse a chain looking for digest BIOs: + + BIO *btmp; + btmp = in_bio; /* in_bio is chain to search through */ + + do { + btmp = BIO_find_type(btmp, BIO_TYPE_MD); + if(btmp == NULL) break; /* Not found */ + /* btmp is a digest BIO, do something with it ...*/ + ... + + btmp = BIO_next(btmp); + } while(btmp); + + +=head1 SEE ALSO + +TBA diff --git a/lib/libssl/src/doc/crypto/BIO_new.pod b/lib/libssl/src/doc/crypto/BIO_new.pod new file mode 100644 index 00000000000..2a245fc8de8 --- /dev/null +++ b/lib/libssl/src/doc/crypto/BIO_new.pod @@ -0,0 +1,65 @@ +=pod + +=head1 NAME + +BIO_new, BIO_set, BIO_free, BIO_vfree, BIO_free_all - BIO allocation and freeing functions + +=head1 SYNOPSIS + + #include + + BIO * BIO_new(BIO_METHOD *type); + int BIO_set(BIO *a,BIO_METHOD *type); + int BIO_free(BIO *a); + void BIO_vfree(BIO *a); + void BIO_free_all(BIO *a); + +=head1 DESCRIPTION + +The BIO_new() function returns a new BIO using method B. + +BIO_set() sets the method of an already existing BIO. + +BIO_free() frees up a single BIO, BIO_vfree() also frees up a single BIO +but it does not return a value. Calling BIO_free() may also have some effect +on the underlying I/O structure, for example it may close the file being +referred to under certain circumstances. For more details see the individual +BIO_METHOD descriptions. + +BIO_free_all() frees up an entire BIO chain, it does not halt if an error +occurs freeing up an individual BIO in the chain. + +=head1 RETURN VALUES + +BIO_new() returns a newly created BIO or NULL if the call fails. + +BIO_set(), BIO_free() return 1 for success and 0 for failure. + +BIO_free_all() and BIO_vfree() do not return values. + +=head1 NOTES + +Some BIOs (such as memory BIOs) can be used immediately after calling +BIO_new(). Others (such as file BIOs) need some additional initialization, +and frequently a utility function exists to create and initialize such BIOs. + +If BIO_free() is called on a BIO chain it will only free one BIO resulting +in a memory leak. + +Calling BIO_free_all() a single BIO has the same effect as calling BIO_free() +on it other than the discarded return value. + +Normally the B argument is supplied by a function which returns a +pointer to a BIO_METHOD. There is a naming convention for such functions: +a source/sink BIO is normally called BIO_s_*() and a filter BIO +BIO_f_*(); + +=head1 EXAMPLE + +Create a memory BIO: + + BIO *mem = BIO_new(BIO_s_mem()); + +=head1 SEE ALSO + +TBA diff --git a/lib/libssl/src/doc/crypto/BIO_new_bio_pair.pod b/lib/libssl/src/doc/crypto/BIO_new_bio_pair.pod new file mode 100644 index 00000000000..2256ba9d341 --- /dev/null +++ b/lib/libssl/src/doc/crypto/BIO_new_bio_pair.pod @@ -0,0 +1,102 @@ +=pod + +=head1 NAME + +BIO_new_bio_pair - create a new BIO pair + +=head1 SYNOPSIS + + #include + + int BIO_new_bio_pair(BIO **bio1, size_t writebuf1, BIO **bio2, size_t writebuf2); + +=head1 DESCRIPTION + +BIO_new_bio_pair() creates a buffering BIO pair. It has two endpoints between +data can be buffered. Its typical use is to connect one endpoint as underlying +input/output BIO to an SSL and access the other one controlled by the program +instead of accessing the network connection directly. + +The two new BIOs B and B are symmetric with respect to their +functionality. The size of their buffers is determined by B and +B. If the size give is 0, the default size is used. + +BIO_new_bio_pair() does not check whether B or B do point to +some other BIO, the values are overwritten, BIO_free() is not called. + +The two BIOs, even though forming a BIO pair and must be BIO_free()'ed +separately. This can be of importance, as some SSL-functions like SSL_set_bio() +or SSL_free() call BIO_free() implicitly, so that the peer-BIO is left +untouched and must also be BIO_free()'ed. + +=head1 EXAMPLE + +The BIO pair can be used to have full control over the network access of an +application. The application can call select() on the socket as required +without having to go through the SSL-interface. + + BIO *internal_bio, *network_bio; + ... + BIO_new_bio_pair(internal_bio, 0, network_bio, 0); + SSL_set_bio(ssl, internal_bio); + SSL_operations(); + ... + + application | TLS-engine + | | + +----------> SSL_operations() + | /\ || + | || \/ + | BIO-pair (internal_bio) + +----------< BIO-pair (network_bio) + | | + socket | + + ... + SSL_free(ssl); /* implicitly frees internal_bio */ + BIO_free(network_bio); + ... + +As the BIO pair will only buffer the data and never directly access the +connection, it behaves non-blocking and will return as soon as the write +buffer is full or the read buffer is drained. Then the application has to +flush the write buffer and/or fill the read buffer. + +Use the BIO_ctrl_pending(), to find out whether data is buffered in the BIO +and must be transfered to the network. Use BIO_ctrl_get_read_request() to +find out, how many bytes must be written into the buffer before the +SSL_operation() can successfully be continued. + +=head1 IMPORTANT + +As the data is buffered, SSL_operation() may return with a ERROR_SSL_WANT_READ +condition, but there is still data in the write buffer. An application must +not rely on the error value of SSL_operation() but must assure that the +write buffer is always flushed first. Otherwise a deadlock may occur as +the peer might be waiting for the data before being able to continue. + +=head1 RETURN VALUES + +The following return values can occur: + +=over 4 + +=item 1 + +The BIO pair was created successfully. The new BIOs are available in +B and B. + +=item 0 + +The operation failed. The NULL pointer is stored into the locations for +B and B. Check the error stack for more information. + +=back + +=head1 SEE ALSO + +L, L, L, +L, +L + +=cut diff --git a/lib/libssl/src/doc/crypto/BIO_push.pod b/lib/libssl/src/doc/crypto/BIO_push.pod new file mode 100644 index 00000000000..8af1d3c0975 --- /dev/null +++ b/lib/libssl/src/doc/crypto/BIO_push.pod @@ -0,0 +1,69 @@ +=pod + +=head1 NAME + +BIO_push, BIO_pop - add and remove BIOs from a chain. + +=head1 SYNOPSIS + + #include + + BIO * BIO_push(BIO *b,BIO *append); + BIO * BIO_pop(BIO *b); + +=head1 DESCRIPTION + +The BIO_push() function appends the BIO B to B, it returns +B. + +BIO_pop() removes the BIO B from a chain and returns the next BIO +in the chain, or NULL if there is no next BIO. The removed BIO then +becomes a single BIO with no association with the original chain, +it can thus be freed or attached to a different chain. + +=head1 NOTES + +The names of these functions are perhaps a little misleading. BIO_push() +joins two BIO chains whereas BIO_pop() deletes a single BIO from a chain, +the deleted BIO does not need to be at the end of a chain. + +The process of calling BIO_push() and BIO_pop() on a BIO may have additional +consequences (a control call is made to the affected BIOs) any effects will +be noted in the descriptions of individual BIOs. + +=head1 EXAMPLES + +For these examples suppose B and B are digest BIOs, B is +a base64 BIO and B is a file BIO. + +If the call: + + BIO_push(b64, f); + +is made then the new chain will be B. After making the calls + + BIO_push(md2, b64); + BIO_push(md1, md2); + +the new chain is B. Data written to B will be digested +by B and B, B encoded and written to B. + +It should be noted that reading causes data to pass in the reverse +direction, that is data is read from B, base64 B and digested +by B and B. If the call: + + BIO_pop(md2); + +The call will return B and the new chain will be B data can +be written to B as before. + +=head1 RETURN VALUES + +BIO_push() returns the end of the chain, B. + +BIO_pop() returns the next BIO in the chain, or NULL if there is no next +BIO. + +=head1 SEE ALSO + +TBA diff --git a/lib/libssl/src/doc/crypto/BIO_read.pod b/lib/libssl/src/doc/crypto/BIO_read.pod new file mode 100644 index 00000000000..b34528104dd --- /dev/null +++ b/lib/libssl/src/doc/crypto/BIO_read.pod @@ -0,0 +1,66 @@ +=pod + +=head1 NAME + +BIO_read, BIO_write, BIO_gets, BIO_puts - BIO I/O functions + +=head1 SYNOPSIS + + #include + + int BIO_read(BIO *b, void *buf, int len); + int BIO_gets(BIO *b,char *buf, int size); + int BIO_write(BIO *b, const void *buf, int len); + int BIO_puts(BIO *b,const char *buf); + +=head1 DESCRIPTION + +BIO_read() attempts to read B bytes from BIO B and places +the data in B. + +BIO_gets() performs the BIOs "gets" operation and places the data +in B. Usually this operation will attempt to read a line of data +from the BIO of maximum length B. There are exceptions to this +however, for example BIO_gets() on a digest BIO will calculate and +return the digest and other BIOs may not support BIO_gets() at all. + +BIO_write() attempts to write B bytes from B to BIO B. + +BIO_puts() attempts to write a null terminated string B to BIO B + +=head1 RETURN VALUES + +All these functions return either the amount of data successfully read or +written (if the return value is positive) or that no data was successfully +read or written if the result is 0 or -1. If the return value is -2 then +the operation is not implemented in the specific BIO type. + +=head1 NOTES + +A 0 or -1 return is not necessarily an indication of an error. In +particular when the source/sink is non-blocking or of a certain type +it may merely be an indication that no data is currently available and that +the application should retry the operation later. + +One technique sometimes used with blocking sockets is to use a system call +(such as select(), poll() or equivalent) to determine when data is available +and then call read() to read the data. The equivalent with BIOs (that is call +select() on the underlying I/O structure and then call BIO_read() to +read the data) should B be used because a single call to BIO_read() +can cause several reads (and writes in the case of SSL BIOs) on the underlying +I/O structure and may block as a result. Instead select() (or equivalent) +should be combined with non blocking I/O so successive reads will request +a retry instead of blocking. + +See L for details of how to +determine the cause of a retry and other I/O issues. + +If the BIO_gets() function is not supported by a BIO then it possible to +work around this by adding a buffering BIO L +to the chain. + +=head1 SEE ALSO + +L + +TBA diff --git a/lib/libssl/src/doc/crypto/BIO_s_accept.pod b/lib/libssl/src/doc/crypto/BIO_s_accept.pod new file mode 100644 index 00000000000..c49da7fb02c --- /dev/null +++ b/lib/libssl/src/doc/crypto/BIO_s_accept.pod @@ -0,0 +1,184 @@ +=pod + +=head1 NAME + +BIO_s_accept, BIO_set_nbio, BIO_set_accept_port, BIO_get_accept_port, +BIO_set_nbio_accept, BIO_set_accept_bios, BIO_set_bind_mode, +BIO_get_bind_mode, BIO_do_accept - accept BIO + +=head1 SYNOPSIS + + #include + + BIO_METHOD * BIO_s_accept(void); + + #define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name) + #define BIO_get_accept_port(b) BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0) + + BIO *BIO_new_accept(char *host_port); + + #define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?"a":NULL) + #define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(char *)bio) + + #define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL) + #define BIO_get_bind_mode(b,mode) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL) + + #define BIO_BIND_NORMAL 0 + #define BIO_BIND_REUSEADDR_IF_UNUSED 1 + #define BIO_BIND_REUSEADDR 2 + + #define BIO_do_accept(b) BIO_do_handshake(b) + +=head1 DESCRIPTION + +BIO_s_accept() returns the accept BIO method. This is a wrapper +round the platform's TCP/IP socket accept routines. + +Using accept BIOs TCP/IP connections can be accepted and data +transferred using only BIO routines. In this way any platform +specific operations are hidden by the BIO abstraction. + +Read and write operations on an accept BIO will perform I/O +on the underlying connection. If no connection is established +and the port (see below) is set up properly then the BIO +waits for an incoming connection. + +Accept BIOs support BIO_puts() but not BIO_gets(). + +If the close flag is set on an accept BIO then any active +connection on that chain is shutdown and the socket closed when +the BIO is freed. + +Calling BIO_reset() on a accept BIO will close any active +connection and reset the BIO into a state where it awaits another +incoming connection. + +BIO_get_fd() and BIO_set_fd() can be called to retrieve or set +the accept socket. See L + +BIO_set_accept_port() uses the string B to set the accept +port. The port is represented as a string of the form "host:port", +where "host" is the interface to use and "port" is the port. +Either or both values can be "*" which is interpreted as meaning +any interface or port respectively. "port" has the same syntax +as the port specified in BIO_set_conn_port() for connect BIOs, +that is it can be a numerical port string or a string to lookup +using getservbyname() and a string table. + +BIO_new_accept() combines BIO_new() and BIO_set_accept_port() into +a single call: that is it creates a new accept BIO with port +B. + +BIO_set_nbio_accept() sets the accept socket to blocking mode +(the default) if B is 0 or non blocking mode if B is 1. + +BIO_set_accept_bios() can be used to set a chain of BIOs which +will be duplicated and prepended to the chain when an incoming +connection is received. This is useful if, for example, a +buffering or SSL BIO is required for each connection. The +chain of BIOs must not be freed after this call, they will +be automatically freed when the accept BIO is freed. + +BIO_set_bind_mode() and BIO_get_bind_mode() set and retrieve +the current bind mode. If BIO_BIND_NORMAL (the default) is set +then another socket cannot be bound to the same port. If +BIO_BIND_REUSEADDR is set then other sockets can bind to the +same port. If BIO_BIND_REUSEADDR_IF_UNUSED is set then and +attempt is first made to use BIO_BIN_NORMAL, if this fails +and the port is not in use then a second attempt is made +using BIO_BIND_REUSEADDR. + +BIO_do_accept() serves two functions. When it is first +called, after the accept BIO has been setup, it will attempt +to create the accept socket and bind an address to it. Second +and subsequent calls to BIO_do_accept() will await an incoming +connection. + +=head1 NOTES + +When an accept BIO is at the end of a chain it will await an +incoming connection before processing I/O calls. When an accept +BIO is not at then end of a chain it passes I/O calls to the next +BIO in the chain. + +When a connection is established a new socket BIO is created for +the connection and appended to the chain. That is the chain is now +accept->socket. This effectively means that attempting I/O on +an initial accept socket will await an incoming connection then +perform I/O on it. + +If any additional BIOs have been set using BIO_set_accept_bios() +then they are placed between the socket and the accept BIO, +that is the chain will be accept->otherbios->socket. + +If a server wishes to process multiple connections (as is normally +the case) then the accept BIO must be made available for further +incoming connections. This can be done by waiting for a connection and +then calling: + + connection = BIO_pop(accept); + +After this call B will contain a BIO for the recently +established connection and B will now be a single BIO +again which can be used to await further incoming connections. +If no further connections will be accepted the B can +be freed using BIO_free(). + +If only a single connection will be processed it is possible to +perform I/O using the accept BIO itself. This is often undesirable +however because the accept BIO will still accept additional incoming +connections. This can be resolved by using BIO_pop() (see above) +and freeing up the accept BIO after the initial connection. + +=head1 RETURN VALUES + +TBA + +=head1 EXAMPLE + +This example accepts two connections on port 4444, sends messages +down each and finally closes both down. + + BIO *abio, *cbio, *cbio2; + ERR_load_crypto_strings(); + abio = BIO_new_accept("4444"); + + /* First call to BIO_accept() sets up accept BIO */ + if(BIO_do_accept(abio) <= 0) { + fprintf(stderr, "Error setting up accept\n"); + ERR_print_errors_fp(stderr); + exit(0); + } + + /* Wait for incoming connection */ + if(BIO_do_accept(abio) <= 0) { + fprintf(stderr, "Error accepting connection\n"); + ERR_print_errors_fp(stderr); + exit(0); + } + fprintf(stderr, "Connection 1 established\n"); + /* Retrieve BIO for connection */ + cbio = BIO_pop(abio); + BIO_puts(cbio, "Connection 1: Sending out Data on initial connection\n"); + fprintf(stderr, "Sent out data on connection 1\n"); + /* Wait for another connection */ + if(BIO_do_accept(abio) <= 0) { + fprintf(stderr, "Error accepting connection\n"); + ERR_print_errors_fp(stderr); + exit(0); + } + fprintf(stderr, "Connection 2 established\n"); + /* Close accept BIO to refuse further connections */ + cbio2 = BIO_pop(abio); + BIO_free(abio); + BIO_puts(cbio2, "Connection 2: Sending out Data on second\n"); + fprintf(stderr, "Sent out data on connection 2\n"); + + BIO_puts(cbio, "Connection 1: Second connection established\n"); + /* Close the two established connections */ + BIO_free(cbio); + BIO_free(cbio2); + +=head1 SEE ALSO + +TBA diff --git a/lib/libssl/src/doc/crypto/BIO_s_bio.pod b/lib/libssl/src/doc/crypto/BIO_s_bio.pod new file mode 100644 index 00000000000..95ae802e472 --- /dev/null +++ b/lib/libssl/src/doc/crypto/BIO_s_bio.pod @@ -0,0 +1,130 @@ +=pod + +=head1 NAME + +BIO_s_bio, BIO_make_bio_pair, BIO_destroy_bio_pair, BIO_shutdown_wr, +BIO_set_write_buf_size, BIO_get_write_buf_size, BIO_new_bio_pair, +BIO_get_write_guarantee, BIO_ctrl_get_write_guarantee, BIO_get_read_request, +BIO_ctrl_get_read_request, BIO_ctrl_reset_read_request - BIO pair BIO + +=head1 SYNOPSIS + + #include + + BIO_METHOD *BIO_s_bio(void); + + #define BIO_make_bio_pair(b1,b2) (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2) + #define BIO_destroy_bio_pair(b) (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL) + + #define BIO_shutdown_wr(b) (int)BIO_ctrl(b, BIO_C_SHUTDOWN_WR, 0, NULL) + + #define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL) + #define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL) + + int BIO_new_bio_pair(BIO **bio1, size_t writebuf1, BIO **bio2, size_t writebuf2); + + #define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL) + size_t BIO_ctrl_get_write_guarantee(BIO *b); + + #define BIO_get_read_request(b) (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL) + size_t BIO_ctrl_get_read_request(BIO *b); + + int BIO_ctrl_reset_read_request(BIO *b); + +=head1 DESCRIPTION + +BIO_s_bio() returns the method for a BIO pair. A BIO pair is a pair of source/sink +BIOs where data written to either half of the pair is buffered and can be read from +the other half. Both halves must usually by handled by the same application thread +since no locking is done on the internal data structures. + +Since BIO chains typically end in a source/sink BIO it is possible to make this +one half of a BIO pair and have all the data processed by the chain under application +control. + +One typical use of BIO pairs is to place TLS/SSL I/O under application control, this +can be used when the application wishes to use a non standard transport for +TLS/SSL or the normal socket routines are inappropriate. + +Calls to BIO_read() will read data from the buffer or request a retry if no +data is available. + +Calls to BIO_write() will place data in the buffer or request a retry if the +buffer is full. + +The standard calls BIO_ctrl_pending() and BIO_ctrl_wpending() can be used to +determine the amount of pending data in the read or write buffer. + +BIO_reset() clears any data in the write buffer. + +BIO_make_bio_pair() joins two separate BIOs into a connected pair. + +BIO_destroy_pair() destroys the association between two connected BIOs. Freeing +up any half of the pair will automatically destroy the association. + +BIO_shutdown_wr() is used to close down a BIO B. After this call no further +writes on BIO B are allowed (they will return an error). Reads on the other +half of the pair will return any pending data or EOF when all pending data has +been read. + +BIO_set_write_buf_size() sets the write buffer size of BIO B to B. +If the size is not initialized a default value is used. This is currently +17K, sufficient for a maximum size TLS record. + +BIO_get_write_buf_size() returns the size of the write buffer. + +BIO_new_bio_pair() combines the calls to BIO_new(), BIO_make_bio_pair() and +BIO_set_write_buf_size() to create a connected pair of BIOs B, B +with write buffer sizes B and B. If either size is +zero then the default size is used. + +BIO_get_write_guarantee() and BIO_ctrl_get_write_guarantee() return the maximum +length of data that can be currently written to the BIO. Writes larger than this +value will return a value from BIO_write() less than the amount requested or if the +buffer is full request a retry. BIO_ctrl_get_write_guarantee() is a function +whereas BIO_get_write_guarantee() is a macro. + +BIO_get_read_request() and BIO_ctrl_get_read_request() return the +amount of data requested, or the buffer size if it is less, if the +last read attempt at the other half of the BIO pair failed due to an +empty buffer. This can be used to determine how much data should be +written to the BIO so the next read will succeed: this is most useful +in TLS/SSL applications where the amount of data read is usually +meaningful rather than just a buffer size. After a successful read +this call will return zero. It also will return zero once new data +has been written satisfying the read request or part of it. +Note that BIO_get_read_request() never returns an amount larger +than that returned by BIO_get_write_guarantee(). + +BIO_ctrl_reset_read_request() can also be used to reset the value returned by +BIO_get_read_request() to zero. + +=head1 NOTES + +Both halves of a BIO pair should be freed. That is even if one half is implicit +freed due to a BIO_free_all() or SSL_free() call the other half needs to be freed. + +When used in bidirectional applications (such as TLS/SSL) care should be taken to +flush any data in the write buffer. This can be done by calling BIO_pending() +on the other half of the pair and, if any data is pending, reading it and sending +it to the underlying transport. This must be done before any normal processing +(such as calling select() ) due to a request and BIO_should_read() being true. + +To see why this is important consider a case where a request is sent using +BIO_write() and a response read with BIO_read(), this can occur during an +TLS/SSL handshake for example. BIO_write() will succeed and place data in the write +buffer. BIO_read() will initially fail and BIO_should_read() will be true. If +the application then waits for data to be available on the underlying transport +before flushing the write buffer it will never succeed because the request was +never sent! + +=head1 EXAMPLE + +TBA + +=head1 SEE ALSO + +L, L, L, +L, L + +=cut diff --git a/lib/libssl/src/doc/crypto/BIO_s_connect.pod b/lib/libssl/src/doc/crypto/BIO_s_connect.pod new file mode 100644 index 00000000000..fe1aa679d44 --- /dev/null +++ b/lib/libssl/src/doc/crypto/BIO_s_connect.pod @@ -0,0 +1,182 @@ +=pod + +=head1 NAME + +BIO_s_connect, BIO_set_conn_hostname, BIO_set_conn_port, +BIO_set_conn_ip, BIO_set_conn_int_port, BIO_get_conn_hostname, +BIO_get_conn_port, BIO_get_conn_ip, BIO_get_conn_int_port, +BIO_set_nbio, BIO_do_connect - connect BIO + +=head1 SYNOPSIS + + #include + + BIO_METHOD * BIO_s_connect(void); + + #define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0,(char *)name) + #define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1,(char *)port) + #define BIO_set_conn_ip(b,ip) BIO_ctrl(b,BIO_C_SET_CONNECT,2,(char *)ip) + #define BIO_set_conn_int_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,3,(char *)port) + #define BIO_get_conn_hostname(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0) + #define BIO_get_conn_port(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1) + #define BIO_get_conn_ip(b,ip) BIO_ptr_ctrl(b,BIO_C_SET_CONNECT,2) + #define BIO_get_conn_int_port(b,port) BIO_int_ctrl(b,BIO_C_SET_CONNECT,3,port) + + #define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) + + #define BIO_do_connect(b) BIO_do_handshake(b) + +=head1 DESCRIPTION + +BIO_s_connect() returns the connect BIO method. This is a wrapper +round the platform's TCP/IP socket connection routines. + +Using connect BIOs TCP/IP connections can be made and data +transferred using only BIO routines. In this way any platform +specific operations are hidden by the BIO abstraction. + +Read and write operations on a connect BIO will perform I/O +on the underlying connection. If no connection is established +and the port and hostname (see below) is set up properly then +a connection is established first. + +Connect BIOs support BIO_puts() but not BIO_gets(). + +If the close flag is set on a connect BIO then any active +connection is shutdown and the socket closed when the BIO +is freed. + +Calling BIO_reset() on a connect BIO will close any active +connection and reset the BIO into a state where it can connect +to the same host again. + +BIO_get_fd() places the underlying socket in B if it is not NULL, +it also returns the socket . If B is not NULL it should be of +type (int *). + +BIO_set_conn_hostname() uses the string B to set the hostname +The hostname can be an IP address. The hostname can also include the +port in the form hostname:port . It is also acceptable to use the +form "hostname/any/other/path" or "hostname:port/any/other/path". + +BIO_set_conn_port() sets the port to B. B can be the +numerical form or a string such as "http". A string will be looked +up first using getservbyname() on the host platform but if that +fails a standard table of port names will be used. Currently the +list is http, telnet, socks, https, ssl, ftp, gopher and wais. + +BIO_set_conn_ip() sets the IP address to B using binary form, +that is four bytes specifying the IP address in big-endian form. + +BIO_set_conn_int_port() sets the port using B. B should +be of type (int *). + +BIO_get_conn_hostname() returns the hostname of the connect BIO or +NULL if the BIO is initialized but no hostname is set. +This return value is an internal pointer which should not be modified. + +BIO_get_conn_port() returns the port as a string. + +BIO_get_conn_ip() returns the IP address in binary form. + +BIO_get_conn_int_port() returns the port as an int. + +BIO_set_nbio() sets the non blocking I/O flag to B. If B is +zero then blocking I/O is set. If B is 1 then non blocking I/O +is set. Blocking I/O is the default. The call to BIO_set_nbio() +should be made before the connection is established because +non blocking I/O is set during the connect process. + +BIO_do_connect() attempts to connect the supplied BIO. It returns 1 +if the connection was established successfully. A zero or negative +value is returned if the connection could not be established, the +call BIO_should_retry() should be used for non blocking connect BIOs +to determine if the call should be retried. + +=head1 NOTES + +If blocking I/O is set then a non positive return value from any +I/O call is caused by an error condition, although a zero return +will normally mean that the connection was closed. + +If the port name is supplied as part of the host name then this will +override any value set with BIO_set_conn_port(). This may be undesirable +if the application does not wish to allow connection to arbitrary +ports. This can be avoided by checking for the presence of the ':' +character in the passed hostname and either indicating an error or +truncating the string at that point. + +The values returned by BIO_get_conn_hostname(), BIO_get_conn_port(), +BIO_get_conn_ip() and BIO_get_conn_int_port() are updated when a +connection attempt is made. Before any connection attempt the values +returned are those set by the application itself. + +Applications do not have to call BIO_do_connect() but may wish to do +so to separate the connection process from other I/O processing. + +If non blocking I/O is set then retries will be requested as appropriate. + +It addition to BIO_should_read() and BIO_should_write() it is also +possible for BIO_should_io_special() to be true during the initial +connection process with the reason BIO_RR_CONNECT. If this is returned +then this is an indication that a connection attempt would block, +the application should then take appropriate action to wait until +the underlying socket has connected and retry the call. + +=head1 RETURN VALUES + +BIO_s_connect() returns the connect BIO method. + +BIO_get_fd() returns the socket or -1 if the BIO has not +been initialized. + +BIO_set_conn_hostname(), BIO_set_conn_port(), BIO_set_conn_ip() and +BIO_set_conn_int_port() always return 1. + +BIO_get_conn_hostname() returns the connected hostname or NULL is +none was set. + +BIO_get_conn_port() returns a string representing the connected +port or NULL if not set. + +BIO_get_conn_ip() returns a pointer to the connected IP address in +binary form or all zeros if not set. + +BIO_get_conn_int_port() returns the connected port or 0 if none was +set. + +BIO_set_nbio() always returns 1. + +BIO_do_connect() returns 1 if the connection was successfully +established and 0 or -1 if the connection failed. + +=head1 EXAMPLE + +This is example connects to a webserver on the local host and attempts +to retrieve a page and copy the result to standard output. + + + BIO *cbio, *out; + int len; + char tmpbuf[1024]; + ERR_load_crypto_strings(); + cbio = BIO_new_connect("localhost:http"); + out = BIO_new_fp(stdout, BIO_NOCLOSE); + if(BIO_do_connect(cbio) <= 0) { + fprintf(stderr, "Error connecting to server\n"); + ERR_print_errors_fp(stderr); + /* whatever ... */ + } + BIO_puts(cbio, "GET / HTTP/1.0\n\n"); + for(;;) { + len = BIO_read(cbio, tmpbuf, 1024); + if(len <= 0) break; + BIO_write(out, tmpbuf, len); + } + BIO_free(cbio); + BIO_free(out); + + +=head1 SEE ALSO + +TBA diff --git a/lib/libssl/src/doc/crypto/BIO_s_fd.pod b/lib/libssl/src/doc/crypto/BIO_s_fd.pod new file mode 100644 index 00000000000..b1de1d10154 --- /dev/null +++ b/lib/libssl/src/doc/crypto/BIO_s_fd.pod @@ -0,0 +1,89 @@ +=pod + +=head1 NAME + +BIO_s_fd, BIO_set_fd, BIO_get_fd, BIO_new_fd - file descriptor BIO + +=head1 SYNOPSIS + + #include + + BIO_METHOD * BIO_s_fd(void); + + #define BIO_set_fd(b,fd,c) BIO_int_ctrl(b,BIO_C_SET_FD,c,fd) + #define BIO_get_fd(b,c) BIO_ctrl(b,BIO_C_GET_FD,0,(char *)c) + + BIO *BIO_new_fd(int fd, int close_flag); + +=head1 DESCRIPTION + +BIO_s_fd() returns the file descriptor BIO method. This is a wrapper +round the platforms file descriptor routines such as read() and write(). + +BIO_read() and BIO_write() read or write the underlying descriptor. +BIO_puts() is supported but BIO_gets() is not. + +If the close flag is set then then close() is called on the underlying +file descriptor when the BIO is freed. + +BIO_reset() attempts to change the file pointer to the start of file +using lseek(fd, 0, 0). + +BIO_seek() sets the file pointer to position B from start of file +using lseek(fd, ofs, 0). + +BIO_tell() returns the current file position by calling lseek(fd, 0, 1). + +BIO_set_fd() sets the file descriptor of BIO B to B and the close +flag to B. + +BIO_get_fd() places the file descriptor in B if it is not NULL, it also +returns the file descriptor. If B is not NULL it should be of type +(int *). + +BIO_new_fd() returns a file descriptor BIO using B and B. + +=head1 NOTES + +The behaviour of BIO_read() and BIO_write() depends on the behavior of the +platforms read() and write() calls on the descriptor. If the underlying +file descriptor is in a non blocking mode then the BIO will behave in the +manner described in the L and L +manual pages. + +File descriptor BIOs should not be used for socket I/O. Use socket BIOs +instead. + +=head1 RETURN VALUES + +BIO_s_fd() returns the file descriptor BIO method. + +BIO_reset() returns zero for success and -1 if an error occurred. +BIO_seek() and BIO_tell() return the current file position or -1 +is an error occurred. These values reflect the underlying lseek() +behaviour. + +BIO_set_fd() always returns 1. + +BIO_get_fd() returns the file descriptor or -1 if the BIO has not +been initialized. + +BIO_new_fd() returns the newly allocated BIO or NULL is an error +occurred. + +=head1 EXAMPLE + +This is a file descriptor BIO version of "Hello World": + + BIO *out; + out = BIO_new_fd(fileno(stdout), BIO_NOCLOSE); + BIO_printf(out, "Hello World\n"); + BIO_free(out); + +=head1 SEE ALSO + +L, L, +L, L, +L, L, +L, L, +L, L diff --git a/lib/libssl/src/doc/crypto/BIO_s_file.pod b/lib/libssl/src/doc/crypto/BIO_s_file.pod new file mode 100644 index 00000000000..b2a29263f4c --- /dev/null +++ b/lib/libssl/src/doc/crypto/BIO_s_file.pod @@ -0,0 +1,144 @@ +=pod + +=head1 NAME + +BIO_s_file, BIO_new_file, BIO_new_fp, BIO_set_fp, BIO_get_fp, +BIO_read_filename, BIO_write_filename, BIO_append_filename, +BIO_rw_filename - FILE bio + +=head1 SYNOPSIS + + #include + + BIO_METHOD * BIO_s_file(void); + BIO *BIO_new_file(const char *filename, const char *mode); + BIO *BIO_new_fp(FILE *stream, int flags); + + BIO_set_fp(BIO *b,FILE *fp, int flags); + BIO_get_fp(BIO *b,FILE **fpp); + + int BIO_read_filename(BIO *b, char *name) + int BIO_write_filename(BIO *b, char *name) + int BIO_append_filename(BIO *b, char *name) + int BIO_rw_filename(BIO *b, char *name) + +=head1 DESCRIPTION + +BIO_s_file() returns the BIO file method. As its name implies it +is a wrapper round the stdio FILE structure and it is a +source/sink BIO. + +Calls to BIO_read() and BIO_write() read and write data to the +underlying stream. BIO_gets() and BIO_puts() are supported on file BIOs. + +BIO_flush() on a file BIO calls the fflush() function on the wrapped +stream. + +BIO_reset() attempts to change the file pointer to the start of file +using fseek(stream, 0, 0). + +BIO_seek() sets the file pointer to position B from start of file +using fseek(stream, ofs, 0). + +BIO_eof() calls feof(). + +Setting the BIO_CLOSE flag calls fclose() on the stream when the BIO +is freed. + +BIO_new_file() creates a new file BIO with mode B the meaning +of B is the same as the stdio function fopen(). The BIO_CLOSE +flag is set on the returned BIO. + +BIO_new_fp() creates a file BIO wrapping B. Flags can be: +BIO_CLOSE, BIO_NOCLOSE (the close flag) BIO_FP_TEXT (sets the underlying +stream to text mode, default is binary: this only has any effect under +Win32). + +BIO_set_fp() set the fp of a file BIO to B. B has the same +meaning as in BIO_new_fp(), it is a macro. + +BIO_get_fp() retrieves the fp of a file BIO, it is a macro. + +BIO_seek() is a macro that sets the position pointer to B bytes +from the start of file. + +BIO_tell() returns the value of the position pointer. + +BIO_read_filename(), BIO_write_filename(), BIO_append_filename() and +BIO_rw_filename() set the file BIO B to use file B for +reading, writing, append or read write respectively. + +=head1 NOTES + +When wrapping stdout, stdin or stderr the underlying stream should not +normally be closed so the BIO_NOCLOSE flag should be set. + +Because the file BIO calls the underlying stdio functions any quirks +in stdio behaviour will be mirrored by the corresponding BIO. + +=head1 EXAMPLES + +File BIO "hello world": + + BIO *bio_out; + bio_out = BIO_new_fp(stdout, BIO_NOCLOSE); + BIO_printf(bio_out, "Hello World\n"); + +Alternative technique: + + BIO *bio_out; + bio_out = BIO_new(BIO_s_file()); + if(bio_out == NULL) /* Error ... */ + if(!BIO_set_fp(bio_out, stdout, BIO_NOCLOSE)) /* Error ... */ + BIO_printf(bio_out, "Hello World\n"); + +Write to a file: + + BIO *out; + out = BIO_new_file("filename.txt", "w"); + if(!out) /* Error occurred */ + BIO_printf(out, "Hello World\n"); + BIO_free(out); + +Alternative technique: + + BIO *out; + out = BIO_new(BIO_s_file()); + if(out == NULL) /* Error ... */ + if(!BIO_write_filename(out, "filename.txt")) /* Error ... */ + BIO_printf(out, "Hello World\n"); + BIO_free(out); + +=head1 RETURN VALUES + +BIO_s_file() returns the file BIO method. + +BIO_new_file() and BIO_new_fp() return a file BIO or NULL if an error +occurred. + +BIO_set_fp() and BIO_get_fp() return 1 for success or 0 for failure +(although the current implementation never return 0). + +BIO_seek() returns the same value as the underlying fseek() function: +0 for success or -1 for failure. + +BIO_tell() returns the current file position. + +BIO_read_filename(), BIO_write_filename(), BIO_append_filename() and +BIO_rw_filename() return 1 for success or 0 for failure. + +=head1 BUGS + +BIO_reset() and BIO_seek() are implemented using fseek() on the underlying +stream. The return value for fseek() is 0 for success or -1 if an error +occurred this differs from other types of BIO which will typically return +1 for success and a non positive value if an error occurred. + +=head1 SEE ALSO + +L, L, +L, L, +L, +L, L, +L, L, +L, L diff --git a/lib/libssl/src/doc/crypto/BIO_s_mem.pod b/lib/libssl/src/doc/crypto/BIO_s_mem.pod new file mode 100644 index 00000000000..19648acfae0 --- /dev/null +++ b/lib/libssl/src/doc/crypto/BIO_s_mem.pod @@ -0,0 +1,115 @@ +=pod + +=head1 NAME + +BIO_s_mem, BIO_set_mem_eof_return, BIO_get_mem_data, BIO_set_mem_buf, +BIO_get_mem_ptr, BIO_new_mem_buf - memory BIO + +=head1 SYNOPSIS + + #include + + BIO_METHOD * BIO_s_mem(void); + + BIO_set_mem_eof_return(BIO *b,int v) + long BIO_get_mem_data(BIO *b, char **pp) + BIO_set_mem_buf(BIO *b,BUF_MEM *bm,int c) + BIO_get_mem_ptr(BIO *b,BUF_MEM **pp) + + BIO *BIO_new_mem_buf(void *buf, int len); + +=head1 DESCRIPTION + +BIO_s_mem() return the memory BIO method function. + +A memory BIO is a source/sink BIO which uses memory for its I/O. Data +written to a memory BIO is stored in a BUF_MEM structure which is extended +as appropriate to accommodate the stored data. + +Any data written to a memory BIO can be recalled by reading from it. +Unless the memory BIO is read only any data read from it is deleted from +the BIO. + +Memory BIOs support BIO_gets() and BIO_puts(). + +If the BIO_CLOSE flag is set when a memory BIO is freed then the underlying +BUF_MEM structure is also freed. + +Calling BIO_reset() on a read write memory BIO clears any data in it. On a +read only BIO it restores the BIO to its original state and the read only +data can be read again. + +BIO_eof() is true if no data is in the BIO. + +BIO_ctrl_pending() returns the number of bytes currently stored. + +BIO_set_mem_eof_return() sets the behaviour of memory BIO B when it is +empty. If the B is zero then an empty memory BIO will return EOF (that is +it will return zero and BIO_should_retry(b) will be false. If B is non +zero then it will return B when it is empty and it will set the read retry +flag (that is BIO_read_retry(b) is true). To avoid ambiguity with a normal +positive return value B should be set to a negative value, typically -1. + +BIO_get_mem_data() sets B to a pointer to the start of the memory BIOs data +and returns the total amount of data available. It is implemented as a macro. + +BIO_set_mem_buf() sets the internal BUF_MEM structure to B and sets the +close flag to B, that is B should be either BIO_CLOSE or BIO_NOCLOSE. +It is a macro. + +BIO_get_mem_ptr() places the underlying BUF_MEM structure in B. It is +a macro. + +BIO_new_mem_buf() creates a memory BIO using B bytes of data at B, +if B is -1 then the B is assumed to be null terminated and its +length is determined by B. The BIO is set to a read only state and +as a result cannot be written to. This is useful when some data needs to be +made available from a static area of memory in the form of a BIO. The +supplied data is read directly from the supplied buffer: it is B copied +first, so the supplied area of memory must be unchanged until the BIO is freed. + +=head1 NOTES + +Writes to memory BIOs will always succeed if memory is available: that is +their size can grow indefinitely. + +Every read from a read write memory BIO will remove the data just read with +an internal copy operation, if a BIO contains a lots of data and it is +read in small chunks the operation can be very slow. The use of a read only +memory BIO avoids this problem. If the BIO must be read write then adding +a buffering BIO to the chain will speed up the process. + +=head1 BUGS + +There should be an option to set the maximum size of a memory BIO. + +There should be a way to "rewind" a read write BIO without destroying +its contents. + +The copying operation should not occur after every small read of a large BIO +to improve efficiency. + +=head1 EXAMPLE + +Create a memory BIO and write some data to it: + + BIO *mem = BIO_new(BIO_s_mem()); + BIO_puts(mem, "Hello World\n"); + +Create a read only memory BIO: + + char data[] = "Hello World"; + BIO *mem; + mem = BIO_new_mem_buf(data, -1); + +Extract the BUF_MEM structure from a memory BIO and then free up the BIO: + + BUF_MEM *bptr; + BIO_get_mem_ptr(mem, &bptr); + BIO_set_close(mem, BIO_NOCLOSE); /* So BIO_free() leaves BUF_MEM alone */ + BIO_free(mem); + + +=head1 SEE ALSO + +TBA diff --git a/lib/libssl/src/doc/crypto/BIO_s_null.pod b/lib/libssl/src/doc/crypto/BIO_s_null.pod new file mode 100644 index 00000000000..e5514f72389 --- /dev/null +++ b/lib/libssl/src/doc/crypto/BIO_s_null.pod @@ -0,0 +1,37 @@ +=pod + +=head1 NAME + +BIO_s_null - null data sink + +=head1 SYNOPSIS + + #include + + BIO_METHOD * BIO_s_null(void); + +=head1 DESCRIPTION + +BIO_s_null() returns the null sink BIO method. Data written to +the null sink is discarded, reads return EOF. + +=head1 NOTES + +A null sink BIO behaves in a similar manner to the Unix /dev/null +device. + +A null bio can be placed on the end of a chain to discard any data +passed through it. + +A null sink is useful if, for example, an application wishes to digest some +data by writing through a digest bio but not send the digested data anywhere. +Since a BIO chain must normally include a source/sink BIO this can be achieved +by adding a null sink BIO to the end of the chain + +=head1 RETURN VALUES + +BIO_s_null() returns the null sink BIO method. + +=head1 SEE ALSO + +TBA diff --git a/lib/libssl/src/doc/crypto/BIO_s_socket.pod b/lib/libssl/src/doc/crypto/BIO_s_socket.pod new file mode 100644 index 00000000000..253185185c7 --- /dev/null +++ b/lib/libssl/src/doc/crypto/BIO_s_socket.pod @@ -0,0 +1,61 @@ +=pod + +=head1 NAME + +BIO_s_socket, BIO_new_socket - socket BIO + +=head1 SYNOPSIS + + #include + + BIO_METHOD * BIO_s_socket(void); + + #define BIO_set_fd(b,fd,c) BIO_int_ctrl(b,BIO_C_SET_FD,c,fd) + #define BIO_get_fd(b,c) BIO_ctrl(b,BIO_C_GET_FD,0,(char *)c) + + BIO *BIO_new_socket(int sock, int close_flag); + +=head1 DESCRIPTION + +BIO_s_socket() returns the socket BIO method. This is a wrapper +round the platform's socket routines. + +BIO_read() and BIO_write() read or write the underlying socket. +BIO_puts() is supported but BIO_gets() is not. + +If the close flag is set then the socket is shut down and closed +when the BIO is freed. + +BIO_set_fd() sets the socket of BIO B to B and the close +flag to B. + +BIO_get_fd() places the socket in B if it is not NULL, it also +returns the socket . If B is not NULL it should be of type (int *). + +BIO_new_socket() returns a socket BIO using B and B. + +=head1 NOTES + +Socket BIOs also support any relevant functionality of file descriptor +BIOs. + +The reason for having separate file descriptor and socket BIOs is that on some +platforms sockets are not file descriptors and use distinct I/O routines, +Windows is one such platform. Any code mixing the two will not work on +all platforms. + +=head1 RETURN VALUES + +BIO_s_socket() returns the socket BIO method. + +BIO_set_fd() always returns 1. + +BIO_get_fd() returns the socket or -1 if the BIO has not been +initialized. + +BIO_new_socket() returns the newly allocated BIO or NULL is an error +occurred. + +=head1 SEE ALSO + +TBA diff --git a/lib/libssl/src/doc/crypto/BIO_set_callback.pod b/lib/libssl/src/doc/crypto/BIO_set_callback.pod new file mode 100644 index 00000000000..9b6961ca8d4 --- /dev/null +++ b/lib/libssl/src/doc/crypto/BIO_set_callback.pod @@ -0,0 +1,108 @@ +=pod + +=head1 NAME + +BIO_set_callback, BIO_get_callback, BIO_set_callback_arg, BIO_get_callback_arg, +BIO_debug_callback - BIO callback functions + +=head1 SYNOPSIS + + #include + + #define BIO_set_callback(b,cb) ((b)->callback=(cb)) + #define BIO_get_callback(b) ((b)->callback) + #define BIO_set_callback_arg(b,arg) ((b)->cb_arg=(char *)(arg)) + #define BIO_get_callback_arg(b) ((b)->cb_arg) + + long BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi, + long argl,long ret); + + typedef long callback(BIO *b, int oper, const char *argp, + int argi, long argl, long retvalue); + +=head1 DESCRIPTION + +BIO_set_callback() and BIO_get_callback() set and retrieve the BIO callback, +they are both macros. The callback is called during most high level BIO +operations. It can be used for debugging purposes to trace operations on +a BIO or to modify its operation. + +BIO_set_callback_arg() and BIO_get_callback_arg() are macros which can be +used to set and retrieve an argument for use in the callback. + +BIO_debug_callback() is a standard debugging callback which prints +out information relating to each BIO operation. If the callback +argument is set if is interpreted as a BIO to send the information +to, otherwise stderr is used. + +callback() is the callback function itself. The meaning of each +argument is described below. + +The BIO the callback is attached to is passed in B. + +B is set to the operation being performed. For some operations +the callback is called twice, once before and once after the actual +operation, the latter case has B or'ed with BIO_CB_RETURN. + +The meaning of the arguments B, B and B depends on +the value of B, that is the operation being performed. + +B is the return value that would be returned to the +application if no callback were present. The actual value returned +is the return value of the callback itself. In the case of callbacks +called before the actual BIO operation 1 is placed in retvalue, if +the return value is not positive it will be immediately returned to +the application and the BIO operation will not be performed. + +The callback should normally simply return B when it has +finished processing, unless if specifically wishes to modify the +value returned to the application. + +=head1 CALLBACK OPERATIONS + +=over 4 + +=item B + +callback(b, BIO_CB_FREE, NULL, 0L, 0L, 1L) is called before the +free operation. + +=item B + +callback(b, BIO_CB_READ, out, outl, 0L, 1L) is called before +the read and callback(b, BIO_CB_READ|BIO_CB_RETURN, out, outl, 0L, retvalue) +after. + +=item B + +callback(b, BIO_CB_WRITE, in, inl, 0L, 1L) is called before +the write and callback(b, BIO_CB_WRITE|BIO_CB_RETURN, in, inl, 0L, retvalue) +after. + +=item B + +callback(b, BIO_CB_GETS, out, outl, 0L, 1L) is called before +the operation and callback(b, BIO_CB_GETS|BIO_CB_RETURN, out, outl, 0L, retvalue) +after. + +=item B + +callback(b, BIO_CB_WRITE, in, 0, 0L, 1L) is called before +the operation and callback(b, BIO_CB_WRITE|BIO_CB_RETURN, in, 0, 0L, retvalue) +after. + +=item B + +callback(b,BIO_CB_CTRL,parg,cmd,larg,1L) is called before the call and +callback(b,BIO_CB_CTRL|BIO_CB_RETURN,parg,cmd, larg,ret) after. + +=back + +=head1 EXAMPLE + +The BIO_debug_callback() function is a good example, its source is +in crypto/bio/bio_cb.c + +=head1 SEE ALSO + +TBA diff --git a/lib/libssl/src/doc/crypto/BIO_should_retry.pod b/lib/libssl/src/doc/crypto/BIO_should_retry.pod new file mode 100644 index 00000000000..539c3912728 --- /dev/null +++ b/lib/libssl/src/doc/crypto/BIO_should_retry.pod @@ -0,0 +1,114 @@ +=pod + +=head1 NAME + +BIO_should_retry, BIO_should_read, BIO_should_write, +BIO_should_io_special, BIO_retry_type, BIO_should_retry, +BIO_get_retry_BIO, BIO_get_retry_reason - BIO retry functions + +=head1 SYNOPSIS + + #include + + #define BIO_should_read(a) ((a)->flags & BIO_FLAGS_READ) + #define BIO_should_write(a) ((a)->flags & BIO_FLAGS_WRITE) + #define BIO_should_io_special(a) ((a)->flags & BIO_FLAGS_IO_SPECIAL) + #define BIO_retry_type(a) ((a)->flags & BIO_FLAGS_RWS) + #define BIO_should_retry(a) ((a)->flags & BIO_FLAGS_SHOULD_RETRY) + + #define BIO_FLAGS_READ 0x01 + #define BIO_FLAGS_WRITE 0x02 + #define BIO_FLAGS_IO_SPECIAL 0x04 + #define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL) + #define BIO_FLAGS_SHOULD_RETRY 0x08 + + BIO * BIO_get_retry_BIO(BIO *bio, int *reason); + int BIO_get_retry_reason(BIO *bio); + +=head1 DESCRIPTION + +These functions determine why a BIO is not able to read or write data. +They will typically be called after a failed BIO_read() or BIO_write() +call. + +BIO_should_retry() is true if the call that produced this condition +should then be retried at a later time. + +If BIO_should_retry() is false then the cause is an error condition. + +BIO_should_read() is true if the cause of the condition is that a BIO +needs to read data. + +BIO_should_write() is true if the cause of the condition is that a BIO +needs to read data. + +BIO_should_io_special() is true if some "special" condition, that is a +reason other than reading or writing is the cause of the condition. + +BIO_get_retry_reason() returns a mask of the cause of a retry condition +consisting of the values B, B, +B though current BIO types will only set one of +these. + +BIO_get_retry_BIO() determines the precise reason for the special +condition, it returns the BIO that caused this condition and if +B is not NULL it contains the reason code. The meaning of +the reason code and the action that should be taken depends on +the type of BIO that resulted in this condition. + +BIO_get_retry_reason() returns the reason for a special condition if +passed the relevant BIO, for example as returned by BIO_get_retry_BIO(). + +=head1 NOTES + +If BIO_should_retry() returns false then the precise "error condition" +depends on the BIO type that caused it and the return code of the BIO +operation. For example if a call to BIO_read() on a socket BIO returns +0 and BIO_should_retry() is false then the cause will be that the +connection closed. A similar condition on a file BIO will mean that it +has reached EOF. Some BIO types may place additional information on +the error queue. For more details see the individual BIO type manual +pages. + +If the underlying I/O structure is in a blocking mode almost all current +BIO types will not request a retry, because the underlying I/O +calls will not. If the application knows that the BIO type will never +signal a retry then it need not call BIO_should_retry() after a failed +BIO I/O call. This is typically done with file BIOs. + +SSL BIOs are the only current exception to this rule: they can request a +retry even if the underlying I/O structure is blocking, if a handshake +occurs during a call to BIO_read(). An application can retry the failed +call immediately or avoid this situation by setting SSL_MODE_AUTO_RETRY +on the underlying SSL structure. + +While an application may retry a failed non blocking call immediately +this is likely to be very inefficient because the call will fail +repeatedly until data can be processed or is available. An application +will normally wait until the necessary condition is satisfied. How +this is done depends on the underlying I/O structure. + +For example if the cause is ultimately a socket and BIO_should_read() +is true then a call to select() may be made to wait until data is +available and then retry the BIO operation. By combining the retry +conditions of several non blocking BIOs in a single select() call +it is possible to service several BIOs in a single thread, though +the performance may be poor if SSL BIOs are present because long delays +can occur during the initial handshake process. + +It is possible for a BIO to block indefinitely if the underlying I/O +structure cannot process or return any data. This depends on the behaviour of +the platforms I/O functions. This is often not desirable: one solution +is to use non blocking I/O and use a timeout on the select() (or +equivalent) call. + +=head1 BUGS + +The OpenSSL ASN1 functions cannot gracefully deal with non blocking I/O: +that is they cannot retry after a partial read or write. This is usually +worked around by only passing the relevant data to ASN1 functions when +the entire structure can be read or written. + +=head1 SEE ALSO + +TBA diff --git a/lib/libssl/src/doc/crypto/bio.pod b/lib/libssl/src/doc/crypto/bio.pod new file mode 100644 index 00000000000..24f61dfb562 --- /dev/null +++ b/lib/libssl/src/doc/crypto/bio.pod @@ -0,0 +1,54 @@ +=pod + +=head1 NAME + +bio - I/O abstraction + +=head1 SYNOPSIS + + #include + +TBA + + +=head1 DESCRIPTION + +A BIO is an I/O abstraction, it hides many of the underlying I/O +details from an application. If an application uses a BIO for its +I/O it can transparently handle SSL connections, unencrypted network +connections and file I/O. + +There are two type of BIO, a source/sink BIO and a filter BIO. + +As its name implies a source/sink BIO is a source and/or sink of data, +examples include a socket BIO and a file BIO. + +A filter BIO takes data from one BIO and passes it through to +another, or the application. The data may be left unmodified (for +example a message digest BIO) or translated (for example an +encryption BIO). The effect of a filter BIO may change according +to the I/O operation it is performing: for example an encryption +BIO will encrypt data if it is being written to and decrypt data +if it is being read from. + +BIOs can be joined together to form a chain (a single BIO is a chain +with one component). A chain normally consist of one source/sink +BIO and one or more filter BIOs. Data read from or written to the +first BIO then traverses the chain to the end (normally a source/sink +BIO). + +=head1 SEE ALSO + +L, +L, +L, L, +L, L, +L, L, +L, +L, L, +L, L, +L, L, +L, L, +L, L, +L, +L diff --git a/lib/libssl/src/doc/crypto/evp.pod b/lib/libssl/src/doc/crypto/evp.pod new file mode 100644 index 00000000000..f089dd49a21 --- /dev/null +++ b/lib/libssl/src/doc/crypto/evp.pod @@ -0,0 +1,37 @@ +=pod + +=head1 NAME + +evp - high-level cryptographic functions + +=head1 SYNOPSIS + + #include + +=head1 DESCRIPTION + +The EVP library provided a high-level interface to cryptographic +functions. + +BI<...> and BI<...> provide public key encryption +and decryption to implement digital "envelopes". + +The BI<...> and BI<...> functions implement +digital signatures. + +Symmetric encryption is available with the BI<...> +functions. The BI<...> functions provide message digests. + +Algorithms are loaded with OpenSSL_add_all_algorithms(3). + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L, +L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_CIPHER_get_name.pod b/lib/libssl/src/doc/ssl/SSL_CIPHER_get_name.pod new file mode 100644 index 00000000000..7fea14ee686 --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_CIPHER_get_name.pod @@ -0,0 +1,57 @@ +=pod + +=head1 NAME + +SSL_CIPHER_get_name, SSL_CIPHER_get_bits, SSL_CIPHER_get_version, +SSL_CIPHER_description - get SSL_CIPHER properties + +=head1 SYNOPSIS + + #include + + const char *SSL_CIPHER_get_name(SSL_CIPHER *cipher); + int SSL_CIPHER_get_bits(SSL_CIPHER *cipher, int *alg_bits); + char *SSL_CIPHER_get_version(SSL_CIPHER *cipher); + char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int size); + +=head1 DESCRIPTION + +SSL_CIPHER_get_name() returns a pointer to the name of B. If the +argument is the NULL pointer, a pointer to the constant value "NONE" is +returned. + +SSL_CIPHER_get_bits() returns the number of secret bits used for B. If +B is not NULL, it contains the number of bits processed by the +chosen algorithm. If B is NULL, 0 is returned. + +SSL_CIPHER_get_version() returns the protocol version for B, currently +"SSLv2", "SSLv3", or "TLSv1". If B is NULL, "(NONE)" is returned. + +SSL_CIPHER_description() returns a textual description of the cipher used +into the buffer B of length B provided. B must be at least +128 bytes, otherwise the string "Buffer too small" is returned. If B +is NULL, a buffer of 128 bytes is allocated using OPENSSL_malloc(). If the +allocation fails, the string "OPENSSL_malloc Error" is returned. + +=head1 NOTES + +The number of bits processed can be different from the secret bits. An +export cipher like e.g. EXP-RC4-MD5 has only 40 secret bits. The algorithm +does use the full 128 bits (which would be returned for B), of +which however 88bits are fixed. The search space is hence only 40 bits. + +=head1 BUGS + +If SSL_CIPHER_description() is called with B being NULL, the +library crashes. + +=head1 RETURN VALUES + +See DESCRIPTION + +=head1 SEE ALSO + +L, L, +L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_CTX_free.pod b/lib/libssl/src/doc/ssl/SSL_CTX_free.pod new file mode 100644 index 00000000000..de696724222 --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_CTX_free.pod @@ -0,0 +1,29 @@ +=pod + +=head1 NAME + +SSL_CTX_free - free an allocated SSL_CTX object + +=head1 SYNOPSIS + + #include + + void SSL_CTX_free(SSL_CTX *ctx); + +=head1 DESCRIPTION + +SSL_CTX_free() decrements the reference count of B, and removes the +SSL_CTX object pointed to by B and frees up the allocated memory if the +the reference count has reached 0. + +It also calls the free()ing procedures for indirectly affected items, if +applicable: the session cacahe, the list of ciphers, the list of Client CAs, +the certificates and keys. + +=head1 RETURN VALUES + +SSL_CTX_free() does not provide diagnostic information. + +L, L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_CTX_new.pod b/lib/libssl/src/doc/ssl/SSL_CTX_new.pod new file mode 100644 index 00000000000..e166c692c35 --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_CTX_new.pod @@ -0,0 +1,93 @@ +=pod + +=head1 NAME + +SSL_CTX_new - create a new SSL_CTX object as framework for TLS/SSL enabled functions + +=head1 SYNOPSIS + + #include + + SSL_CTX *SSL_CTX_new(SSL_METHOD *method); + +=head1 DESCRIPTION + +SSL_CTX_new() creates a new B object as framework to establish +TLS/SSL enabled connections. + +=head1 NOTES + +The SSL_CTX object uses B as connection method. The methods exist +in a generic type (for client and server use), a server only type, and a +client only type. B can be of the following types: + +=over 4 + +=item SSLv2_method(void), SSLv2_server_method(void), SSLv2_client_method(void) + +A TLS/SSL connection established with these methods will only understand +the SSLv2 protocol. A client will send out SSLv2 client hello messages +and will also indicate that it only understand SSLv2. A server will only +understand SSLv2 client hello messages. + +=item SSLv3_method(void), SSLv3_server_method(void), SSLv3_client_method(void) + +A TLS/SSL connection established with these methods will only understand the +SSLv3 and TLSv1 protocol. A client will send out SSLv3 client hello messages +and will indicate that it also understands TLSv1. A server will only understand +SSLv3 and TLSv1 client hello messages. This especially means, that it will +not understand SSLv2 client hello messages which are widely used for +compatibility reasons, see SSLv23_*_method(). + +=item TLSv1_method(void), TLSv1_server_method(void), TLSv1_client_method(void) + +A TLS/SSL connection established with these methods will only understand the +TLSv1 protocol. A client will send out TLSv1 client hello messages +and will indicate that it only understands TLSv1. A server will only understand +TLSv1 client hello messages. This especially means, that it will +not understand SSLv2 client hello messages which are widely used for +compatibility reasons, see SSLv23_*_method(). + +=item SSLv23_method(void), SSLv23_server_method(void), SSLv23_client_method(void) + +A TLS/SSL connection established with these methods will understand the SSLv2, +SSLv3, and TLSv1 protocol. A client will send out SSLv2 client hello messages +and will indicate that it also understands SSLv3 and TLSv1. A server will +understand SSLv2, SSLv3, and TLSv1 client hello messages. This is the best +choice when compatibility is a concern. + +=back + +The list of protocols available can later be limited using the SSL_OP_NO_SSLv2, +SSL_OP_NO_SSLv3, SSL_OP_NO_TLSv1 options of the B or +B functions. Using these options it is possible to choose +e.g. SSLv23_server_method() and be able to negotiate with all possible +clients, but to only allow newer protocols like SSLv3 or TLSv1. + +SSL_CTX_new() initializes the list of ciphers, the session cache setting, +the callbacks, the keys and certificates, and the options to its default +values. + +=head1 RETURN VALUES + +The following return values can occur: + +=over 4 + +=item NULL + +The creation of a new SSL_CTX object failed. Check the error stack to +find out the reason. + +=item Pointer to an SSL_CTX object + +The return value points to an allocated SSL_CTX object. + +=back + +=head1 SEE ALSO + +L, L, +L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_CTX_set_cipher_list.pod b/lib/libssl/src/doc/ssl/SSL_CTX_set_cipher_list.pod new file mode 100644 index 00000000000..272d6b3de28 --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_CTX_set_cipher_list.pod @@ -0,0 +1,52 @@ +=pod + +=head1 NAME + +SSL_CTX_set_cipher_list, SSL_set_cipher_list +- choose list of available SSL_CIPHERs + +=head1 SYNOPSIS + + #include + + int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str); + int SSL_set_cipher_list(SSL *ssl, const char *str); + +=head1 DESCRIPTION + +SSL_CTX_set_cipher_list() sets the list of available ciphers for B +using the control string B. The format of the string is described +in L. The list of ciphers is inherited by all +B objects created from B. + +SSL_set_cipher_list() sets the list of ciphers only for B. + +=head1 NOTES + +The control string B should be universally usable and not depend +on details of the library configuration (ciphers compiled in). Thus no +syntax checking takes place. Items that are not recognized, because the +corresponding ciphers are not compiled in or because they are mistyped, +are simply ignored. Failure is only flagged if no ciphers could be collected +at all. + +It should be noted, that inclusion of a cipher to be used into the list is +a necessary condition. On the client side, the inclusion into the list is +also sufficient. On the server side, additional restrictions apply. All ciphers +have additional requirements. ADH ciphers don't need a certificate, but +DH-parameters must have been set. All other ciphers need a corresponding +certificate and key. A RSA cipher can only be chosen, when a RSA certificate is +available, the respective is valid for DSA ciphers. Ciphers using EDH need +a certificate and key and DH-parameters. + +=head1 RETURN VALUES + +SSL_CTX_set_cipher_list() and SSL_set_cipher_list() return 1 if any cipher +could be selected and 0 on complete failure. + +=head1 SEE ALSO + +L, L, +L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_CTX_set_ssl_version.pod b/lib/libssl/src/doc/ssl/SSL_CTX_set_ssl_version.pod new file mode 100644 index 00000000000..3091bd6895f --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_CTX_set_ssl_version.pod @@ -0,0 +1,60 @@ +=pod + +=head1 NAME + +SSL_CTX_set_ssl_version, SSL_set_ssl_method, SSL_get_ssl_method +- choose a new TLS/SSL method + +=head1 SYNOPSIS + + #include + + int SSL_CTX_set_ssl_version(SSL_CTX *ctx, SSL_METHOD *method); + int SSL_set_ssl_method(SSL *s, SSL_METHOD *method); + SSL_METHOD *SSL_get_ssl_method(SSL *ssl); + +=head1 DESCRIPTION + +SSL_CTX_set_ssl_version() sets a new default TLS/SSL B for SSL objects +newly created from this B. SSL objects already created with +L are not affected, except when SSL_clear() is +being called. + +SSL_set_ssl_method() sets a new TLS/SSL B for a particular B +object. It may be reset, when SSL_clear() is called. + +SSL_get_ssl_method() returns a function pointer to the TLS/SSL method +set in B. + +=head1 NOTES + +The available B choices are described in +L. + +When SSL_clear() is called and no session is connected to an SSL object, +the method of the SSL object is reset to the method currently set in +the corresponding SSL_CTX object. + +=head1 RETURN VALUES + +The following return values can occur for SSL_CTX_set_ssl_version() +and SSL_set_ssl_method(): + +=over 4 + +=item 0 + +The new choice failed, check the error stack to find out the reason. + +=item 1 + +The operation succeeded. + +=back + +=head1 SEE ALSO + +L, L, +L, L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_SESSION_free.pod b/lib/libssl/src/doc/ssl/SSL_SESSION_free.pod new file mode 100644 index 00000000000..df30ccbb320 --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_SESSION_free.pod @@ -0,0 +1,25 @@ +=pod + +=head1 NAME + +SSL_SESSION_free - free an allocated SSL_SESSION structure + +=head1 SYNOPSIS + + #include + + void SSL_SESSION_free(SSL_SESSION *session); + +=head1 DESCRIPTION + +SSL_SESSION_free() decrements the reference count of B and removes +the B structure pointed to by B and frees up the allocated +memory, if the the reference count has reached 0. + +=head1 RETURN VALUES + +SSL_SESSION_free() does not provide diagnostic information. + +L, L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_accept.pod b/lib/libssl/src/doc/ssl/SSL_accept.pod new file mode 100644 index 00000000000..0c79ac515e1 --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_accept.pod @@ -0,0 +1,72 @@ +=pod + +=head1 NAME + +SSL_accept - wait for a TLS/SSL client to initiate a TLS/SSL handshake + +=head1 SYNOPSIS + + #include + + int SSL_accept(SSL *ssl); + +=head1 DESCRIPTION + +SSL_accept() waits for a TLS/SSL client to initiate the TLS/SSL handshake. +The communication channel must already have been set and assigned to the +B by setting an underlying B. + +=head1 NOTES + +The behaviour of SSL_accept() depends on the underlying BIO. + +If the underlying BIO is B, SSL_accept() will only return once the +handshake has been finished or an error occurred, except for SGC (Server +Gated Cryptography). For SGC, SSL_accept() may return with -1, but +SSL_get_error() will yield B and SSL_accept() +should be called again. + +If the underlying BIO is B, SSL_accept() will also return +when the underlying BIO could not satisfy the needs of SSL_accept() +to continue the handshake. In this case a call to SSL_get_error() with the +return value of SSL_accept() will yield B or +B. The calling process then must repeat the call after +taking appropriate action to satisfy the needs of SSL_accept(). +The action depends on the underlying BIO. When using a non-blocking socket, +nothing is to be done, but select() can be used to check for the required +condition. When using a buffering BIO, like a BIO pair, data must be written +into or retrieved out of the BIO before being able to continue. + +=head1 RETURN VALUES + +The following return values can occur: + +=over 4 + +=item 1 + +The TLS/SSL handshake was successfully completed, a TLS/SSL connection has been +established. + +=item 0 + +The TLS/SSL handshake was not successful but was shut down controlled and +by the specifications of the TLS/SSL protocol. Call SSL_get_error() with the +return value B to find out the reason. + +=item -1 + +The TLS/SSL handshake was not successful because a fatal error occurred either +at the protocol level or a connection failure occurred. The shutdown was +not clean. It can also occur of action is need to continue the operation +for non-blocking BIOs. Call SSL_get_error() with the return value B +to find out the reason. + +=back + +=head1 SEE ALSO + +L, L, +L, L, L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_clear.pod b/lib/libssl/src/doc/ssl/SSL_clear.pod new file mode 100644 index 00000000000..862fd8291df --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_clear.pod @@ -0,0 +1,39 @@ +=pod + +=head1 NAME + +SSL_clear - reset SSL object to allow another connection + +=head1 SYNOPSIS + + #include + + int SSL_clear(SSL *ssl); + +=head1 DESCRIPTION + +Reset B to allow another connection. All settings (method, ciphers, +BIOs) are kept. A completely negotiated B is not freed but left +untouched for the underlying B. + +=head1 RETURN VALUES + +The following return values can occur: + +=over 4 + +=item 0 + +The SSL_clear() operation could not be performed. Check the error stack to +find out the reason. + +=item 1 + +The SSL_clear() operation was successful. + +=back + +L, L, +L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_connect.pod b/lib/libssl/src/doc/ssl/SSL_connect.pod new file mode 100644 index 00000000000..debe41744f0 --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_connect.pod @@ -0,0 +1,69 @@ +=pod + +=head1 NAME + +SSL_connect - initiate the TLS/SSL handshake with an TLS/SSL server + +=head1 SYNOPSIS + + #include + + int SSL_connect(SSL *ssl); + +=head1 DESCRIPTION + +SSL_connect() initiates the TLS/SSL handshake with a server. The communication +channel must already have been set and assigned to the B by setting an +underlying B. + +=head1 NOTES + +The behaviour of SSL_connect() depends on the underlying BIO. + +If the underlying BIO is B, SSL_connect() will only return once the +handshake has been finished or an error occurred. + +If the underlying BIO is B, SSL_connect() will also return +when the underlying BIO could not satisfy the needs of SSL_connect() +to continue the handshake. In this case a call to SSL_get_error() with the +return value of SSL_connect() will yield B or +B. The calling process then must repeat the call after +taking appropriate action to satisfy the needs of SSL_connect(). +The action depends on the underlying BIO. When using a non-blocking socket, +nothing is to be done, but select() can be used to check for the required +condition. When using a buffering BIO, like a BIO pair, data must be written +into or retrieved out of the BIO before being able to continue. + +=head1 RETURN VALUES + +The following return values can occur: + +=over 4 + +=item 1 + +The TLS/SSL handshake was successfully completed, a TLS/SSL connection has been +established. + +=item 0 + +The TLS/SSL handshake was not successful but was shut down controlled and +by the specifications of the TLS/SSL protocol. Call SSL_get_error() with the +return value B to find out the reason. + +=item -1 + +The TLS/SSL handshake was not successful, because a fatal error occurred either +at the protocol level or a connection failure occurred. The shutdown was +not clean. It can also occur of action is need to continue the operation +for non-blocking BIOs. Call SSL_get_error() with the return value B +to find out the reason. + +=back + +=head1 SEE ALSO + +L, L, +L, L , L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_free.pod b/lib/libssl/src/doc/ssl/SSL_free.pod new file mode 100644 index 00000000000..f3f0c345f8a --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_free.pod @@ -0,0 +1,33 @@ +=pod + +=head1 NAME + +SSL_free - free an allocated SSL structure + +=head1 SYNOPSIS + + #include + + void SSL_free(SSL *ssl); + +=head1 DESCRIPTION + +SSL_free() decrements the reference count of B, and removes the SSL +structure pointed to by B and frees up the allocated memory if the +the reference count has reached 0. + +It also calls the free()ing procedures for indirectly affected items, if +applicable: the buffering BIO, the read and write BIOs, +cipher lists specially created for this B, the B. +Do not explicitly free these indirectly freed up items before or after +calling SSL_free(), as trying to free things twice may lead to program +failure. + +=head1 RETURN VALUES + +SSL_free() does not provide diagnostic information. + +L, L, +L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_get_ciphers.pod b/lib/libssl/src/doc/ssl/SSL_get_ciphers.pod new file mode 100644 index 00000000000..2a57455c235 --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_get_ciphers.pod @@ -0,0 +1,42 @@ +=pod + +=head1 NAME + +SSL_get_ciphers, SSL_get_cipher_list - get list of available SSL_CIPHERs + +=head1 SYNOPSIS + + #include + + STACK_OF(SSL_CIPHER) *SSL_get_ciphers(SSL *ssl); + const char *SSL_get_cipher_list(SSL *ssl, int priority); + +=head1 DESCRIPTION + +SSL_get_ciphers() returns the stack of available SSL_CIPHERs for B, +sorted by preference. If B is NULL or no ciphers are available, NULL +is returned. + +SSL_get_cipher_list() returns a pointer to the name of the SSL_CIPHER +listed for B with B. If B is NULL, no ciphers are +available, or there are less ciphers than B available, NULL +is returned. + +=head1 NOTES + +The details of the ciphers obtained by SSL_get_ciphers() can be obtained using +the L family of functions. + +Call SSL_get_cipher_list() with B starting from 0 to obtain the +sorted list of available ciphers, until NULL is returned. + +=head1 RETURN VALUES + +See DESCRIPTION + +=head1 SEE ALSO + +L, L, +L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_get_current_cipher.pod b/lib/libssl/src/doc/ssl/SSL_get_current_cipher.pod new file mode 100644 index 00000000000..2dd7261d89d --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_get_current_cipher.pod @@ -0,0 +1,43 @@ +=pod + +=head1 NAME + +SSL_get_current_cipher, SSL_get_cipher, SSL_get_cipher_name, +SSL_get_cipher_bits, SSL_get_cipher_version - get SSL_CIPHER of a connection + +=head1 SYNOPSIS + + #include + + SSL_CIPHER *SSL_get_current_cipher(SSL *ssl); + #define SSL_get_cipher(s) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(s)) + #define SSL_get_cipher_name(s) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(s)) + #define SSL_get_cipher_bits(s,np) \ + SSL_CIPHER_get_bits(SSL_get_current_cipher(s),np) + #define SSL_get_cipher_version(s) \ + SSL_CIPHER_get_version(SSL_get_current_cipher(s)) + +=head1 DESCRIPTION + +SSL_get_current_cipher() returns a pointer to an SSL_CIPHER object containing +the description of the actually used cipher of a connection established with +the B object. + +SSL_get_cipher() and SSL_get_cipher_name() are identical macros to obtain the +name of the currently used cipher. SSL_get_cipher_bits() is a +macro to obtain the number of secret/algorithm bits used and +SSL_get_cipher_version() returns the protocol name. +See L for more details. + +=head1 RETURN VALUES + +SSL_get_current_cipher() returns the cipher actually used or NULL, when +no session has been established. + +=head1 SEE ALSO + +L, L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_get_fd.pod b/lib/libssl/src/doc/ssl/SSL_get_fd.pod new file mode 100644 index 00000000000..a3f76259316 --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_get_fd.pod @@ -0,0 +1,44 @@ +=pod + +=head1 NAME + +SSL_get_fd - get file descriptor linked to an SSL object + +=head1 SYNOPSIS + + #include + + int SSL_get_fd(SSL *ssl); + int SSL_get_rfd(SSL *ssl); + int SSL_get_wfd(SSL *ssl); + +=head1 DESCRIPTION + +SSL_get_fd() returns the file descriptor which is linked to B. +SSL_get_rfd() and SSL_get_wfd() return the file descriptors for the +read or the write channel, which can be different. If the read and the +write channel are different, SSL_get_fd() will return the file descriptor +of the read channel. + +=head1 RETURN VALUES + +The following return values can occur: + +=over 4 + +=item -1 + +The operation failed, because the underlying BIO is not of the correct type +(suitable for file descriptors). + +=item E=0 + +The file descriptor linked to B. + +=back + +=head1 SEE ALSO + +L, L , L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_get_peer_cert_chain.pod b/lib/libssl/src/doc/ssl/SSL_get_peer_cert_chain.pod new file mode 100644 index 00000000000..e93e8206faf --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_get_peer_cert_chain.pod @@ -0,0 +1,52 @@ +=pod + +=head1 NAME + +SSL_get_peer_cert_chain - get the X509 certificate chain of the peer + +=head1 SYNOPSIS + + #include + + STACKOF(X509) *SSL_get_peer_cert_chain(SSL *ssl); + +=head1 DESCRIPTION + +SSL_get_peer_cert_chain() returns a pointer to STACKOF(X509) certificates +forming the certificate chain of the peer. If called on the client side, +the stack also contains the peer's certificate; if called on the server +side, the peer's certificate must be obtained seperately using +L. +If the peer did not present a certificate, NULL is returned. + +=head1 NOTES + +The peer certificate chain is not necessarily available after reusing +a session, in which case a NULL pointer is returned. + +The reference count of the STACKOF(X509) object is not incremented. +If the corresponding session is freed, the pointer must not be used +any longer. + +=head1 RETURN VALUES + +The following return values can occur: + +=over 4 + +=item NULL + +No certificate was presented by the peer or no connection was established +or the certificate chain is no longer available when a session is reused. + +=item Pointer to a STACKOF(X509) + +The return value points to the certificate chain presented by the peer. + +=back + +=head1 SEE ALSO + +L, L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_get_peer_certificate.pod b/lib/libssl/src/doc/ssl/SSL_get_peer_certificate.pod new file mode 100644 index 00000000000..79c089aa517 --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_get_peer_certificate.pod @@ -0,0 +1,48 @@ +=pod + +=head1 NAME + +SSL_get_peer_certificate - get the X509 certificate of the peer + +=head1 SYNOPSIS + + #include + + X509 *SSL_get_peer_certificate(SSL *ssl); + +=head1 DESCRIPTION + +SSL_get_peer_certificate() returns a pointer to the X509 certificate the +peer presented. If the peer did not present a certificate, NULL is returned. + +=head1 NOTES + +That a certificate is returned does not indicate information about the +verification state, use L +to check the verification state. + +The reference count of the X509 object is incremented by one, so that it +will not be destroyed when the session containing the peer certificate is +freed. The X509 object must be explicitely freed using X509_free(). + +=head1 RETURN VALUES + +The following return values can occur: + +=over 4 + +=item NULL + +No certificate was presented by the peer or no connection was established. + +=item Pointer to an X509 certificate + +The return value points to the certificate presented by the peer. + +=back + +=head1 SEE ALSO + +L, L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_get_rbio.pod b/lib/libssl/src/doc/ssl/SSL_get_rbio.pod new file mode 100644 index 00000000000..3d98233cace --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_get_rbio.pod @@ -0,0 +1,40 @@ +=pod + +=head1 NAME + +SSL_get_rbio - get BIO linked to an SSL object + +=head1 SYNOPSIS + + #include + + BIO *SSL_get_rbio(SSL *ssl); + BIO *SSL_get_wbio(SSL *ssl); + +=head1 DESCRIPTION + +SSL_get_rbio() and SSL_get_wbio() return pointers to the BIOs for the +read or the write channel, which can be different. The reference count +of the BIO is not incremented. + +=head1 RETURN VALUES + +The following return values can occur: + +=over 4 + +=item NULL + +No BIO was connected to the SSL object + +=item Any other pointer + +The BIO linked to B. + +=back + +=head1 SEE ALSO + +L, L , L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_get_session.pod b/lib/libssl/src/doc/ssl/SSL_get_session.pod new file mode 100644 index 00000000000..aff41fb9cf6 --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_get_session.pod @@ -0,0 +1,48 @@ +=pod + +=head1 NAME + +SSL_get_session - retrieve TLS/SSL session data + +=head1 SYNOPSIS + + #include + + SSL_SESSION *SSL_get_session(SSL *ssl); + SSL_SESSION *SSL_get0_session(SSL *ssl); + SSL_SESSION *SSL_get1_session(SSL *ssl); + +=head1 DESCRIPTION + +SSL_get_session() returns a pointer to the B actually used in +B. The reference count of the B is not incremented, so +that the pointer can become invalid when the B is freed and +SSL_SESSION_free() is implicitly called. + +SSL_get0_session() is the same as SSL_get_session(). + +SSL_get1_session() is the same as SSL_get_session(), but the reference +count of the B is incremented by one. + +=head1 RETURN VALUES + +The following return values can occur: + +=over 4 + +=item NULL + +There is no session available in B. + +=item Pointer to an SSL + +The return value points to the data of an SSL session. + +=back + +=head1 SEE ALSO + +L, L, +L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_get_verify_result.pod b/lib/libssl/src/doc/ssl/SSL_get_verify_result.pod new file mode 100644 index 00000000000..4d66236a05e --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_get_verify_result.pod @@ -0,0 +1,57 @@ +=pod + +=head1 NAME + +SSL_get_verify_result - get result of peer certificate verification + +=head1 SYNOPSIS + + #include + + long SSL_get_verify_result(SSL *ssl); + +=head1 DESCRIPTION + +SSL_get_verify_result() returns the result of the verification of the +X509 certificate presented by the peer, if any. + +=head1 NOTES + +SSL_get_verify_result() can only return one error code while the verification +of a certificate can fail because of many reasons at the same time. Only +the last verification error that occured during the processing is available +from SSL_get_verify_result(). + +The verification result is part of the established session and is restored +when a session is reused. + +=head1 BUGS + +If no peer certificate was presented, the returned result code is +X509_V_OK. This is because no verification error occured, it does however +not indicate success. SSL_get_verify_result() is only useful in connection +with L. + +=head1 RETURN VALUES + +The following return values can currently occur: + +=over 4 + +=item X509_V_OK + +The verification succeeded or no peer certificate was presented. + +=item Any other value + +Documented in L. + +=back + +=head1 SEE ALSO + +L, L, +L, +L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_library_init.pod b/lib/libssl/src/doc/ssl/SSL_library_init.pod new file mode 100644 index 00000000000..ecf3c4858e5 --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_library_init.pod @@ -0,0 +1,52 @@ +=pod + +=head1 NAME + +SSL_library_init, OpenSSL_add_ssl_algorithms, SSLeay_add_ssl_algorithms +- initialize SSL library by registering algorithms + +=head1 SYNOPSIS + + #include + + int SSL_library_init(void); + #define OpenSSL_add_ssl_algorithms() SSL_library_init() + #define SSLeay_add_ssl_algorithms() SSL_library_init() + +=head1 DESCRIPTION + +SSL_library_init() registers the available ciphers and digests. + +OpenSSL_add_ssl_algorithms() and SSLeay_add_ssl_algorithms() are synonyms +for SSL_library_init(). + +=head1 NOTES + +SSL_library_init() must be called before any other action takes place. + +=head1 WARNING + +SSL_library_init() only registers ciphers. Another important initialization +is the seeding of the PRNG (Pseudo Random Number Generator), which has to +be performed separately. + +=head1 EXAMPLES + +A typical TLS/SSL application will start with the library initialization, +will provide readable error messages and will seed the PRNG. + + SSL_load_error_strings(); /* readable error messages */ + SSL_library_init(); /* initialize library */ + actions_to_seed_PRNG(); + +=head1 RETURN VALUES + +SSL_library_init() always returns "1", so it is safe to discard the return +value. + +=head1 SEE ALSO + +L, L, +L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_new.pod b/lib/libssl/src/doc/ssl/SSL_new.pod new file mode 100644 index 00000000000..8e8638fa956 --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_new.pod @@ -0,0 +1,42 @@ +=pod + +=head1 NAME + +SSL_new - create a new SSL structure for a connection + +=head1 SYNOPSIS + + #include + + SSL *SSL_new(SSL_CTX *ctx); + +=head1 DESCRIPTION + +SSL_new() creates a new B structure which is needed to hold the +data for a TLS/SSL connection. The new structure inherits the settings +of the underlying context B: connection method (SSLv2/v3/TLSv1), +options, verification settings, timeout settings. + +=head1 RETURN VALUES + +The following return values can occur: + +=over 4 + +=item NULL + +The creation of a new SSL structure failed. Check the error stack to +find out the reason. + +=item Pointer to an SSL structure + +The return value points to an allocated SSL structure. + +=back + +=head1 SEE ALSO + +L, L, +L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_pending.pod b/lib/libssl/src/doc/ssl/SSL_pending.pod new file mode 100644 index 00000000000..744e1855e15 --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_pending.pod @@ -0,0 +1,30 @@ +=pod + +=head1 NAME + +SSL_pending - obtain number of readable bytes buffered in an SSL object + +=head1 SYNOPSIS + + #include + + int SSL_pending(SSL *ssl); + +=head1 DESCRIPTION + +SSL_pending() returns the number of bytes which are available inside +B for immediate read. + +=head1 NOTES + +Data are received in blocks from the peer. Therefore data can be buffered +inside B and are ready for immediate retrieval with +L. + +=head1 RETURN VALUES + +The number of bytes pending is returned. + +L, L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_read.pod b/lib/libssl/src/doc/ssl/SSL_read.pod new file mode 100644 index 00000000000..072dc26cf28 --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_read.pod @@ -0,0 +1,77 @@ +=pod + +=head1 NAME + +SSL_read - read bytes from a TLS/SSL connection. + +=head1 SYNOPSIS + + #include + + int SSL_read(SSL *ssl, char *buf, int num); + +=head1 DESCRIPTION + +SSL_read() tries to read B bytes from the specified B into the +buffer B. + +=head1 NOTES + +If necessary, SSL_read() will negotiate a TLS/SSL session, if +not already explicitly performed by SSL_connect() or SSL_accept(). If the +peer requests a re-negotiation, it will be performed transparently during +the SSL_read() operation. The behaviour of SSL_read() depends on the +underlying BIO. + +If the underlying BIO is B, SSL_read() will only return, once the +read operation has been finished or an error occurred. + +If the underlying BIO is B, SSL_read() will also return +when the underlying BIO could not satisfy the needs of SSL_read() +to continue the operation. In this case a call to SSL_get_error() with the +return value of SSL_read() will yield B or +B. As at any time a re-negotiation is possible, a +call to SSL_read() can also cause write operations! The calling process +then must repeat the call after taking appropriate action to satisfy the +needs of SSL_read(). The action depends on the underlying BIO. When using a +non-blocking socket, nothing is to be done, but select() can be used to check +for the required condition. When using a buffering BIO, like a BIO pair, data +must be written into or retrieved out of the BIO before being able to continue. + +=head1 WARNING + +When an SSL_read() operation has to be repeated because of +B or B, it must be repeated +with the same arguments. + +=head1 RETURN VALUES + +The following return values can occur: + +=over 4 + +=item E0 + +The read operation was successful; the return value is the number of +bytes actually read from the TLS/SSL connection. + +=item 0 + +The read operation was not successful, probably because no data was +available. Call SSL_get_error() with the return value B to find out, +whether an error occurred. + +=item -1 + +The read operation was not successful, because either an error occurred +or action must be taken by the calling process. Call SSL_get_error() with the +return value B to find out the reason. + +=back + +=head1 SEE ALSO + +L, L, +L, L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_set_bio.pod b/lib/libssl/src/doc/ssl/SSL_set_bio.pod new file mode 100644 index 00000000000..67c9756d3fe --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_set_bio.pod @@ -0,0 +1,34 @@ +=pod + +=head1 NAME + +SSL_set_bio - connect the SSL object with a BIO + +=head1 SYNOPSIS + + #include + + void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio); + +=head1 DESCRIPTION + +SSL_set_bio() connects the BIOs B and B for the read and write +operations of the TLS/SSL (encrypted) side of B. + +The SSL engine inherits the behaviour of B and B, respectively. +If a BIO is non-blocking, the B will also have non-blocking behaviour. + +If there was already a BIO connected to B, BIO_free() will be called +(for both the reading and writing side, if different). + +=head1 RETURN VALUES + +SSL_set_bio() cannot fail. + +=head1 SEE ALSO + +L, +L, L, +L, L, L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_set_fd.pod b/lib/libssl/src/doc/ssl/SSL_set_fd.pod new file mode 100644 index 00000000000..70291128fce --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_set_fd.pod @@ -0,0 +1,54 @@ +=pod + +=head1 NAME + +SSL_set_fd - connect the SSL object with a file descriptor + +=head1 SYNOPSIS + + #include + + int SSL_set_fd(SSL *ssl, int fd); + int SSL_set_rfd(SSL *ssl, int fd); + int SSL_set_wfd(SSL *ssl, int fd); + +=head1 DESCRIPTION + +SSL_set_fd() sets the file descriptor B as the input/output facility +for the TLS/SSL (encrypted) side of B. B will typically be the +socket file descriptor of a network connection. + +When performing the operation, a B is automatically created to +interface between the B and B. The BIO and hence the SSL engine +inherit the behaviour of B. If B is non-blocking, the B will +also have non-blocking behaviour. + +If there was already a BIO connected to B, BIO_free() will be called +(for both the reading and writing side, if different). + +SSL_set_rfd() and SSL_set_wfd() perform the respective action, but only +for the read channel or the write channel, which can be set independently. + +=head1 RETURN VALUES + +The following return values can occur: + +=over 4 + +=item 0 + +The operation failed. Check the error stack to find out why. + +=item 1 + +The operation succeeded. + +=back + +=head1 SEE ALSO + +L, L, +L, L, +L, L , L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_set_session.pod b/lib/libssl/src/doc/ssl/SSL_set_session.pod new file mode 100644 index 00000000000..9f78d9e434a --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_set_session.pod @@ -0,0 +1,45 @@ +=pod + +=head1 NAME + +SSL_set_session - set a TLS/SSL session to be used during TLS/SSL connect + +=head1 SYNOPSIS + + #include + + int SSL_set_session(SSL *ssl, SSL_SESSION *session); + +=head1 DESCRIPTION + +SSL_set_session() sets B to be used when the TLS/SSL connection +is to be established. SSL_set_session() is only useful for TLS/SSL clients. +When the session is set, the reference count of B is incremented +by 1. If the session is not reused, the reference count is decremented +again during SSL_connect(). + +If there is already a session set inside B (because it was set with +SSL_set_session() before or because the same B was already used for +a connection), SSL_SESSION_free() will be called for that session. + +=head1 RETURN VALUES + +The following return values can occur: + +=over 4 + +=item 0 + +The operation failed; check the error stack to find out the reason. + +=item 1 + +The operation succeeded. + +=back + +=head1 SEE ALSO + +L, L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_set_verify_result.pod b/lib/libssl/src/doc/ssl/SSL_set_verify_result.pod new file mode 100644 index 00000000000..04ab101aad2 --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_set_verify_result.pod @@ -0,0 +1,38 @@ +=pod + +=head1 NAME + +SSL_set_verify_result - override result of peer certificate verification + +=head1 SYNOPSIS + + #include + + void SSL_set_verify_result(SSL *ssl, long verify_result); + +=head1 DESCRIPTION + +SSL_set_verify_result() sets B of the object B to be the +result of the verification of the X509 certificate presented by the peer, +if any. + +=head1 NOTES + +SSL_set_verify_result() overrides the verification result. It only changes +the verification result of the B object. It does not become part of the +established session, so if the session is to be reused later, the original +value will reappear. + +The valid codes for B are documented in L. + +=head1 RETURN VALUES + +SSL_set_verify_result() does not provide a return value. + +=head1 SEE ALSO + +L, L, +L, +L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_shutdown.pod b/lib/libssl/src/doc/ssl/SSL_shutdown.pod new file mode 100644 index 00000000000..20e273bd4d5 --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_shutdown.pod @@ -0,0 +1,62 @@ +=pod + +=head1 NAME + +SSL_shutdown - shut down a TLS/SSL connection + +=head1 SYNOPSIS + + #include + + int SSL_shutdown(SSL *ssl); + +=head1 DESCRIPTION + +SSL_shutdown() shuts down an active TLS/SSL connection. It sends the shutdown +alert to the peer. The behaviour of SSL_shutdown() depends on the underlying +BIO. + +If the underlying BIO is B, SSL_shutdown() will only return once the +handshake has been finished or an error occurred. + +If the underlying BIO is B, SSL_shutdown() will also return +when the underlying BIO could not satisfy the needs of SSL_shutdown() +to continue the handshake. In this case a call to SSL_get_error() with the +return value of SSL_shutdown() will yield B or +B. The calling process then must repeat the call after +taking appropriate action to satisfy the needs of SSL_shutdown(). +The action depends on the underlying BIO. When using a non-blocking socket, +nothing is to be done, but select() can be used to check for the required +condition. When using a buffering BIO, like a BIO pair, data must be written +into or retrieved out of the BIO before being able to continue. + +=head1 RETURN VALUES + +The following return values can occur: + +=over 4 + +=item 1 + +The shutdown was successfully completed. + +=item 0 + +The shutdown was not successful. Call SSL_get_error() with the return +value B to find out the reason. + +=item -1 + +The shutdown was not successful because a fatal error occurred either +at the protocol level or a connection failure occurred. It can also occur of +action is need to continue the operation for non-blocking BIOs. +Call SSL_get_error() with the return value B to find out the reason. + +=back + +=head1 SEE ALSO + +L, L, +L, L, L + +=cut diff --git a/lib/libssl/src/doc/ssl/SSL_write.pod b/lib/libssl/src/doc/ssl/SSL_write.pod new file mode 100644 index 00000000000..db67c187e0e --- /dev/null +++ b/lib/libssl/src/doc/ssl/SSL_write.pod @@ -0,0 +1,76 @@ +=pod + +=head1 NAME + +SSL_read - write bytes to a TLS/SSL connection. + +=head1 SYNOPSIS + + #include + + int SSL_write(SSL *ssl, char *buf, int num); + +=head1 DESCRIPTION + +SSL_write() writes B bytes from the buffer B into the specified +B connection. + +=head1 NOTES + +If necessary, SSL_write() will negotiate a TLS/SSL session, if +not already explicitly performed by SSL_connect() or SSL_accept(). If the +peer requests a re-negotiation, it will be performed transparently during +the SSL_write() operation. The behaviour of SSL_write() depends on the +underlying BIO. + +If the underlying BIO is B, SSL_write() will only return, once the +write operation has been finished or an error occurred. + +If the underlying BIO is B, SSL_write() will also return, +when the underlying BIO could not satisfy the needs of SSL_write() +to continue the operation. In this case a call to SSL_get_error() with the +return value of SSL_write() will yield B or +B. As at any time a re-negotiation is possible, a +call to SSL_write() can also cause write operations! The calling process +then must repeat the call after taking appropriate action to satisfy the +needs of SSL_write(). The action depends on the underlying BIO. When using a +non-blocking socket, nothing is to be done, but select() can be used to check +for the required condition. When using a buffering BIO, like a BIO pair, data +must be written into or retrieved out of the BIO before being able to continue. + +=head1 WARNING + +When an SSL_write() operation has to be repeated because of +B or B, it must be repeated +with the same arguments. + +=head1 RETURN VALUES + +The following return values can occur: + +=over 4 + +=item E0 + +The write operation was successful, the return value is the number of +bytes actually written to the TLS/SSL connection. + +=item 0 + +The write operation was not successful. Call SSL_get_error() with the return +value B to find out, whether an error occurred. + +=item -1 + +The read operation was not successful, because either an error occurred +or action must be taken by the calling process. Call SSL_get_error() with the +return value B to find out the reason. + +=back + +=head1 SEE ALSO + +L, L, +L, L + +=cut diff --git a/lib/libssl/src/doc/standards.txt b/lib/libssl/src/doc/standards.txt new file mode 100644 index 00000000000..61ccc5d7e0a --- /dev/null +++ b/lib/libssl/src/doc/standards.txt @@ -0,0 +1,121 @@ +Standards related to OpenSSL +============================ + +[Please, this is currently a draft. I made a first try at finding + documents that describe parts of what OpenSSL implements. There are + big gaps, and I've most certainly done something wrong. Please + correct whatever is... Also, this note should be removed when this + file is reaching a somewhat correct state. -- Richard Levitte] + + +All pointers in here will be either URL's or blobs of text borrowed +from miscellaneous indexes, like rfc-index.txt (index of RFCs), +1id-index.txt (index of Internet drafts) and the like. + +To find the latest possible RFCs, it's recommended to either browse +ftp://ftp.isi.edu/in-notes/ or go to http://www.rfc-editor.org/ and +use the search mechanism found there. +To find the latest possible Internet drafts, it's recommended to +browse ftp://ftp.isi.edu/internet-drafts/. +To find the latest possible PKCS, it's recommended to browse +http://www.rsasecurity.com/rsalabs/pkcs/. + + +Implemented: +------------ + +These are documents that describe things that are implemented in OpenSSL. + +1319 The MD2 Message-Digest Algorithm. B. Kaliski. April 1992. + (Format: TXT=25661 bytes) (Status: INFORMATIONAL) + +1320 The MD4 Message-Digest Algorithm. R. Rivest. April 1992. (Format: + TXT=32407 bytes) (Status: INFORMATIONAL) + +1321 The MD5 Message-Digest Algorithm. R. Rivest. April 1992. (Format: + TXT=35222 bytes) (Status: INFORMATIONAL) + +2246 The TLS Protocol Version 1.0. T. Dierks, C. Allen. January 1999. + (Format: TXT=170401 bytes) (Status: PROPOSED STANDARD) + +2268 A Description of the RC2(r) Encryption Algorithm. R. Rivest. + January 1998. (Format: TXT=19048 bytes) (Status: INFORMATIONAL) + +2314 PKCS 10: Certification Request Syntax Version 1.5. B. Kaliski. + March 1998. (Format: TXT=15814 bytes) (Status: INFORMATIONAL) + +2315 PKCS 7: Cryptographic Message Syntax Version 1.5. B. Kaliski. + March 1998. (Format: TXT=69679 bytes) (Status: INFORMATIONAL) + +2437 PKCS #1: RSA Cryptography Specifications Version 2.0. B. Kaliski, + J. Staddon. October 1998. (Format: TXT=73529 bytes) (Obsoletes + RFC2313) (Status: INFORMATIONAL) + +2459 Internet X.509 Public Key Infrastructure Certificate and CRL + Profile. R. Housley, W. Ford, W. Polk, D. Solo. January 1999. + (Format: TXT=278438 bytes) (Status: PROPOSED STANDARD) + +PKCS#8: Private-Key Information Syntax Standard + +PKCS#12: Personal Information Exchange Syntax Standard, version 1.0. + + +Related: +-------- + +These are documents that are close to OpenSSL, for example the +STARTTLS documents. + +1421 Privacy Enhancement for Internet Electronic Mail: Part I: Message + Encryption and Authentication Procedures. J. Linn. February 1993. + (Format: TXT=103894 bytes) (Obsoletes RFC1113) (Status: PROPOSED + STANDARD) + +1422 Privacy Enhancement for Internet Electronic Mail: Part II: + Certificate-Based Key Management. S. Kent. February 1993. (Format: + TXT=86085 bytes) (Obsoletes RFC1114) (Status: PROPOSED STANDARD) + +1423 Privacy Enhancement for Internet Electronic Mail: Part III: + Algorithms, Modes, and Identifiers. D. Balenson. February 1993. + (Format: TXT=33277 bytes) (Obsoletes RFC1115) (Status: PROPOSED + STANDARD) + +1424 Privacy Enhancement for Internet Electronic Mail: Part IV: Key + Certification and Related Services. B. Kaliski. February 1993. + (Format: TXT=17537 bytes) (Status: PROPOSED STANDARD) + +2487 SMTP Service Extension for Secure SMTP over TLS. P. Hoffman. + January 1999. (Format: TXT=15120 bytes) (Status: PROPOSED STANDARD) + +2585 Internet X.509 Public Key Infrastructure Operational Protocols: + FTP and HTTP. R. Housley, P. Hoffman. May 1999. (Format: TXT=14813 + bytes) (Status: PROPOSED STANDARD) + +2595 Using TLS with IMAP, POP3 and ACAP. C. Newman. June 1999. + (Format: TXT=32440 bytes) (Status: PROPOSED STANDARD) + +2712 Addition of Kerberos Cipher Suites to Transport Layer Security + (TLS). A. Medvinsky, M. Hur. October 1999. (Format: TXT=13763 bytes) + (Status: PROPOSED STANDARD) + +2817 Upgrading to TLS Within HTTP/1.1. R. Khare, S. Lawrence. May + 2000. (Format: TXT=27598 bytes) (Updates RFC2616) (Status: PROPOSED + STANDARD) + +2818 HTTP Over TLS. E. Rescorla. May 2000. (Format: TXT=15170 bytes) + (Status: INFORMATIONAL) + + "Securing FTP with TLS", 01/27/2000, + + +To be implemented: +------------------ + +These are documents that describe things that are planed to be +implemented in the hopefully short future. + +2560 X.509 Internet Public Key Infrastructure Online Certificate + Status Protocol - OCSP. M. Myers, R. Ankney, A. Malpani, S. Galperin, + C. Adams. June 1999. (Format: TXT=43243 bytes) (Status: PROPOSED + STANDARD) + diff --git a/lib/libssl/src/ms/tlhelp32.h b/lib/libssl/src/ms/tlhelp32.h new file mode 100644 index 00000000000..8f4222e34f1 --- /dev/null +++ b/lib/libssl/src/ms/tlhelp32.h @@ -0,0 +1,136 @@ +/* + tlhelp32.h - Include file for Tool help functions. + + Written by Mumit Khan + + This file is part of a free library for the Win32 API. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +*/ +#ifndef _TLHELP32_H +#define _TLHELP32_H +#ifdef __cplusplus +extern "C" { +#endif +#define HF32_DEFAULT 1 +#define HF32_SHARED 2 +#define LF32_FIXED 0x1 +#define LF32_FREE 0x2 +#define LF32_MOVEABLE 0x4 +#define MAX_MODULE_NAME32 255 +#define TH32CS_SNAPHEAPLIST 0x1 +#define TH32CS_SNAPPROCESS 0x2 +#define TH32CS_SNAPTHREAD 0x4 +#define TH32CS_SNAPMODULE 0x8 +#define TH32CS_SNAPALL (TH32CS_SNAPHEAPLIST|TH32CS_SNAPPROCESS|TH32CS_SNAPTHREAD|TH32CS_SNAPMODULE) +#define TH32CS_INHERIT 0x80000000 +typedef struct tagHEAPLIST32 { + DWORD dwSize; + DWORD th32ProcessID; + DWORD th32HeapID; + DWORD dwFlags; +} HEAPLIST32,*PHEAPLIST32,*LPHEAPLIST32; +typedef struct tagHEAPENTRY32 { + DWORD dwSize; + HANDLE hHandle; + DWORD dwAddress; + DWORD dwBlockSize; + DWORD dwFlags; + DWORD dwLockCount; + DWORD dwResvd; + DWORD th32ProcessID; + DWORD th32HeapID; +} HEAPENTRY32,*PHEAPENTRY32,*LPHEAPENTRY32; +typedef struct tagPROCESSENTRY32W { + DWORD dwSize; + DWORD cntUsage; + DWORD th32ProcessID; + DWORD th32DefaultHeapID; + DWORD th32ModuleID; + DWORD cntThreads; + DWORD th32ParentProcessID; + LONG pcPriClassBase; + DWORD dwFlags; + WCHAR szExeFile[MAX_PATH]; +} PROCESSENTRY32W,*PPROCESSENTRY32W,*LPPROCESSENTRY32W; +typedef struct tagPROCESSENTRY32 { + DWORD dwSize; + DWORD cntUsage; + DWORD th32ProcessID; + DWORD th32DefaultHeapID; + DWORD th32ModuleID; + DWORD cntThreads; + DWORD th32ParentProcessID; + LONG pcPriClassBase; + DWORD dwFlags; + CHAR szExeFile[MAX_PATH]; +} PROCESSENTRY32,*PPROCESSENTRY32,*LPPROCESSENTRY32; +typedef struct tagTHREADENTRY32 { + DWORD dwSize; + DWORD cntUsage; + DWORD th32ThreadID; + DWORD th32OwnerProcessID; + LONG tpBasePri; + LONG tpDeltaPri; + DWORD dwFlags; +} THREADENTRY32,*PTHREADENTRY32,*LPTHREADENTRY32; +typedef struct tagMODULEENTRY32W { + DWORD dwSize; + DWORD th32ModuleID; + DWORD th32ProcessID; + DWORD GlblcntUsage; + DWORD ProccntUsage; + BYTE *modBaseAddr; + DWORD modBaseSize; + HMODULE hModule; + WCHAR szModule[MAX_MODULE_NAME32 + 1]; + WCHAR szExePath[MAX_PATH]; +} MODULEENTRY32W,*PMODULEENTRY32W,*LPMODULEENTRY32W; +typedef struct tagMODULEENTRY32 { + DWORD dwSize; + DWORD th32ModuleID; + DWORD th32ProcessID; + DWORD GlblcntUsage; + DWORD ProccntUsage; + BYTE *modBaseAddr; + DWORD modBaseSize; + HMODULE hModule; + char szModule[MAX_MODULE_NAME32 + 1]; + char szExePath[MAX_PATH]; +} MODULEENTRY32,*PMODULEENTRY32,*LPMODULEENTRY32; +BOOL WINAPI Heap32First(LPHEAPENTRY32,DWORD,DWORD); +BOOL WINAPI Heap32ListFirst(HANDLE,LPHEAPLIST32); +BOOL WINAPI Heap32ListNext(HANDLE,LPHEAPLIST32); +BOOL WINAPI Heap32Next(LPHEAPENTRY32); +BOOL WINAPI Module32First(HANDLE,LPMODULEENTRY32); +BOOL WINAPI Module32FirstW(HANDLE,LPMODULEENTRY32W); +BOOL WINAPI Module32Next(HANDLE,LPMODULEENTRY32); +BOOL WINAPI Module32NextW(HANDLE,LPMODULEENTRY32W); +BOOL WINAPI Process32First(HANDLE,LPPROCESSENTRY32); +BOOL WINAPI Process32FirstW(HANDLE,LPPROCESSENTRY32W); +BOOL WINAPI Process32Next(HANDLE,LPPROCESSENTRY32); +BOOL WINAPI Process32NextW(HANDLE,LPPROCESSENTRY32W); +BOOL WINAPI Thread32First(HANDLE,LPTHREADENTRY32); +BOOL WINAPI Thread32Next(HANDLE,LPTHREADENTRY32); +BOOL WINAPI Toolhelp32ReadProcessMemory(DWORD,LPCVOID,LPVOID,DWORD,LPDWORD); +HANDLE WINAPI CreateToolhelp32Snapshot(DWORD,DWORD); +#ifdef UNICODE +#define LPMODULEENTRY32 LPMODULEENTRY32W +#define LPPROCESSENTRY32 LPPROCESSENTRY32W +#define MODULEENTRY32 MODULEENTRY32W +#define Module32First Module32FirstW +#define Module32Next Module32NextW +#define PMODULEENTRY32 PMODULEENTRY32W +#define PPROCESSENTRY32 PPROCESSENTRY32W +#define PROCESSENTRY32 PROCESSENTRY32W +#define Process32First Process32FirstW +#define Process32Next Process32NextW +#endif /* UNICODE */ +#ifdef __cplusplus +} +#endif +#endif /* _TLHELP32_H */ + diff --git a/lib/libssl/src/openssl.spec b/lib/libssl/src/openssl.spec new file mode 100644 index 00000000000..1c8f4e9d817 --- /dev/null +++ b/lib/libssl/src/openssl.spec @@ -0,0 +1,213 @@ +%define libmaj 0 +%define libmin 9 +%define librel 6 +#%define librev +Release: 1 + +%define openssldir /var/ssl + +Summary: Secure Sockets Layer and cryptography libraries and tools +Name: openssl-engine +Version: %{libmaj}.%{libmin}.%{librel} +#Version: %{libmaj}.%{libmin}.%{librel}%{librev} +Source0: ftp://ftp.openssl.org/source/%{name}-%{version}.tar.gz +Copyright: Freely distributable +Group: System Environment/Libraries +Provides: SSL +URL: http://www.openssl.org/ +Packager: Damien Miller +BuildRoot: /var/tmp/%{name}-%{version}-root + +%description +The OpenSSL Project is a collaborative effort to develop a robust, +commercial-grade, fully featured, and Open Source toolkit implementing the +Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1) +protocols as well as a full-strength general purpose cryptography library. +The project is managed by a worldwide community of volunteers that use the +Internet to communicate, plan, and develop the OpenSSL tookit and its related +documentation. + +OpenSSL is based on the excellent SSLeay library developed from Eric A. +Young and Tim J. Hudson. The OpenSSL toolkit is licensed under an +Apache-style licence, which basically means that you are free to get and +use it for commercial and non-commercial purposes. + +This package contains the base OpenSSL cryptography and SSL/TLS +libraries and tools. + +%package devel +Summary: Secure Sockets Layer and cryptography static libraries and headers +Group: Development/Libraries +Requires: openssl-engine +%description devel +The OpenSSL Project is a collaborative effort to develop a robust, +commercial-grade, fully featured, and Open Source toolkit implementing the +Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1) +protocols as well as a full-strength general purpose cryptography library. +The project is managed by a worldwide community of volunteers that use the +Internet to communicate, plan, and develop the OpenSSL tookit and its related +documentation. + +OpenSSL is based on the excellent SSLeay library developed from Eric A. +Young and Tim J. Hudson. The OpenSSL toolkit is licensed under an +Apache-style licence, which basically means that you are free to get and +use it for commercial and non-commercial purposes. + +This package contains the the OpenSSL cryptography and SSL/TLS +static libraries and header files required when developing applications. + +%package doc +Summary: OpenSSL miscellaneous files +Group: Documentation +Requires: openssl-engine +%description doc +The OpenSSL Project is a collaborative effort to develop a robust, +commercial-grade, fully featured, and Open Source toolkit implementing the +Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1) +protocols as well as a full-strength general purpose cryptography library. +The project is managed by a worldwide community of volunteers that use the +Internet to communicate, plan, and develop the OpenSSL tookit and its related +documentation. + +OpenSSL is based on the excellent SSLeay library developed from Eric A. +Young and Tim J. Hudson. The OpenSSL toolkit is licensed under an +Apache-style licence, which basically means that you are free to get and +use it for commercial and non-commercial purposes. + +This package contains the the OpenSSL cryptography and SSL/TLS extra +documentation and POD files from which the man pages were produced. + +%prep + +%setup -q + +%build + +%define CONFIG_FLAGS -DSSL_ALLOW_ADH --prefix=/usr + +perl util/perlpath.pl /usr/bin/perl + +%ifarch i386 i486 i586 i686 +./Configure %{CONFIG_FLAGS} --openssldir=%{openssldir} linux-elf +#!#./Configure %{CONFIG_FLAGS} --openssldir=%{openssldir} linux-elf shared +%endif +%ifarch ppc +./Configure %{CONFIG_FLAGS} --openssldir=%{openssldir} linux-ppc +#!#./Configure %{CONFIG_FLAGS} --openssldir=%{openssldir} linux-ppc shared +%endif +%ifarch alpha +./Configure %{CONFIG_FLAGS} --openssldir=%{openssldir} linux-alpha +#!#./Configure %{CONFIG_FLAGS} --openssldir=%{openssldir} linux-alpha shared +%endif +LD_LIBRARY_PATH=`pwd` make +LD_LIBRARY_PATH=`pwd` make rehash +LD_LIBRARY_PATH=`pwd` make test + +%install +rm -rf $RPM_BUILD_ROOT +make install MANDIR=/usr/man INSTALL_PREFIX="$RPM_BUILD_ROOT" + +# Rename manpages +for x in $RPM_BUILD_ROOT/usr/man/man*/* + do mv ${x} ${x}ssl +done + +# Install RSAref stuff +install -m644 rsaref/rsaref.h $RPM_BUILD_ROOT/usr/include/openssl +install -m644 libRSAglue.a $RPM_BUILD_ROOT/usr/lib + +# Make backwards-compatibility symlink to ssleay +ln -s /usr/bin/openssl $RPM_BUILD_ROOT/usr/bin/ssleay + +# Install shared libs +install -m644 libcrypto.a $RPM_BUILD_ROOT/usr/lib +#!#install -m755 libcrypto.so.%{libmaj}.%{libmin}.%{librel} $RPM_BUILD_ROOT/usr/lib +install -m644 libssl.a $RPM_BUILD_ROOT/usr/lib +#!#install -m755 libssl.so.%{libmaj}.%{libmin}.%{librel} $RPM_BUILD_ROOT/usr/lib +( + cd $RPM_BUILD_ROOT/usr/lib + #!#ln -s libcrypto.so.%{libmaj}.%{libmin}.%{librel} libcrypto.so.%{libmaj} + #!#ln -s libcrypto.so.%{libmaj}.%{libmin}.%{librel} libcrypto.so + #!#ln -s libssl.so.%{libmaj}.%{libmin}.%{librel} libssl.so.%{libmaj} + #!#ln -s libssl.so.%{libmaj}.%{libmin}.%{librel} libssl.so +) + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(0644,root,root,0755) +%doc CHANGES CHANGES.SSLeay LICENSE NEWS README + +%attr(0755,root,root) /usr/bin/* +#!#%attr(0755,root,root) /usr/lib/*.so* +%attr(0755,root,root) %{openssldir}/misc/* +%attr(0644,root,root) /usr/man/man[157]/* + +%config %attr(0644,root,root) %{openssldir}/openssl.cnf +%dir %attr(0755,root,root) %{openssldir}/certs +%dir %attr(0755,root,root) %{openssldir}/lib +%dir %attr(0755,root,root) %{openssldir}/misc +%dir %attr(0750,root,root) %{openssldir}/private + +%files devel +%doc CHANGES CHANGES.SSLeay LICENSE NEWS README + +%defattr(0644,root,root,0755) +%attr(0644,root,root) /usr/lib/*.a +%attr(0644,root,root) /usr/include/openssl/* +%attr(0644,root,root) /usr/man/man[3]/* + +%files doc +%doc CHANGES CHANGES.SSLeay LICENSE NEWS README +%doc doc + +%post +ldconfig + +%postun +ldconfig + +%changelog +* Thu Sep 14 2000 Richard Levitte +- Changed to adapt to the new (supported) way of making shared libraries +- Installs all static libraries, not just libRSAglue.a +- Extra documents now end up in a separate document package +* Sun Feb 27 2000 Damien Miller +- Merged patches to spec +- Updated to 0.9.5beta2 (now with manpages) +* Sat Feb 5 2000 Michal Jaegermann +- added 'linux-alpha' to configuration +- fixed nasty absolute links +* Tue Jan 25 2000 Bennett Todd +- Added -DSSL_ALLOW_ADH, bumped Release to 4 +* Thu Oct 14 1999 Damien Miller +- Set default permissions +- Removed documentation from devel sub-package +* Thu Sep 30 1999 Damien Miller +- Added "make test" stage +- GPG signed +* Tue Sep 10 1999 Damien Miller +- Updated to version 0.9.4 +* Tue May 25 1999 Damien Miller +- Updated to version 0.9.3 +- Added attributes for all files +- Paramatised openssl directory +* Sat Mar 20 1999 Carlo M. Arenas Belon +- Added "official" bnrec patch and taking other out +- making a link from ssleay to openssl binary +- putting all changelog together on SPEC file +* Fri Mar 5 1999 Henri Gomez +- Added bnrec patch +* Tue Dec 29 1998 Jonathan Ruano +- minimum spec and patches changes for openssl +- modified for openssl sources +* Sat Aug 8 1998 Khimenko Victor +- shared library creating process honours $RPM_OPT_FLAGS +- shared libarry supports threads (as well as static library) +* Wed Jul 22 1998 Khimenko Victor +- building of shared library completely reworked +* Tue Jul 21 1998 Khimenko Victor +- RPM is BuildRoot'ed +* Tue Feb 10 1998 Khimenko Victor +- all stuff is moved out of /usr/local diff --git a/lib/libssl/src/times/x86/md4s.cpp b/lib/libssl/src/times/x86/md4s.cpp new file mode 100644 index 00000000000..c0ec97fc9f9 --- /dev/null +++ b/lib/libssl/src/times/x86/md4s.cpp @@ -0,0 +1,78 @@ +// +// gettsc.inl +// +// gives access to the Pentium's (secret) cycle counter +// +// This software was written by Leonard Janke (janke@unixg.ubc.ca) +// in 1996-7 and is entered, by him, into the public domain. + +#if defined(__WATCOMC__) +void GetTSC(unsigned long&); +#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax]; +#elif defined(__GNUC__) +inline +void GetTSC(unsigned long& tsc) +{ + asm volatile(".byte 15, 49\n\t" + : "=eax" (tsc) + : + : "%edx", "%eax"); +} +#elif defined(_MSC_VER) +inline +void GetTSC(unsigned long& tsc) +{ + unsigned long a; + __asm _emit 0fh + __asm _emit 31h + __asm mov a, eax; + tsc=a; +} +#endif + +#include +#include +#include + +extern "C" { +void md4_block_x86(MD4_CTX *ctx, unsigned char *buffer,int num); +} + +void main(int argc,char *argv[]) + { + unsigned char buffer[64*256]; + MD4_CTX ctx; + unsigned long s1,s2,e1,e2; + unsigned char k[16]; + unsigned long data[2]; + unsigned char iv[8]; + int i,num=0,numm; + int j=0; + + if (argc >= 2) + num=atoi(argv[1]); + + if (num == 0) num=16; + if (num > 250) num=16; + numm=num+2; + num*=64; + numm*=64; + + for (j=0; j<6; j++) + { + for (i=0; i<10; i++) /**/ + { + md4_block_x86(&ctx,buffer,numm); + GetTSC(s1); + md4_block_x86(&ctx,buffer,numm); + GetTSC(e1); + GetTSC(s2); + md4_block_x86(&ctx,buffer,num); + GetTSC(e2); + md4_block_x86(&ctx,buffer,num); + } + printf("md4 (%d bytes) %d %d (%.2f)\n",num, + e1-s1,e2-s2,(double)((e1-s1)-(e2-s2))/2); + } + } + diff --git a/lib/libssl/src/util/mkstack.pl b/lib/libssl/src/util/mkstack.pl new file mode 100644 index 00000000000..3ee13fe7c9d --- /dev/null +++ b/lib/libssl/src/util/mkstack.pl @@ -0,0 +1,124 @@ +#!/usr/local/bin/perl -w + +# This is a utility that searches out "DECLARE_STACK_OF()" +# declarations in .h and .c files, and updates/creates/replaces +# the corresponding macro declarations in crypto/stack/safestack.h. +# As it's not generally possible to have macros that generate macros, +# we need to control this from the "outside", here in this script. +# +# Geoff Thorpe, June, 2000 (with massive Perl-hacking +# help from Steve Robb) + +my $safestack = "crypto/stack/safestack"; + +my $do_write; +while (@ARGV) { + my $arg = $ARGV[0]; + if($arg eq "-write") { + $do_write = 1; + } + shift @ARGV; +} + + +@source = (, , , ); +foreach $file (@source) { + next if -l $file; + + # Open the .c/.h file for reading + open(IN, "< $file") || die "Can't open $file for reading: $!"; + + while() { + if (/^DECLARE_STACK_OF\(([^)]+)\)/) { + push @stacklst, $1; + } if (/^DECLARE_ASN1_SET_OF\(([^)]+)\)/) { + push @asn1setlst, $1; + } if (/^DECLARE_PKCS12_STACK_OF\(([^)]+)\)/) { + push @p12stklst, $1; + } + } + close(IN); +} + + + +my $old_stackfile = ""; +my $new_stackfile = ""; +my $inside_block = 0; +my $type_thing; + +open(IN, "< $safestack.h") || die "Can't open input file: $!"; +while() { + $old_stackfile .= $_; + + if (m|^/\* This block of defines is updated by util/mkstack.pl, please do not touch! \*/|) { + $inside_block = 1; + } + if (m|^/\* End of util/mkstack.pl block, you may now edit :-\) \*/|) { + $inside_block = 0; + } elsif ($inside_block == 0) { + $new_stackfile .= $_; + } + next if($inside_block != 1); + $new_stackfile .= "/* This block of defines is updated by util/mkstack.pl, please do not touch! */"; + + foreach $type_thing (sort @stacklst) { + $new_stackfile .= <$safestack.h" || die "Can't open output file"; + print OUT $new_stackfile; + close OUT; +} -- cgit v1.2.3